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

📄 mutex.h

📁 File system using stacked.
💻 H
📖 第 1 页 / 共 2 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2002 *	Sleepycat Software.  All rights reserved. * * $Id: mutex.h,v 1.1.1.1 2004/08/19 23:53:56 gopalan Exp $ */#ifndef _DB_MUTEX_H_#define	_DB_MUTEX_H_/* * Some of the Berkeley DB ports require single-threading at various * places in the code.  In those cases, these #defines will be set. */#define	DB_BEGIN_SINGLE_THREAD#define	DB_END_SINGLE_THREAD/********************************************************************* * kernel semaphore interface to use with kdb3. *********************************************************************/#ifdef __KERNEL__#define	MUTEX_FIELDS	#include <asm/semaphore.h>	struct semaphore tas;		/* Mutex. */			#define	MUTEX_ALIGN	 sizeof(struct semaphore)/*XXX*/#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_DESTROY(x)                /*XXX: sema_destroy(x).					 *Commented for porting to					 *kdb3.					 */#define	MUTEX_INIT(x)	 sema_init(x, 1)#define	MUTEX_SET(x)	 (down_interruptible(x) == 0)#define	MUTEX_UNSET(x)	 up(x)#endif#endif /* __KERNEL__ */#ifndef __KERNEL__ /********************************************************************* * POSIX.1 pthreads interface. *********************************************************************///#ifdef HAVE_MUTEX_PTHREADS//#include <pthread.h>//#define	MUTEX_FIELDS												 //	pthread_mutex_t mutex;		/* Mutex. */		     					 //	pthread_cond_t  cond;		/* Condition variable. *///#endif/********************************************************************* * Solaris lwp threads interface. * * !!! * We use LWP mutexes on Solaris instead of UI or POSIX mutexes (both of * which are available), for two reasons.  First, the Solaris C library * includes versions of the both UI and POSIX thread mutex interfaces, but * they are broken in that they don't support inter-process locking, and * there's no way to detect it, e.g., calls to configure the mutexes for * inter-process locking succeed without error.  So, we use LWP mutexes so * that we don't fail in fairly undetectable ways because the application * wasn't linked with the appropriate threads library.  Second, there were * bugs in SunOS 5.7 (Solaris 7) where if an application loaded the C library * before loading the libthread/libpthread threads libraries (e.g., by using * dlopen to load the DB library), the pwrite64 interface would be translated * into a call to pwrite and DB would drop core. *********************************************************************/#ifdef HAVE_MUTEX_SOLARIS_LWP/* * XXX * Don't change <synch.h> to <sys/lwp.h> -- although lwp.h is listed in the * Solaris manual page as the correct include to use, it causes the Solaris * compiler on SunOS 2.6 to fail. */#include <synch.h>#define	MUTEX_FIELDS							\	lwp_mutex_t mutex;		/* Mutex. */			\	lwp_cond_t cond;		/* Condition variable. */#endif/********************************************************************* * Solaris/Unixware threads interface. *********************************************************************/#ifdef HAVE_MUTEX_UI_THREADS#include <thread.h>#include <synch.h>#define	MUTEX_FIELDS							\	mutex_t mutex;			/* Mutex. */			\	cond_t  cond;			/* Condition variable. */#endif/********************************************************************* * AIX C library functions. *********************************************************************/#ifdef HAVE_MUTEX_AIX_CHECK_LOCK#include <sys/atomic_op.h>typedef int tsl_t;#define	MUTEX_ALIGN	sizeof(int)#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_INIT(x)	0#define	MUTEX_SET(x)	(!_check_lock(x, 0, 1))#define	MUTEX_UNSET(x)	_clear_lock(x, 0)#endif#endif/********************************************************************* * General C library functions (msemaphore). * * !!! * Check for HPPA as a special case, because it requires unusual alignment, * and doesn't support semaphores in malloc(3) or shmget(2) memory. * * !!! * Do not remove the MSEM_IF_NOWAIT flag.  The problem is that if a single * process makes two msem_lock() calls in a row, the second one returns an * error.  We depend on the fact that we can lock against ourselves in the * locking subsystem, where we set up a mutex so that we can block ourselves. * Tested on OSF1 v4.0. *********************************************************************/#ifdef HAVE_MUTEX_HPPA_MSEM_INIT#define	MUTEX_NO_MALLOC_LOCKS#define	MUTEX_NO_SHMGET_LOCKS#define	MUTEX_ALIGN	16#endif#if defined(HAVE_MUTEX_MSEM_INIT) || defined(HAVE_MUTEX_HPPA_MSEM_INIT)#include <sys/mman.h>typedef msemaphore tsl_t;#ifndef MUTEX_ALIGN#define	MUTEX_ALIGN	sizeof(int)#endif#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_INIT(x)	(msem_init(x, MSEM_UNLOCKED) <= (msemaphore *)0)#define	MUTEX_SET(x)	(!msem_lock(x, MSEM_IF_NOWAIT))#define	MUTEX_UNSET(x)	msem_unlock(x, 0)#endif#endif/********************************************************************* * Plan 9 library functions. *********************************************************************/#ifdef HAVE_MUTEX_PLAN9typedef Lock tsl_t;#define	MUTEX_ALIGN	sizeof(int)#define	MUTEX_INIT(x)	(memset(x, 0, sizeof(Lock)), 0)#define	MUTEX_SET(x)	canlock(x)#define	MUTEX_UNSET(x)	unlock(x)#endif/********************************************************************* * Reliant UNIX C library functions. *********************************************************************/#ifdef HAVE_MUTEX_RELIANTUNIX_INITSPIN#include <ulocks.h>typedef spinlock_t tsl_t;#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_INIT(x)	(initspin(x, 1), 0)#define	MUTEX_SET(x)	(cspinlock(x) == 0)#define	MUTEX_UNSET(x)	spinunlock(x)#endif#endif/********************************************************************* * General C library functions (POSIX 1003.1 sema_XXX). * * !!! * Never selected by autoconfig in this release (semaphore calls are known * to not work in Solaris 5.5). *********************************************************************/#ifdef HAVE_MUTEX_SEMA_INIT#include <synch.h>typedef sema_t tsl_t;#define	MUTEX_ALIGN	 sizeof(int)#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_DESTROY(x) sema_destroy(x)#define	MUTEX_INIT(x)	 (sema_init(x, 1, USYNC_PROCESS, NULL) != 0)#define	MUTEX_SET(x)	 (sema_wait(x) == 0)#define	MUTEX_UNSET(x)	 sema_post(x)#endif#endif/********************************************************************* * SGI C library functions. *********************************************************************/#ifdef HAVE_MUTEX_SGI_INIT_LOCK#include <abi_mutex.h>typedef abilock_t tsl_t;#define	MUTEX_ALIGN	sizeof(int)#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_INIT(x)	(init_lock(x) != 0)#define	MUTEX_SET(x)	(!acquire_lock(x))#define	MUTEX_UNSET(x)	release_lock(x)#endif#endif/********************************************************************* * Solaris C library functions. * * !!! * These are undocumented functions, but they're the only ones that work * correctly as far as we know. *********************************************************************/#ifdef HAVE_MUTEX_SOLARIS_LOCK_TRY#include <sys/machlock.h>typedef lock_t tsl_t;#define	MUTEX_ALIGN	sizeof(int)#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_INIT(x)	0#define	MUTEX_SET(x)	_lock_try(x)#define	MUTEX_UNSET(x)	_lock_clear(x)#endif#endif/********************************************************************* * VMS. *********************************************************************/#ifdef HAVE_MUTEX_VMS#include <sys/mman.h>;#include <builtins.h>typedef unsigned char tsl_t;#define	MUTEX_ALIGN		sizeof(unsigned int)#ifdef LOAD_ACTUAL_MUTEX_CODE#ifdef __ALPHA#define	MUTEX_SET(tsl)		(!__TESTBITSSI(tsl, 0))#else /* __VAX */#define	MUTEX_SET(tsl)		(!(int)_BBSSI(0, tsl))#endif#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * VxWorks * Use basic binary semaphores in VxWorks, as we currently do not need * any special features.  We do need the ability to single-thread the * entire system, however, because VxWorks doesn't support the open(2) * flag O_EXCL, the mechanism we normally use to single thread access * when we're first looking for a DB environment. *********************************************************************/#ifdef HAVE_MUTEX_VXWORKS#include "taskLib.h"typedef SEM_ID tsl_t;#define	MUTEX_ALIGN		sizeof(unsigned int)#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_SET(tsl)		(semTake((*tsl), WAIT_FOREVER) == OK)#define	MUTEX_UNSET(tsl)	(semGive((*tsl)))#define	MUTEX_INIT(tsl)							\	((*(tsl) = semBCreate(SEM_Q_FIFO, SEM_FULL)) == NULL)#define	MUTEX_DESTROY(tsl)	semDelete(*tsl)#endif/* * Use the taskLock() mutex to eliminate a race where two tasks are * trying to initialize the global lock at the same time. */#undef	DB_BEGIN_SINGLE_THREAD#define	DB_BEGIN_SINGLE_THREAD						\do {									\	if (DB_GLOBAL(db_global_init))					\		(void)semTake(DB_GLOBAL(db_global_lock), WAIT_FOREVER);	\	else {								\		taskLock();						\		if (DB_GLOBAL(db_global_init)) {			\			taskUnlock();					\			(void)semTake(DB_GLOBAL(db_global_lock),	\			    WAIT_FOREVER);				\			continue;					\		}							\		DB_GLOBAL(db_global_lock) =				\		    semBCreate(SEM_Q_FIFO, SEM_EMPTY);			\		if (DB_GLOBAL(db_global_lock) != NULL)			\			DB_GLOBAL(db_global_init) = 1;			\		taskUnlock();						\	}								\} while (DB_GLOBAL(db_global_init) == 0)#undef	DB_END_SINGLE_THREAD#define	DB_END_SINGLE_THREAD	(void)semGive(DB_GLOBAL(db_global_lock))#endif/********************************************************************* * Win16 * * Win16 spinlocks are simple because we cannot possibly be preempted. * * !!! * We should simplify this by always returning a no-need-to-lock lock * when we initialize the mutex. *********************************************************************/#ifdef HAVE_MUTEX_WIN16typedef unsigned int tsl_t;#define	MUTEX_ALIGN		sizeof(unsigned int)#ifdef LOAD_ACTUAL_MUTEX_CODE#define	MUTEX_INIT(x)		0#define	MUTEX_SET(tsl)		(*(tsl) = 1)#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#endif#endif/********************************************************************* * Win32 *********************************************************************/#ifdef HAVE_MUTEX_WIN32#define	MUTEX_FIELDS							\	LONG tas;							\	LONG nwaiters;							\	u_int32_t id;	/* ID used for creating events */		\#if defined(LOAD_ACTUAL_MUTEX_CODE)#define	MUTEX_SET(tsl)		(!InterlockedExchange((PLONG)tsl, 1))#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * 68K/gcc assembly. *********************************************************************/#ifdef HAVE_MUTEX_68K_GCC_ASSEMBLYtypedef unsigned char tsl_t;#ifdef LOAD_ACTUAL_MUTEX_CODE/* * For gcc/68K, 0 is clear, 1 is set. */#define	MUTEX_SET(tsl) ({						\	register tsl_t *__l = (tsl);					\	int __r;							\	    asm volatile("tas  %1; \n					\			  seq  %0"					\		: "=dm" (__r), "=m" (*__l)				\		: "1" (*__l)						\		);							\	__r & 1;							\})#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * ALPHA/gcc assembly. *********************************************************************/#ifdef HAVE_MUTEX_ALPHA_GCC_ASSEMBLYtypedef u_int32_t tsl_t;#define	MUTEX_ALIGN	4#ifdef LOAD_ACTUAL_MUTEX_CODE/* * For gcc/alpha.  Should return 0 if could not acquire the lock, 1 if * lock was acquired properly. */#ifdef __GNUC__static inline intMUTEX_SET(tsl_t *tsl) {	register tsl_t *__l = tsl;	register tsl_t __r;	asm volatile(		"1:	ldl_l	%0,%2\n"		"	blbs	%0,2f\n"		"	or	$31,1,%0\n"		"	stl_c	%0,%1\n"		"	beq	%0,3f\n"		"	mb\n"		"	br	3f\n"		"2:	xor	%0,%0\n"		"3:"		: "=&r"(__r), "=m"(*__l) : "1"(*__l) : "memory");	return __r;}/* * Unset mutex. Judging by Alpha Architecture Handbook, the mb instruction * might be necessary before unlocking */static inline intMUTEX_UNSET(tsl_t *tsl) {	asm volatile("	mb\n");	return *tsl = 0;}#endif#ifdef __DECC#include <alpha/builtins.h>#define	MUTEX_SET(tsl)		(__LOCK_LONG_RETRY((tsl), 1) != 0)#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)#endif#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * ARM/gcc assembly. *********************************************************************/#ifdef HAVE_MUTEX_ARM_GCC_ASSEMBLYtypedef unsigned char tsl_t;#ifdef LOAD_ACTUAL_MUTEX_CODE/* * For arm/gcc, 0 is clear, 1 is set. */#define	MUTEX_SET(tsl) ({						\	int __r;							\	asm volatile("swpb %0, %1, [%2]"				\	    : "=r" (__r) 						\	    : "0" (1), "r" (tsl)					\	    : "memory"							\	    );								\	__r & 1;							\})#define	MUTEX_UNSET(tsl)	(*(volatile tsl_t *)(tsl) = 0)#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)#endif#endif/********************************************************************* * HPPA/gcc assembly. *********************************************************************/#ifdef HAVE_MUTEX_HPPA_GCC_ASSEMBLYtypedef u_int32_t tsl_t;#define	MUTEX_ALIGN	16#ifdef LOAD_ACTUAL_MUTEX_CODE/* * The PA-RISC has a "load and clear" instead of a "test and set" instruction. * The 32-bit word used by that instruction must be 16-byte aligned.  We could * use the "aligned" attribute in GCC but that doesn't work for stack variables. */#define	MUTEX_SET(tsl) ({						\	register tsl_t *__l = (tsl);					\	int __r;							\	asm volatile("ldcws 0(%1),%0" : "=r" (__r) : "r" (__l));	\	__r & 1;							\})#define	MUTEX_UNSET(tsl)	(*(tsl) = -1)#define	MUTEX_INIT(tsl)		(MUTEX_UNSET(tsl), 0)#endif#endif/********************************************************************* * IA64/gcc assembly. *********************************************************************/#ifdef HAVE_MUTEX_IA64_GCC_ASSEMBLY

⌨️ 快捷键说明

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