From: Ivan Maidanski Date: Fri, 25 May 2018 07:12:56 +0000 (+0300) Subject: Hide value stored to thread-specific entries for a test purpose X-Git-Tag: v8.0.0~161 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=89e66ca7e4626344b74ff848e0c307c1870201f2;p=gc Hide value stored to thread-specific entries for a test purpose * include/private/specific.h (ts_entry_value_t): New type. * include/private/specific.h (TS_HIDE_VALUE, TS_REVEAL_PTR): New macro. * include/private/specific.h (thread_specific_entry): Replace void* to ts_entry_value_t (for value). * include/private/specific.h (GC_getspecific): Apply TS_REVEAL_PTR to entry->value. * specific.c [USE_CUSTOM_SPECIFIC] (GC_slow_getspecific): Likewise. * specific.c [USE_CUSTOM_SPECIFIC] (GC_setspecific): Apply TS_HIDE_VALUE to value stored to entry. --- diff --git a/include/private/specific.h b/include/private/specific.h index 1cc1f6b0..a1873ac8 100644 --- a/include/private/specific.h +++ b/include/private/specific.h @@ -30,6 +30,18 @@ EXTERN_C_BEGIN #define HASH(p) \ ((unsigned)((((word)(p)) >> 8) ^ (word)(p)) & (TS_HASH_SIZE - 1)) +#ifdef GC_ASSERTIONS + /* Thread-local storage is not guaranteed to be scanned by GC. */ + /* We hide values stored in "specific" entries for a test purpose. */ + typedef GC_hidden_pointer ts_entry_value_t; +# define TS_HIDE_VALUE(p) GC_HIDE_POINTER(p) +# define TS_REVEAL_PTR(p) GC_REVEAL_POINTER(p) +#else + typedef void * ts_entry_value_t; +# define TS_HIDE_VALUE(p) (p) +# define TS_REVEAL_PTR(p) (p) +#endif + /* An entry describing a thread-specific value for a given thread. */ /* All such accessible structures preserve the invariant that if either */ /* thread is a valid pthread id or qtid is a valid "quick thread id" */ @@ -38,7 +50,7 @@ EXTERN_C_BEGIN /* asynchronous reads are allowed. */ typedef struct thread_specific_entry { volatile AO_t qtid; /* quick thread id, only for cache */ - void * value; + ts_entry_value_t value; struct thread_specific_entry *next; pthread_t thread; } tse; @@ -95,7 +107,7 @@ GC_INLINE void * GC_getspecific(tsd * key) GC_ASSERT(qtid != INVALID_QTID); if (EXPECT(entry -> qtid == qtid, TRUE)) { GC_ASSERT(entry -> thread == pthread_self()); - return entry -> value; + return TS_REVEAL_PTR(entry -> value); } return GC_slow_getspecific(key, qtid, entry_ptr); } diff --git a/specific.c b/specific.c index f17d3254..624236fd 100644 --- a/specific.c +++ b/specific.c @@ -65,7 +65,7 @@ GC_INNER int GC_setspecific(tsd * key, void * value) /* Could easily check for an existing entry here. */ entry -> next = key->hash[hash_val].p; entry -> thread = self; - entry -> value = value; + entry -> value = TS_HIDE_VALUE(value); GC_ASSERT(entry -> qtid == INVALID_QTID); /* There can only be one writer at a time, but this needs to be */ /* atomic with respect to concurrent readers. */ @@ -153,7 +153,7 @@ GC_INNER void * GC_slow_getspecific(tsd * key, word qtid, *cache_ptr = entry; /* Again this is safe since pointer assignments are */ /* presumed atomic, and either pointer is valid. */ - return entry -> value; + return TS_REVEAL_PTR(entry -> value); } #ifdef GC_ASSERTIONS