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

📄 mutex.h

📁 这是国外的resip协议栈
💻 H
📖 第 1 页 / 共 3 页
字号:
}#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * SCO/cc assembly. *********************************************************************/#ifdef HAVE_MUTEX_SCO_X86_CC_ASSEMBLYtypedef unsigned char tsl_t;#ifdef LOAD_ACTUAL_MUTEX_CODE/* * UnixWare has threads in libthread, but OpenServer doesn't (yet). */#define	MUTEX_SET_TEST	1		/* cc/x86: 0 is clear, 1 is set. */#if defined(__USLC__)asm int_tsl_set(void *tsl){%mem tsl	movl	tsl, %ecx	movl	$1, %eax	lock	xchgb	(%ecx),%al	xorl	$1,%eax}#endif#define	MUTEX_SET(tsl)		_tsl_set(tsl)#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * Sparc/gcc assembly. *********************************************************************/#ifdef HAVE_MUTEX_SPARC_GCC_ASSEMBLYtypedef unsigned char tsl_t;#ifdef LOAD_ACTUAL_MUTEX_CODE/* * * The ldstub instruction takes the location specified by its first argument * (a register containing a memory address) and loads its contents into its * second argument (a register) and atomically sets the contents the location * specified by its first argument to a byte of 1s.  (The value in the second * argument is never read, but only overwritten.) * * The stbar is needed for v8, and is implemented as membar #sync on v9, * so is functional there as well.  For v7, stbar may generate an illegal * instruction and we have no way to tell what we're running on.  Some * operating systems notice and skip this instruction in the fault handler. */#define	MUTEX_SET_TEST	1		/* gcc/sparc: 0 is clear, 1 is set. */#define	MUTEX_SET(tsl) ({						\	register tsl_t *__l = (tsl);					\	register tsl_t __r;						\	__asm__ volatile						\	    ("ldstub [%1],%0; stbar"					\	    : "=r"( __r) : "r" (__l));					\	!__r;								\})#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * UTS/cc assembly. *********************************************************************/#ifdef HAVE_MUTEX_UTS_CC_ASSEMBLYtypedef int tsl_t;#ifndef	MUTEX_ALIGN#define	MUTEX_ALIGN	sizeof(int)#endif#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_INIT(x)	0#define	MUTEX_SET(x)	(!uts_lock(x, 1))#define	MUTEX_UNSET(x)	(*(x) = 0)#endif#endif/********************************************************************* * x86/gcc assembly. *********************************************************************/#ifdef HAVE_MUTEX_X86_GCC_ASSEMBLYtypedef unsigned char tsl_t;#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_SET_TEST	1		/* gcc/x86: 0 is clear, 1 is set. */#define	MUTEX_SET(tsl) ({						\	register tsl_t *__l = (tsl);					\	int __r;							\	asm volatile("movl $1,%%eax; lock; xchgb %1,%%al; xorl $1,%%eax"\	    : "=&a" (__r), "=m" (*__l)					\	    : "1" (*__l)						\	    );								\	__r & 1;							\})#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)/* * From Intel's performance tuning documentation (and see SR #6975): * ftp://download.intel.com/design/perftool/cbts/appnotes/sse2/w_spinlock.pdf * * "For this reason, it is highly recommended that you insert the PAUSE * instruction into all spin-wait code immediately. Using the PAUSE * instruction does not affect the correctness of programs on existing * platforms, and it improves performance on Pentium 4 processor platforms." */#define	MUTEX_PAUSE		asm volatile ("rep; nop" : : );#endif#endif/* * Mutex alignment defaults to one byte. * * !!! * Various systems require different alignments for mutexes (the worst we've * seen so far is 16-bytes on some HP architectures).  Malloc(3) is assumed * to return reasonable alignment, all other mutex users must ensure proper * alignment locally. */#ifndef	MUTEX_ALIGN#define	MUTEX_ALIGN	1#endif/* * Mutex destruction defaults to a no-op. */#ifdef LOAD_ACTUAL_MUTEX_CODE#ifndef	MUTEX_DESTROY#define	MUTEX_DESTROY(x)#endif#endif/* * !!! * The flag arguments for __db_mutex_setup (and the underlying initialization * function for the mutex type, for example, __db_tas_mutex_init), and flags * stored in the DB_MUTEX structure are combined, and may not overlap.  Flags * to __db_mutex_setup: * * MUTEX_ALLOC: *	Use when the mutex to initialize needs to be allocated. The 'ptr' *	arg to __db_mutex_setup should be a DB_MUTEX ** whenever you use *	this flag.  If this flag is not set, the 'ptr' arg is a DB_MUTEX *. * MUTEX_NO_RECORD: *	Explicitly do not record the mutex in the region.  Otherwise the *	mutex will be recorded by default.  If you set this you need to *	understand why you don't need it recorded.  The *only* ones not *	recorded are those that are part of region structures that only *	get destroyed when the regions are destroyed. * MUTEX_NO_RLOCK: *	Explicitly do not lock the given region otherwise the region will *	be locked by default. * MUTEX_SELF_BLOCK: *	Set if self blocking mutex. * MUTEX_THREAD: *	Set if mutex is a thread-only mutex. */#define	MUTEX_ALLOC		0x0001	/* Allocate and init a mutex */#define	MUTEX_IGNORE		0x0002	/* Ignore, no lock required. */#define	MUTEX_INITED		0x0004	/* Mutex is successfully initialized */#define	MUTEX_LOGICAL_LOCK	0x0008	/* Mutex backs database lock. */#define	MUTEX_MPOOL		0x0010	/* Allocated from mpool. */#define	MUTEX_NO_RECORD		0x0020	/* Do not record lock */#define	MUTEX_NO_RLOCK		0x0040	/* Do not acquire region lock */#define	MUTEX_SELF_BLOCK	0x0080	/* Must block self. */#define	MUTEX_THREAD		0x0100	/* Thread-only mutex. *//* Mutex. */struct __mutex_t {#ifdef	HAVE_MUTEX_THREADS#ifdef	MUTEX_FIELDS	MUTEX_FIELDS#else	tsl_t	tas;			/* Test and set. */#endif	u_int32_t locked;		/* !0 if locked. */#else	u_int32_t off;			/* Byte offset to lock. */	u_int32_t pid;			/* Lock holder: 0 or process pid. */#endif	u_int32_t mutex_set_wait;	/* Granted after wait. */	u_int32_t mutex_set_nowait;	/* Granted without waiting. */	u_int32_t mutex_set_spin;	/* Granted without spinning. */	u_int32_t mutex_set_spins;	/* Total number of spins. */#ifdef HAVE_MUTEX_SYSTEM_RESOURCES	roff_t	  reg_off;		/* Shared lock info offset. */#endif	/*	 * Flags should be an unsigned integer even if it's not required by	 * the possible flags values, getting a single byte on some machines	 * is expensive, and the mutex structure is a MP hot spot.	 */	u_int32_t flags;		/* MUTEX_XXX */};/* Macro to clear mutex statistics. */#define	MUTEX_CLEAR(mp) {						\	(mp)->mutex_set_wait = (mp)->mutex_set_nowait = 0;		\}/* Redirect calls to the correct functions. */#ifdef HAVE_MUTEX_THREADS#if defined(HAVE_MUTEX_PTHREADS) ||					\    defined(HAVE_MUTEX_SOLARIS_LWP) ||					\    defined(HAVE_MUTEX_UI_THREADS)#define	__db_mutex_init_int(a, b, c, d)	__db_pthread_mutex_init(a, b, d)#define	__db_mutex_lock(a, b)		__db_pthread_mutex_lock(a, b)#define	__db_mutex_unlock(a, b)		__db_pthread_mutex_unlock(a, b)#define	__db_mutex_destroy(a)		__db_pthread_mutex_destroy(a)#else#if defined(HAVE_MUTEX_WIN32) || defined(HAVE_MUTEX_WIN32_GCC)#define	__db_mutex_init_int(a, b, c, d)	__db_win32_mutex_init(a, b, d)#define	__db_mutex_lock(a, b)		__db_win32_mutex_lock(a, b)#define	__db_mutex_unlock(a, b)		__db_win32_mutex_unlock(a, b)#define	__db_mutex_destroy(a)		__db_win32_mutex_destroy(a)#else#define	__db_mutex_init_int(a, b, c, d)	__db_tas_mutex_init(a, b, d)#define	__db_mutex_lock(a, b)		__db_tas_mutex_lock(a, b)#define	__db_mutex_unlock(a, b)		__db_tas_mutex_unlock(a, b)#define	__db_mutex_destroy(a)		__db_tas_mutex_destroy(a)#endif#endif#else#define	__db_mutex_init_int(a, b, c, d)	__db_fcntl_mutex_init(a, b, c)#define	__db_mutex_lock(a, b)		__db_fcntl_mutex_lock(a, b)#define	__db_mutex_unlock(a, b)		__db_fcntl_mutex_unlock(a, b)#define	__db_mutex_destroy(a)		__db_fcntl_mutex_destroy(a)#endif/* Redirect system resource calls to correct functions */#ifdef HAVE_MUTEX_SYSTEM_RESOURCES#define	__db_maintinit(a, b, c)		__db_shreg_maintinit(a, b, c)#define	__db_shlocks_clear(a, b, c)	__db_shreg_locks_clear(a, b, c)#define	__db_shlocks_destroy(a, b)	__db_shreg_locks_destroy(a, b)#define	__db_mutex_init(a, b, c, d, e, f)	\    __db_shreg_mutex_init(a, b, c, d, e, f)#else#define	__db_maintinit(a, b, c)#define	__db_shlocks_clear(a, b, c)#define	__db_shlocks_destroy(a, b)#define	__db_mutex_init(a, b, c, d, e, f)	__db_mutex_init_int(a, b, c, d)#endif/* * Lock/unlock a mutex.  If the mutex was marked as uninteresting, the thread * of control can proceed without it. * * If the lock is for threads-only, then it was optionally not allocated and * file handles aren't necessary, as threaded applications aren't supported by * fcntl(2) locking. */#ifdef DIAGNOSTIC	/*	 * XXX	 * We want to switch threads as often as possible.  Yield every time	 * we get a mutex to ensure contention.	 */#define	MUTEX_LOCK(dbenv, mp)						\	if (!F_ISSET((mp), MUTEX_IGNORE))				\		DB_ASSERT(__db_mutex_lock(dbenv, mp) == 0);		\	if (F_ISSET(dbenv, DB_ENV_YIELDCPU))				\		__os_yield(NULL, 1);#else#define	MUTEX_LOCK(dbenv, mp)						\	if (!F_ISSET((mp), MUTEX_IGNORE))				\		(void)__db_mutex_lock(dbenv, mp);#endif#define	MUTEX_UNLOCK(dbenv, mp)						\	if (!F_ISSET((mp), MUTEX_IGNORE))				\		(void)__db_mutex_unlock(dbenv, mp);#define	MUTEX_THREAD_LOCK(dbenv, mp)					\	if (mp != NULL)							\		MUTEX_LOCK(dbenv, mp)#define	MUTEX_THREAD_UNLOCK(dbenv, mp)					\	if (mp != NULL)							\		MUTEX_UNLOCK(dbenv, mp)/* * We use a single file descriptor for fcntl(2) locking, and (generally) the * object's offset in a shared region as the byte that we're locking.  So, * there's a (remote) possibility that two objects might have the same offsets * such that the locks could conflict, resulting in deadlock.  To avoid this * possibility, we offset the region offset by a small integer value, using a * different offset for each subsystem's locks.  Since all region objects are * suitably aligned, the offset guarantees that we don't collide with another * region's objects. */#define	DB_FCNTL_OFF_GEN	0		/* Everything else. */#define	DB_FCNTL_OFF_LOCK	1		/* Lock subsystem offset. */#define	DB_FCNTL_OFF_MPOOL	2		/* Mpool subsystem offset. */#ifdef HAVE_MUTEX_SYSTEM_RESOURCES/* * When the underlying mutexes require library (most likely heap) or system * resources, we have to clean up when we discard mutexes (for the library * resources) and both when discarding mutexes and after application failure * (for the mutexes requiring system resources).  This violates the rule that * we never look at a shared region after application failure, but we've no * other choice.  In those cases, the #define HAVE_MUTEX_SYSTEM_RESOURCES is * set. * * To support mutex release after application failure, allocate thread-handle * mutexes in shared memory instead of in the heap.  The number of slots we * allocate for this purpose isn't configurable, but this tends to be an issue * only on embedded systems where we don't expect large server applications. */#define	DB_MAX_HANDLES	100			/* Mutex slots for handles. */#endif#endif /* !_DB_MUTEX_H_ */

⌨️ 快捷键说明

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