]> granicus.if.org Git - gc/commitdiff
2010-09-09 Ivan Maidanski <ivmai@mail.ru> (with input from Ludovic Courtes)
authorivmai <ivmai>
Wed, 8 Sep 2010 21:18:29 +0000 (21:18 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:54 +0000 (21:06 +0400)
* include/private/specific.h (quick_thread_id): Define thru
GC_approx_sp(); define as a macro.
* include/private/specific.h (getspecific): Use GC_INLINE instead
of __inline__ (to work around Sun CC which does not recognize
inline keyword surrounded with underscores).
* include/private/specific.h: Expand all tabs to spaces; remove
trailing spaces at EOLn.

ChangeLog
include/private/specific.h

index bb2c10a0d28e72250a2f4c202b9b8904b1d4e6ec..85b95b57c1a7b08a5be2e2d30c7b40dfa292d2e0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-09-09  Ivan Maidanski <ivmai@mail.ru> (with input from Ludovic Courtes)
+
+       * include/private/specific.h (quick_thread_id): Define thru
+       GC_approx_sp(); define as a macro.
+       * include/private/specific.h (getspecific): Use GC_INLINE instead
+       of __inline__ (to work around Sun CC which does not recognize
+       inline keyword surrounded with underscores).
+       * include/private/specific.h: Expand all tabs to spaces; remove
+       trailing spaces at EOLn.
+
 2010-09-04  Ivan Maidanski <ivmai@mail.ru>
 
        * darwin_stop_world.c (FindTopOfStack): Simplify condition
index fc2e8f9e6609802e71670b51267203756eb5a8d1..a404f67b4985088c26e057f9e80ea70a031800e1 100644 (file)
 #include <errno.h>
 #include "atomic_ops.h"
 
-/* Called during key creation or setspecific.          */
-/* For the GC we already hold lock.                    */
-/* Currently allocated objects leak on thread exit.    */
-/* That's hard to fix, but OK if we allocate garbage   */
-/* collected memory.                                   */
+/* Called during key creation or setspecific.           */
+/* For the GC we already hold lock.                     */
+/* Currently allocated objects leak on thread exit.     */
+/* That's hard to fix, but OK if we allocate garbage    */
+/* collected memory.                                    */
 #define MALLOC_CLEAR(n) GC_INTERNAL_MALLOC(n, NORMAL)
 #define PREFIXED(name) GC_##name
 
 #define TS_HASH_SIZE 1024
 #define HASH(n) (((((long)n) >> 8) ^ (long)n) & (TS_HASH_SIZE - 1))
 
-/* 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 tread id"    */
-/* for a thread, then value holds the corresponding thread specific    */
-/* value.  This invariant must be preserved at ALL times, since                */
-/* asynchronous reads are allowed.                                     */
+/* 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 tread id"     */
+/* for a thread, then value holds the corresponding thread specific     */
+/* value.  This invariant must be preserved at ALL times, since         */
+/* asynchronous reads are allowed.                                      */
 typedef struct thread_specific_entry {
-       volatile AO_t qtid;     /* quick thread id, only for cache */
-       void * value;
-       struct thread_specific_entry *next;
-       pthread_t thread;
+        volatile AO_t qtid;     /* quick thread id, only for cache */
+        void * value;
+        struct thread_specific_entry *next;
+        pthread_t thread;
 } tse;
 
-
-/* We represent each thread-specific datum as two tables.  The first is        */
-/* a cache, indexed by a "quick thread identifier".  The "quick" thread        */
-/* identifier is an easy to compute value, which is guaranteed to      */
-/* determine the thread, though a thread may correspond to more than   */
-/* one value.  We typically use the address of a page in the stack.    */
-/* The second is a hash table, indexed by pthread_self().  It is used  */
-/* only as a backup.                                                   */
-
-/* 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   */
+/* We represent each thread-specific datum as two tables.  The first is */
+/* a cache, indexed by a "quick thread identifier".  The "quick" thread */
+/* identifier is an easy to compute value, which is guaranteed to       */
+/* determine the thread, though a thread may correspond to more than    */
+/* one value.  We typically use the address of a page in the stack.     */
+/* The second is a hash table, indexed by pthread_self().  It is used   */
+/* only as a backup.                                                    */
+
+/* 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.)*/
-static __inline__ unsigned long quick_thread_id() {
-    int dummy;
-    return (unsigned long)(&dummy) >> 12;
-}
+#define quick_thread_id() (((unsigned long)GC_approx_sp()) >> 12)
 
 #define INVALID_QTID ((unsigned long)0)
 #define INVALID_THREADID ((pthread_t)0)
 
 typedef struct thread_specific_data {
     tse * volatile cache[TS_CACHE_SIZE];
-                       /* A faster index to the hash table */
+                        /* A faster index to the hash table */
     tse * hash[TS_HASH_SIZE];
     pthread_mutex_t lock;
 } tsd;
@@ -77,20 +73,20 @@ extern int PREFIXED(setspecific) (tsd * key, void * value);
 
 extern void PREFIXED(remove_specific) (tsd * key);
 
-/* An internal version of getspecific that assumes a cache miss.       */
+/* An internal version of getspecific that assumes a cache miss.        */
 void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid,
-                                  tse * volatile * cache_entry);
+                                   tse * volatile * cache_entry);
 
-static __inline__ void * PREFIXED(getspecific) (tsd * key) {
+/* GC_INLINE is defined in gc_priv.h. */
+GC_INLINE void * PREFIXED(getspecific) (tsd * key)
+{
     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.   */
+    tse * entry = *entry_ptr;   /* Must be loaded only once.    */
     if (EXPECT(entry -> qtid == qtid, 1)) {
       GC_ASSERT(entry -> thread == pthread_self());
       return entry -> value;
     }
     return PREFIXED(slow_getspecific) (key, qtid, entry_ptr);
 }
-
-