| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef GC_LOCKS_H |
| #define GC_LOCKS_H |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| # ifdef THREADS |
| # include <atomic_ops.h> |
|
|
| void GC_noop1(word); |
| # ifdef PCR |
| # include <base/PCR_Base.h> |
| # include <th/PCR_Th.h> |
| extern PCR_Th_ML GC_allocate_ml; |
| # define DCL_LOCK_STATE \ |
| PCR_ERes GC_fastLockRes; PCR_sigset_t GC_old_sig_mask |
| # define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml) |
| # define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml) |
| # endif |
|
|
| # if !defined(AO_HAVE_test_and_set_acquire) && defined(GC_PTHREADS) |
| # define USE_PTHREAD_LOCKS |
| # endif |
|
|
| # if defined(GC_WIN32_THREADS) && defined(GC_PTHREADS) |
| # define USE_PTHREAD_LOCKS |
| # 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; |
| # ifdef GC_ASSERTIONS |
| # define UNCOND_LOCK() \ |
| { EnterCriticalSection(&GC_allocate_ml); \ |
| SET_LOCK_HOLDER(); } |
| # define UNCOND_UNLOCK() \ |
| { 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); |
| # endif |
| # 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()) |
| # define I_DONT_HOLD_LOCK() (!GC_need_to_lock \ |
| || GC_lock_holder != GetCurrentThreadId()) |
| # elif defined(GC_PTHREADS) |
| # include <pthread.h> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| # if !defined(GC_WIN32_PTHREADS) |
| # define NUMERIC_THREAD_ID(id) ((unsigned long)(id)) |
| # define THREAD_EQUAL(id1, id2) ((id1) == (id2)) |
| # define NUMERIC_THREAD_ID_UNIQUE |
| # else |
| # if defined(GC_WIN32_PTHREADS) |
| # define NUMERIC_THREAD_ID(id) ((unsigned long)(id.p)) |
| |
| |
| |
| # define THREAD_EQUAL(id1, id2) ((id1.p == id2.p) && (id1.x == id2.x)) |
| # undef NUMERIC_THREAD_ID_UNIQUE |
| # else |
| |
| |
| # 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 (-1l) |
| |
|
|
| # if !defined(THREAD_LOCAL_ALLOC) && !defined(USE_PTHREAD_LOCKS) |
| |
| |
| |
| |
| # define USE_SPIN_LOCK |
| extern volatile AO_TS_t GC_allocate_lock; |
| extern void GC_lock(void); |
| |
| |
| # ifdef GC_ASSERTIONS |
| # define UNCOND_LOCK() \ |
| { 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); } |
| # else |
| # define UNCOND_LOCK() \ |
| { if (AO_test_and_set_acquire(&GC_allocate_lock) == AO_TS_SET) \ |
| GC_lock(); } |
| # define UNCOND_UNLOCK() \ |
| AO_CLEAR(&GC_allocate_lock) |
| # endif |
| # else |
| # ifndef USE_PTHREAD_LOCKS |
| # define USE_PTHREAD_LOCKS |
| # endif |
| # endif |
| # ifdef USE_PTHREAD_LOCKS |
| # include <pthread.h> |
| extern pthread_mutex_t GC_allocate_ml; |
| # ifdef GC_ASSERTIONS |
| # define UNCOND_LOCK() \ |
| { GC_lock(); \ |
| SET_LOCK_HOLDER(); } |
| # define UNCOND_UNLOCK() \ |
| { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \ |
| pthread_mutex_unlock(&GC_allocate_ml); } |
| # else |
| # if defined(NO_PTHREAD_TRYLOCK) |
| # define UNCOND_LOCK() GC_lock(); |
| # else |
| # define UNCOND_LOCK() \ |
| { if (0 != pthread_mutex_trylock(&GC_allocate_ml)) GC_lock(); } |
| # endif |
| # define UNCOND_UNLOCK() pthread_mutex_unlock(&GC_allocate_ml) |
| # endif |
| # endif |
| # define SET_LOCK_HOLDER() \ |
| 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())) |
| # ifndef NUMERIC_THREAD_ID_UNIQUE |
| # define I_DONT_HOLD_LOCK() 1 |
| # else |
| # define I_DONT_HOLD_LOCK() \ |
| (!GC_need_to_lock \ |
| || GC_lock_holder != NUMERIC_THREAD_ID(pthread_self())) |
| # endif |
| 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; |
| # ifdef GC_ASSERTIONS |
| extern unsigned long GC_mark_lock_holder; |
| # endif |
| # endif |
|
|
|
|
| # else |
| # define LOCK() |
| # define UNLOCK() |
| # define SET_LOCK_HOLDER() |
| # define UNSET_LOCK_HOLDER() |
| # define I_HOLD_LOCK() TRUE |
| # define I_DONT_HOLD_LOCK() TRUE |
| |
| |
| |
| # endif |
|
|
| #if defined(UNCOND_LOCK) && !defined(LOCK) |
| GC_API GC_bool GC_need_to_lock; |
| |
| # define LOCK() if (GC_need_to_lock) { UNCOND_LOCK(); } |
| # define UNLOCK() if (GC_need_to_lock) { UNCOND_UNLOCK(); } |
| #endif |
|
|
| # ifndef ENTER_GC |
| # define ENTER_GC() |
| # define EXIT_GC() |
| # endif |
|
|
| # ifndef DCL_LOCK_STATE |
| # define DCL_LOCK_STATE |
| # endif |
|
|
| #endif |
|
|