Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / include / private / gc_locks.h
index 467c1a536a440b2ac583cdeff02cb8158d5ee761..0a8162c326bf2b5f9ca50bf57fcc2cf127b62055 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
  * Copyright (c) 1996-1999 by Silicon Graphics.  All rights reserved.
  * DCL_LOCK_STATE declares any local variables needed by LOCK and UNLOCK.
  *
  * Note that I_HOLD_LOCK and I_DONT_HOLD_LOCK are used only positively
- * in assertions, and may return TRUE in the "dont know" case.
- */  
+ * in assertions, and may return TRUE in the "don't know" case.
+ */
 # ifdef THREADS
-#  include <atomic_ops.h>
+
+#  if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS)
+#    include "atomic_ops.h"
+#  endif
 
    GC_API void GC_CALL GC_noop1(word);
 #  ifdef PCR
 #    include <base/PCR_Base.h>
 #    include <th/PCR_Th.h>
-     extern PCR_Th_ML GC_allocate_ml;
+     GC_EXTERN PCR_Th_ML GC_allocate_ml;
 #    define DCL_LOCK_STATE \
-        PCR_ERes GC_fastLockRes; PCR_sigset_t GC_old_sig_mask
+         PCR_ERes GC_fastLockRes; PCR_sigset_t GC_old_sig_mask
 #    define UNCOND_LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml)
 #    define UNCOND_UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
 #  endif
 #  if defined(GC_WIN32_THREADS) && !defined(USE_PTHREAD_LOCKS)
 #    include <windows.h>
 #    define NO_THREAD (DWORD)(-1)
-     extern DWORD GC_lock_holder;
-     GC_API CRITICAL_SECTION GC_allocate_ml;
+     GC_EXTERN DWORD GC_lock_holder;
+     GC_EXTERN CRITICAL_SECTION GC_allocate_ml;
 #    ifdef GC_ASSERTIONS
 #        define UNCOND_LOCK() \
-               { EnterCriticalSection(&GC_allocate_ml); \
-                 SET_LOCK_HOLDER(); }
+                { EnterCriticalSection(&GC_allocate_ml); \
+                  SET_LOCK_HOLDER(); }
 #        define UNCOND_UNLOCK() \
-               { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
-                 LeaveCriticalSection(&GC_allocate_ml); }
+                { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
+                  LeaveCriticalSection(&GC_allocate_ml); }
 #    else
 #      define UNCOND_LOCK() EnterCriticalSection(&GC_allocate_ml);
 #      define UNCOND_UNLOCK() LeaveCriticalSection(&GC_allocate_ml);
 #    define SET_LOCK_HOLDER() GC_lock_holder = GetCurrentThreadId()
 #    define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD
 #    define I_HOLD_LOCK() (!GC_need_to_lock \
-                          || GC_lock_holder == GetCurrentThreadId())
+                           || GC_lock_holder == GetCurrentThreadId())
 #    define I_DONT_HOLD_LOCK() (!GC_need_to_lock \
-                          || GC_lock_holder != GetCurrentThreadId())
+                           || GC_lock_holder != GetCurrentThreadId())
 #  elif defined(GC_PTHREADS)
 #    include <pthread.h>
-     
-     /* Posix allows pthread_t to be a struct, though it rarely is.    */
-     /* Unfortunately, we need to use a pthread_t to index a data      */
-     /* structure.  It also helps if comparisons don't involve a       */
-     /* function call.  Hence we introduce platform-dependent macros   */
-     /* to compare pthread_t ids and to map them to integers.          */
-     /* the mapping to integers does not need to result in different   */
-     /* integers for each thread, though that should be true as much   */
-     /* as possible.                                                   */
+
+     /* Posix allows pthread_t to be a struct, though it rarely is.     */
+     /* Unfortunately, we need to use a pthread_t to index a data       */
+     /* structure.  It also helps if comparisons don't involve a        */
+     /* function call.  Hence we introduce platform-dependent macros    */
+     /* to compare pthread_t ids and to map them to integers.           */
+     /* the mapping to integers does not need to result in different    */
+     /* integers for each thread, though that should be true as much    */
+     /* as possible.                                                    */
      /* Refine to exclude platforms on which pthread_t is struct */
 #    if !defined(GC_WIN32_PTHREADS)
 #      define NUMERIC_THREAD_ID(id) ((unsigned long)(id))
 #      define NUMERIC_THREAD_ID_UNIQUE
 #    else
 #      if defined(GC_WIN32_PTHREADS)
-#       define NUMERIC_THREAD_ID(id) ((unsigned long)(id.p))
-        /* Using documented internal details of win32_pthread library. */
-        /* Faster than pthread_equal(). Should not change with         */
-        /* future versions of win32_pthread library.                   */
-#       define THREAD_EQUAL(id1, id2) ((id1.p == id2.p) && (id1.x == id2.x))
+#        define NUMERIC_THREAD_ID(id) ((unsigned long)(id.p))
+         /* Using documented internal details of win32_pthread library. */
+         /* Faster than pthread_equal(). Should not change with         */
+         /* future versions of win32_pthread library.                   */
+#        define THREAD_EQUAL(id1, id2) ((id1.p == id2.p) && (id1.x == id2.x))
 #        undef NUMERIC_THREAD_ID_UNIQUE
 #      else
-        /* Generic definitions that always work, but will result in    */
-        /* poor performance and weak assertion checking.               */
-#       define NUMERIC_THREAD_ID(id) 1l
-#       define THREAD_EQUAL(id1, id2) pthread_equal(id1, id2)
+         /* Generic definitions that always work, but will result in    */
+         /* poor performance and weak assertion checking.               */
+#        define NUMERIC_THREAD_ID(id) 1l
+#        define THREAD_EQUAL(id1, id2) pthread_equal(id1, id2)
 #        undef NUMERIC_THREAD_ID_UNIQUE
 #      endif
 #    endif
 #    define NO_THREAD ((unsigned long)(-1l))
-               /* != NUMERIC_THREAD_ID(pthread_self()) for any thread */
+                /* != NUMERIC_THREAD_ID(pthread_self()) for any thread */
 
 #    if !defined(THREAD_LOCAL_ALLOC) && !defined(USE_PTHREAD_LOCKS)
-      /* In the THREAD_LOCAL_ALLOC case, the allocation lock tends to  */
-      /* be held for long periods, if it is held at all.  Thus spinning        */
-      /* and sleeping for fixed periods are likely to result in        */
+      /* In the THREAD_LOCAL_ALLOC case, the allocation lock tends to   */
+      /* be held for long periods, if it is held at all.  Thus spinning */
+      /* and sleeping for fixed periods are likely to result in         */
       /* significant wasted time.  We thus rely mostly on queued locks. */
 #     define USE_SPIN_LOCK
-      extern volatile AO_TS_t GC_allocate_lock;
-      extern void GC_lock(void);
-       /* Allocation lock holder.  Only set if acquired by client through */
-       /* GC_call_with_alloc_lock.                                        */
+      GC_EXTERN volatile AO_TS_t GC_allocate_lock;
+      GC_INNER void GC_lock(void);
+        /* Allocation lock holder.  Only set if acquired by client through */
+        /* GC_call_with_alloc_lock.                                        */
 #     ifdef GC_ASSERTIONS
 #        define UNCOND_LOCK() \
-               { if (AO_test_and_set_acquire(&GC_allocate_lock) == AO_TS_SET) \
-                       GC_lock(); \
-                 SET_LOCK_HOLDER(); }
+                { if (AO_test_and_set_acquire(&GC_allocate_lock) == AO_TS_SET) \
+                        GC_lock(); \
+                  SET_LOCK_HOLDER(); }
 #        define UNCOND_UNLOCK() \
-               { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
-                 AO_CLEAR(&GC_allocate_lock); }
+                { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
+                  AO_CLEAR(&GC_allocate_lock); }
 #     else
 #        define UNCOND_LOCK() \
-               { if (AO_test_and_set_acquire(&GC_allocate_lock) == AO_TS_SET) \
-                       GC_lock(); }
+                { if (AO_test_and_set_acquire(&GC_allocate_lock) == AO_TS_SET) \
+                        GC_lock(); }
 #        define UNCOND_UNLOCK() \
-               AO_CLEAR(&GC_allocate_lock)
+                AO_CLEAR(&GC_allocate_lock)
 #     endif /* !GC_ASSERTIONS */
 #    else /* THREAD_LOCAL_ALLOC  || USE_PTHREAD_LOCKS */
 #      ifndef USE_PTHREAD_LOCKS
 #    endif /* THREAD_LOCAL_ALLOC || USE_PTHREAD_LOCK */
 #    ifdef USE_PTHREAD_LOCKS
 #      include <pthread.h>
-       extern pthread_mutex_t GC_allocate_ml;
+       GC_EXTERN pthread_mutex_t GC_allocate_ml;
 #      ifdef GC_ASSERTIONS
 #        define UNCOND_LOCK() \
-               { GC_lock(); \
-                 SET_LOCK_HOLDER(); }
+                { GC_lock(); \
+                  SET_LOCK_HOLDER(); }
 #        define UNCOND_UNLOCK() \
-               { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
-                 pthread_mutex_unlock(&GC_allocate_ml); }
+                { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
+                  pthread_mutex_unlock(&GC_allocate_ml); }
 #      else /* !GC_ASSERTIONS */
 #        if defined(NO_PTHREAD_TRYLOCK)
 #          define UNCOND_LOCK() GC_lock();
 #        else /* !defined(NO_PTHREAD_TRYLOCK) */
 #        define UNCOND_LOCK() \
-          { if (0 != pthread_mutex_trylock(&GC_allocate_ml)) GC_lock(); }
+           { if (0 != pthread_mutex_trylock(&GC_allocate_ml)) GC_lock(); }
 #        endif
 #        define UNCOND_UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
 #      endif /* !GC_ASSERTIONS */
 #    endif /* USE_PTHREAD_LOCKS */
 #    define SET_LOCK_HOLDER() \
-               GC_lock_holder = NUMERIC_THREAD_ID(pthread_self())
+                GC_lock_holder = NUMERIC_THREAD_ID(pthread_self())
 #    define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD
 #    define I_HOLD_LOCK() \
-               (!GC_need_to_lock || \
-                GC_lock_holder == NUMERIC_THREAD_ID(pthread_self()))
+                (!GC_need_to_lock || \
+                 GC_lock_holder == NUMERIC_THREAD_ID(pthread_self()))
 #    ifndef NUMERIC_THREAD_ID_UNIQUE
 #      define I_DONT_HOLD_LOCK() 1  /* Conservatively say yes */
 #    else
 #      define I_DONT_HOLD_LOCK() \
-               (!GC_need_to_lock \
-                || GC_lock_holder != NUMERIC_THREAD_ID(pthread_self()))
+                (!GC_need_to_lock \
+                 || GC_lock_holder != NUMERIC_THREAD_ID(pthread_self()))
 #    endif
-     extern volatile GC_bool GC_collecting;
+     GC_EXTERN volatile GC_bool GC_collecting;
 #    define ENTER_GC() GC_collecting = 1;
 #    define EXIT_GC() GC_collecting = 0;
-     extern void GC_lock(void);
-     extern unsigned long GC_lock_holder;
+     GC_INNER void GC_lock(void);
+     GC_EXTERN unsigned long GC_lock_holder;
 #    ifdef GC_ASSERTIONS
-      extern unsigned long GC_mark_lock_holder;
+       GC_EXTERN unsigned long GC_mark_lock_holder;
 #    endif
 #  endif /* GC_PTHREADS with linux_threads.c implementation */
 
 #   define UNSET_LOCK_HOLDER()
 #   define I_HOLD_LOCK() TRUE
 #   define I_DONT_HOLD_LOCK() TRUE
-                       /* Used only in positive assertions or to test whether  */
-                       /* we still need to acquire the lock.  TRUE works in    */
-                       /* either case.                                         */
+                /* Used only in positive assertions or to test whether  */
+                /* we still need to acquire the lock.  TRUE works in    */
+                /* either case.                                         */
 # endif /* !THREADS */
 
-#if defined(UNCOND_LOCK) && !defined(LOCK) 
-     GC_API GC_bool GC_need_to_lock;
-               /* At least two thread running; need to lock.   */
+#if defined(UNCOND_LOCK) && !defined(LOCK)
+     GC_EXTERN GC_bool GC_need_to_lock;
+                /* At least two thread running; need to lock.   */
 #    define LOCK() if (GC_need_to_lock) { UNCOND_LOCK(); }
 #    define UNLOCK() if (GC_need_to_lock) { UNCOND_UNLOCK(); }
 #endif