]> granicus.if.org Git - gc/commitdiff
Hide value stored to thread-specific entries for a test purpose
authorIvan Maidanski <ivmai@mail.ru>
Fri, 25 May 2018 07:12:56 +0000 (10:12 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 25 May 2018 07:12:56 +0000 (10:12 +0300)
* 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.

include/private/specific.h
specific.c

index 1cc1f6b00fe091f93c34c425f70f2fd77e378abc..a1873ac85d36920582c37671f0d292ccc8188e8a 100644 (file)
@@ -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);
 }
index f17d3254b6ce7c194e50f1fb1853133901e216dd..624236fdf20d7b27dac4c0cf838b34436dfbab3b 100644 (file)
@@ -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