📄 mutex.h
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2004 * Sleepycat Software. All rights reserved. * * $Id: mutex.h,v 11.100 2004/10/05 14:41:12 mjc 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/********************************************************************* * 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;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(int)#endif#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/********************************************************************* * Apple/Darwin library functions. *********************************************************************/#ifdef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRYtypedef u_int32_t tsl_t;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(int)#endif#ifdef LOAD_ACTUAL_MUTEX_CODEextern int _spin_lock_try(tsl_t *);extern void _spin_unlock(tsl_t *);#define MUTEX_SET(tsl) _spin_lock_try(tsl)#define MUTEX_UNSET(tsl) _spin_unlock(tsl)#define MUTEX_INIT(tsl) (MUTEX_UNSET(tsl), 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#ifndef MUTEX_ALIGN#define MUTEX_ALIGN 16#define HPUX_MUTEX_PAD 8#endif#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;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(int)#endif#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;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(int)#endif#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;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(int)#endif#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;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(int)#endif#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 volatile unsigned char tsl_t;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(unsigned int)#endif#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;#ifndef MUTEX_ALIGN#define MUTEX_ALIGN sizeof(unsigned int)#endif#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;#ifndef MUTEX_ALIGN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -