]> granicus.if.org Git - gc/commitdiff
2011-05-13 Ivan Maidanski <ivmai@mail.ru>
authorivmai <ivmai>
Fri, 13 May 2011 14:40:31 +0000 (14:40 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:59 +0000 (21:06 +0400)
* dyn_load.c (GC_FirstDLOpenedLinkMap): Remove unused "r" local
variable.
* pthread_support.c (GC_unregister_my_thread_inner): Revert back
GC_remove_specific invocation; add a comment.
* include/private/thread_local_alloc.h (GC_remove_specific):
Revert back.
* specific.c: Expand all tabs to spaces.
* specific.c (slow_getspecific): Cast qtid to AO_t.
* include/private/specific.h (quick_thread_id): Reformat comment.
* include/private/specific.h (key_create, setspecific,
remove_specific): Remove "extern" keyword.
* include/private/specific.h (getspecific): Change type of "qtid"
local variable to unsigned long.

ChangeLog
dyn_load.c
include/private/specific.h
include/private/thread_local_alloc.h
pthread_support.c
specific.c

index 7d87f5b200681fdc8c9849bad9e8b7fddab89244..4d0d337654ea5bbda984c884b31fa405a29708f6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2011-05-13  Ivan Maidanski  <ivmai@mail.ru>
+
+       * dyn_load.c (GC_FirstDLOpenedLinkMap): Remove unused "r" local
+       variable.
+       * pthread_support.c (GC_unregister_my_thread_inner): Revert back
+       GC_remove_specific invocation; add a comment.
+       * include/private/thread_local_alloc.h (GC_remove_specific):
+       Revert back.
+       * specific.c: Expand all tabs to spaces.
+       * specific.c (slow_getspecific): Cast qtid to AO_t.
+       * include/private/specific.h (quick_thread_id): Reformat comment.
+       * include/private/specific.h (key_create, setspecific,
+       remove_specific): Remove "extern" keyword.
+       * include/private/specific.h (getspecific): Change type of "qtid"
+       local variable to unsigned long.
+
 2011-05-11  Ivan Maidanski  <ivmai@mail.ru>
 
        * pthread_support.c (GC_check_tls): Fix "#endif" comment.
index a00e0102873b49086bb86bef1789a82a6c41c03d..7cdceffb0f44f012ef3317c874947948e251d1ce 100644 (file)
@@ -135,7 +135,6 @@ GC_FirstDLOpenedLinkMap(void)
 {
     extern ElfW(Dyn) _DYNAMIC;
     ElfW(Dyn) *dp;
-    struct r_debug *r;
     static struct link_map * cachedResult = 0;
     static ElfW(Dyn) *dynStructureAddr = 0;
                 /* BTL: added to avoid Solaris 5.3 ld.so _DYNAMIC bug   */
index 372238dca56c32b290730629bfd104cac7adafc5..8b5cf847713d25403568a5fab442bb61550938d1 100644 (file)
@@ -51,8 +51,8 @@ typedef struct thread_specific_entry {
 
 /* Return the "quick thread id".  Default version.  Assumes page size,  */
 /* or at least thread stack separation, is at least 4K.                 */
-/* Must be defined so that it never returns 0.  (Page 0 can't really    */
-/* be part of any stack, since that would make 0 a valid stack pointer.)*/
+/* Must be defined so that it never returns 0.  (Page 0 can't really be */
+/* part of any stack, since that would make 0 a valid stack pointer.)   */
 #define quick_thread_id() (((unsigned long)GC_approx_sp()) >> 12)
 
 #define INVALID_QTID ((unsigned long)0)
@@ -67,11 +67,9 @@ typedef struct thread_specific_data {
 
 typedef tsd * PREFIXED(key_t);
 
-extern int PREFIXED(key_create) (tsd ** key_ptr, void (* destructor)(void *));
-
-extern int PREFIXED(setspecific) (tsd * key, void * value);
-
-extern void PREFIXED(remove_specific) (tsd * key);
+int PREFIXED(key_create) (tsd ** key_ptr, void (* destructor)(void *));
+int PREFIXED(setspecific) (tsd * key, void * value);
+void PREFIXED(remove_specific) (tsd * key);
 
 /* An internal version of getspecific that assumes a cache miss.        */
 void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid,
@@ -80,7 +78,7 @@ void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid,
 /* GC_INLINE is defined in gc_priv.h. */
 GC_INLINE void * PREFIXED(getspecific) (tsd * key)
 {
-    long qtid = quick_thread_id();
+    unsigned long qtid = quick_thread_id();
     unsigned hash_val = CACHE_HASH(qtid);
     tse * volatile * entry_ptr = key -> cache + hash_val;
     tse * entry = *entry_ptr;   /* Must be loaded only once.    */
index 258b592e2539150f53570b5efa2ad399b66e138c..55d8fd6e03171aaedf6d4ca68043c8a119eaa605 100644 (file)
@@ -94,11 +94,13 @@ typedef struct thread_local_freelists {
 # define GC_getspecific pthread_getspecific
 # define GC_setspecific pthread_setspecific
 # define GC_key_create pthread_key_create
+# define GC_remove_specific(key)  /* No need for cleanup on exit. */
   typedef pthread_key_t GC_key_t;
 #elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS)
 # define GC_getspecific(x) (x)
 # define GC_setspecific(key, v) ((key) = (v), 0)
 # define GC_key_create(key, d) 0
+# define GC_remove_specific(key)  /* No need for cleanup on exit. */
   typedef void * GC_key_t;
 #elif defined(USE_WIN32_SPECIFIC)
 # ifndef WIN32_LEAN_AND_MEAN
@@ -115,6 +117,7 @@ typedef struct thread_local_freelists {
 # endif
 # define GC_key_create(key, d) \
         ((d) != 0 || (*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? -1 : 0)
+# define GC_remove_specific(key)  /* No need for cleanup on exit. */
         /* Need TlsFree on process exit/detach?   */
   typedef DWORD GC_key_t;
 #elif defined(USE_CUSTOM_SPECIFIC)
index 3a3f66728c7f98cc6bbd58955383e42191efd9c3..175663c0db8a8e7b8b6677fec5d989cc77427326 100644 (file)
@@ -1182,6 +1182,10 @@ STATIC void GC_unregister_my_thread_inner(GC_thread me)
     } else {
         me -> flags |= FINISHED;
     }
+#   if defined(THREAD_LOCAL_ALLOC)
+      /* It is required to call remove_specific defined in specific.c. */
+      GC_remove_specific(GC_thread_key);
+#   endif
 }
 
 GC_API int GC_CALL GC_unregister_my_thread(void)
index b8ea49dd321ac766fe9cc698cf5a372d2cbfdcbb..cbeb23317c8fa9fa71603fd5d7caaa0d9146bada 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
  *
  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  * modified is included with the above copyright notice.
  */
 
-#include "private/gc_priv.h"   /* For configuration, pthreads.h. */
+#include "private/gc_priv.h"    /* For configuration, pthreads.h. */
 #include "private/thread_local_alloc.h"
-                               /* To determine type of tsd impl. */
-                               /* Includes private/specific.h    */
-                               /* if needed.                     */
+                /* To determine type of tsd impl.       */
+                /* Includes private/specific.h          */
+                /* if needed.                           */
 
 #if defined(USE_CUSTOM_SPECIFIC)
 
 #include "atomic_ops.h"
 
 static tse invalid_tse = {INVALID_QTID, 0, 0, INVALID_THREADID};
-                       /* A thread-specific data entry which will never    */
-                       /* appear valid to a reader.  Used to fill in empty */
-                       /* cache entries to avoid a check for 0.            */
+            /* A thread-specific data entry which will never    */
+            /* appear valid to a reader.  Used to fill in empty */
+            /* cache entries to avoid a check for 0.            */
 
 int PREFIXED(key_create) (tsd ** key_ptr, void (* destructor)(void *)) {
     int i;
-    tsd * result = (tsd *)MALLOC_CLEAR(sizeof (tsd));
+    tsd * result = (tsd *)MALLOC_CLEAR(sizeof(tsd));
 
     /* A quick alignment check, since we need atomic stores */
-      GC_ASSERT((unsigned long)(&invalid_tse.next) % sizeof(tse *) == 0);
+    GC_ASSERT((unsigned long)(&invalid_tse.next) % sizeof(tse *) == 0);
     if (0 == result) return ENOMEM;
     pthread_mutex_init(&(result -> lock), NULL);
     for (i = 0; i < TS_CACHE_SIZE; ++i) {
-       result -> cache[i] = &invalid_tse;
+      result -> cache[i] = &invalid_tse;
     }
 #   ifdef GC_ASSERTIONS
       for (i = 0; i < TS_HASH_SIZE; ++i) {
-       GC_ASSERT(result -> hash[i] == 0);
+        GC_ASSERT(result -> hash[i] == 0);
       }
 #   endif
     *key_ptr = result;
@@ -50,24 +50,24 @@ int PREFIXED(setspecific) (tsd * key, void * value) {
     pthread_t self = pthread_self();
     int hash_val = HASH(self);
     volatile tse * entry = (volatile tse *)MALLOC_CLEAR(sizeof (tse));
-    
+
     GC_ASSERT(self != INVALID_THREADID);
     if (0 == entry) return ENOMEM;
     pthread_mutex_lock(&(key -> lock));
-    /* Could easily check for an existing entry here.  */
+    /* Could easily check for an existing entry here.   */
     entry -> next = key -> hash[hash_val];
     entry -> thread = self;
     entry -> 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.                      */ 
+    /* There can only be one writer at a time, but this needs to be     */
+    /* atomic with respect to concurrent readers.                       */
     AO_store_release((volatile AO_t *)(key -> hash + hash_val), (AO_t)entry);
     pthread_mutex_unlock(&(key -> lock));
     return 0;
 }
 
-/* Remove thread-specific data for this thread.  Should be called on   */
-/* thread exit.                                                                */
+/* Remove thread-specific data for this thread.  Should be called on    */
+/* thread exit.                                                         */
 void PREFIXED(remove_specific) (tsd * key) {
     pthread_t self = pthread_self();
     unsigned hash_val = HASH(self);
@@ -77,89 +77,86 @@ void PREFIXED(remove_specific) (tsd * key) {
     pthread_mutex_lock(&(key -> lock));
     entry = *link;
     while (entry != NULL && entry -> thread != self) {
-       link = &(entry -> next);
-        entry = *link;
+      link = &(entry -> next);
+      entry = *link;
     }
-    /* Invalidate qtid field, since qtids may be reused, and a later   */
-    /* cache lookup could otherwise find this entry.                   */
-        entry -> qtid = INVALID_QTID;
+    /* Invalidate qtid field, since qtids may be reused, and a later    */
+    /* cache lookup could otherwise find this entry.                    */
+    entry -> qtid = INVALID_QTID;
     if (entry != NULL) {
-       *link = entry -> next;
-       /* Atomic! concurrent accesses still work.      */
-       /* They must, since readers don't lock.         */
-       /* We shouldn't need a volatile access here,    */
-       /* since both this and the preceding write      */
-       /* should become visible no later than          */
-       /* the pthread_mutex_unlock() call.             */
+      *link = entry -> next;
+      /* Atomic! concurrent accesses still work.        */
+      /* They must, since readers don't lock.           */
+      /* We shouldn't need a volatile access here,      */
+      /* since both this and the preceding write        */
+      /* should become visible no later than            */
+      /* the pthread_mutex_unlock() call.               */
     }
-    /* If we wanted to deallocate the entry, we'd first have to clear  */
-    /* any cache entries pointing to it.  That probably requires       */
-    /* additional synchronization, since we can't prevent a concurrent         */
+    /* If we wanted to deallocate the entry, we'd first have to clear   */
+    /* any cache entries pointing to it.  That probably requires        */
+    /* additional synchronization, since we can't prevent a concurrent  */
     /* cache lookup, which should still be examining deallocated memory.*/
-    /* This can only happen if the concurrent access is from another   */
-    /* thread, and hence has missed the cache, but still...            */
+    /* This can only happen if the concurrent access is from another    */
+    /* thread, and hence has missed the cache, but still...             */
 
-    /* With GC, we're done, since the pointers from the cache will     */
-    /* be overwritten, all local pointers to the entries will be       */
-    /* dropped, and the entry will then be reclaimed.                  */
+    /* With GC, we're done, since the pointers from the cache will      */
+    /* be overwritten, all local pointers to the entries will be        */
+    /* dropped, and the entry will then be reclaimed.                   */
     pthread_mutex_unlock(&(key -> lock));
 }
 
-/* Note that even the slow path doesn't lock.  */
-void *  PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid,
-                                   tse * volatile * cache_ptr) {
+/* Note that even the slow path doesn't lock.   */
+void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid,
+                tse * volatile * cache_ptr) {
     pthread_t self = pthread_self();
     unsigned hash_val = HASH(self);
     tse *entry = key -> hash[hash_val];
 
     GC_ASSERT(qtid != INVALID_QTID);
     while (entry != NULL && entry -> thread != self) {
-       entry = entry -> next;
-    } 
+      entry = entry -> next;
+    }
     if (entry == NULL) return NULL;
-    /* Set cache_entry.                */
-        entry -> qtid = qtid;
-               /* It's safe to do this asynchronously.  Either value   */
-               /* is safe, though may produce spurious misses.         */
-               /* We're replacing one qtid with another one for the    */
-               /* same thread.                                         */
-       *cache_ptr = entry;
-               /* Again this is safe since pointer assignments are     */
-               /* presumed atomic, and either pointer is valid.        */
+    /* Set cache_entry. */
+    entry -> qtid = (AO_t)qtid;
+        /* It's safe to do this asynchronously.  Either value   */
+        /* is safe, though may produce spurious misses.         */
+        /* We're replacing one qtid with another one for the    */
+        /* same thread.                                         */
+    *cache_ptr = entry;
+        /* Again this is safe since pointer assignments are     */
+        /* presumed atomic, and either pointer is valid.        */
     return entry -> value;
 }
 
 #ifdef GC_ASSERTIONS
-
-/* Check that that all elements of the data structure associated       */
-/* with key are marked.                                                        */
-void PREFIXED(check_tsd_marks) (tsd *key)
-{
+  /* Check that that all elements of the data structure associated  */
+  /* with key are marked.                                           */
+  void PREFIXED(check_tsd_marks) (tsd *key)
+  {
     int i;
     tse *p;
 
     if (!GC_is_marked(GC_base(key))) {
-       ABORT("Unmarked thread-specific-data table");
+      ABORT("Unmarked thread-specific-data table");
     }
     for (i = 0; i < TS_HASH_SIZE; ++i) {
-        for (p = key -> hash[i]; p != 0; p = p -> next) {
-           if (!GC_is_marked(GC_base(p))) {
-               GC_err_printf(
-                       "Thread-specific-data entry at %p not marked\n",p);
-               ABORT("Unmarked tse");
-           }
-       }
+      for (p = key -> hash[i]; p != 0; p = p -> next) {
+        if (!GC_is_marked(GC_base(p))) {
+          GC_err_printf("Thread-specific-data entry at %p not marked\n", p);
+          ABORT("Unmarked tse");
+        }
+      }
     }
     for (i = 0; i < TS_CACHE_SIZE; ++i) {
-        p = key -> cache[i];
-       if (p != &invalid_tse && !GC_is_marked(GC_base(p))) {
-           GC_err_printf(
-               "Cached thread-specific-data entry at %p not marked\n",p);
-           ABORT("Unmarked cached tse");
-       }
+      p = key -> cache[i];
+      if (p != &invalid_tse && !GC_is_marked(GC_base(p))) {
+        GC_err_printf("Cached thread-specific-data entry at %p not marked\n",
+                      p);
+        ABORT("Unmarked cached tse");
+      }
     }
-}
-
-#endif
+  }
+#endif /* GC_ASSERTIONS */
 
 #endif /* USE_CUSTOM_SPECIFIC */