⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gc_locks.h

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 H
字号:
/*  * 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. * Copyright (c) 1999 by Hewlett-Packard Company. All rights reserved. * * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. * * Permission is hereby granted to use or copy this program * for any purpose,  provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. */#ifndef GC_LOCKS_H#define GC_LOCKS_H/* * Mutual exclusion between allocator/collector routines. * Needed if there is more than one allocator thread. * 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. */  # 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 /* !GC_ASSERTIONS */#    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>          /* 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 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))	 /* 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)#        undef NUMERIC_THREAD_ID_UNIQUE#      endif#    endif#    define NO_THREAD (-1l)		/* != 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 	*/      /* 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.					   */#     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 /* !GC_ASSERTIONS */#    else /* THREAD_LOCAL_ALLOC  || USE_PTHREAD_LOCKS */#      ifndef USE_PTHREAD_LOCKS#        define USE_PTHREAD_LOCKS#      endif#    endif /* THREAD_LOCAL_ALLOC || USE_PTHREAD_LOCK */#    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 /* !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(); }#        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())#    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  /* Conservatively say yes */#    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 /* GC_PTHREADS with linux_threads.c implementation */# else /* !THREADS */#   define LOCK()#   define UNLOCK()#   define SET_LOCK_HOLDER()#   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 acaquire 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.	*/#    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 /* GC_LOCKS_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -