mariadb/bdb/dbinc/mutex.h
unknown 155e78f014 BDB 4.1.24
BitKeeper/deleted/.del-ex_access.wpj~3df6ae8c99bf7c5f:
  Delete: bdb/build_vxworks/ex_access/ex_access.wpj
BitKeeper/deleted/.del-ex_btrec.wpj~a7622f1c6f432dc6:
  Delete: bdb/build_vxworks/ex_btrec/ex_btrec.wpj
BitKeeper/deleted/.del-ex_dbclient.wpj~7345440f3b204cdd:
  Delete: bdb/build_vxworks/ex_dbclient/ex_dbclient.wpj
BitKeeper/deleted/.del-ex_env.wpj~fbe1ab10b04e8b74:
  Delete: bdb/build_vxworks/ex_env/ex_env.wpj
BitKeeper/deleted/.del-ex_mpool.wpj~4479cfd5c45f327d:
  Delete: bdb/build_vxworks/ex_mpool/ex_mpool.wpj
BitKeeper/deleted/.del-ex_tpcb.wpj~f78093006e14bf41:
  Delete: bdb/build_vxworks/ex_tpcb/ex_tpcb.wpj
BitKeeper/deleted/.del-db_buildall.dsp~bd749ff6da11682:
  Delete: bdb/build_win32/db_buildall.dsp
BitKeeper/deleted/.del-cxx_app.cpp~ad8df8e0791011ed:
  Delete: bdb/cxx/cxx_app.cpp
BitKeeper/deleted/.del-cxx_log.cpp~a50ff3118fe06952:
  Delete: bdb/cxx/cxx_log.cpp
BitKeeper/deleted/.del-cxx_table.cpp~ecd751e79b055556:
  Delete: bdb/cxx/cxx_table.cpp
BitKeeper/deleted/.del-namemap.txt~796a3acd3885d8fd:
  Delete: bdb/cxx/namemap.txt
BitKeeper/deleted/.del-Design.fileop~3ca4da68f1727373:
  Delete: bdb/db/Design.fileop
BitKeeper/deleted/.del-db185_int.h~61bee3736e7959ef:
  Delete: bdb/db185/db185_int.h
BitKeeper/deleted/.del-acconfig.h~411e8854d67ad8b5:
  Delete: bdb/dist/acconfig.h
BitKeeper/deleted/.del-mutex.m4~a13383cde18a64e1:
  Delete: bdb/dist/aclocal/mutex.m4
BitKeeper/deleted/.del-options.m4~b9d0ca637213750a:
  Delete: bdb/dist/aclocal/options.m4
BitKeeper/deleted/.del-programs.m4~3ce7890b47732b30:
  Delete: bdb/dist/aclocal/programs.m4
BitKeeper/deleted/.del-tcl.m4~f944e2db93c3b6db:
  Delete: bdb/dist/aclocal/tcl.m4
BitKeeper/deleted/.del-types.m4~59cae158c9a32cff:
  Delete: bdb/dist/aclocal/types.m4
BitKeeper/deleted/.del-script~d38f6d3a4f159cb4:
  Delete: bdb/dist/build/script
BitKeeper/deleted/.del-configure.in~ac795a92c8fe049c:
  Delete: bdb/dist/configure.in
BitKeeper/deleted/.del-ltconfig~66bbd007d8024af:
  Delete: bdb/dist/ltconfig
BitKeeper/deleted/.del-rec_ctemp~a28554362534f00a:
  Delete: bdb/dist/rec_ctemp
BitKeeper/deleted/.del-s_tcl~2ffe4326459fcd9f:
  Delete: bdb/dist/s_tcl
BitKeeper/deleted/.del-.IGNORE_ME~d8148b08fa7d5d15:
  Delete: bdb/dist/template/.IGNORE_ME
BitKeeper/deleted/.del-btree.h~179f2aefec1753d:
  Delete: bdb/include/btree.h
BitKeeper/deleted/.del-cxx_int.h~6b649c04766508f8:
  Delete: bdb/include/cxx_int.h
BitKeeper/deleted/.del-db.src~6b433ae615b16a8d:
  Delete: bdb/include/db.src
BitKeeper/deleted/.del-db_185.h~ad8b373d9391d35c:
  Delete: bdb/include/db_185.h
BitKeeper/deleted/.del-db_am.h~a714912b6b75932f:
  Delete: bdb/include/db_am.h
BitKeeper/deleted/.del-db_cxx.h~fcafadf45f5d19e9:
  Delete: bdb/include/db_cxx.h
BitKeeper/deleted/.del-db_dispatch.h~6844f20f7eb46904:
  Delete: bdb/include/db_dispatch.h
BitKeeper/deleted/.del-db_int.src~419a3f48b6a01da7:
  Delete: bdb/include/db_int.src
BitKeeper/deleted/.del-db_join.h~76f9747a42c3399a:
  Delete: bdb/include/db_join.h
BitKeeper/deleted/.del-db_page.h~e302ca3a4db3abdc:
  Delete: bdb/include/db_page.h
BitKeeper/deleted/.del-db_server_int.h~e1d20b6ba3bca1ab:
  Delete: bdb/include/db_server_int.h
BitKeeper/deleted/.del-db_shash.h~5fbf2d696fac90f3:
  Delete: bdb/include/db_shash.h
BitKeeper/deleted/.del-db_swap.h~1e60887550864a59:
  Delete: bdb/include/db_swap.h
BitKeeper/deleted/.del-db_upgrade.h~c644eee73701fc8d:
  Delete: bdb/include/db_upgrade.h
BitKeeper/deleted/.del-db_verify.h~b8d6c297c61f342e:
  Delete: bdb/include/db_verify.h
BitKeeper/deleted/.del-debug.h~dc2b4f2cf27ccebc:
  Delete: bdb/include/debug.h
BitKeeper/deleted/.del-hash.h~2aaa548b28882dfb:
  Delete: bdb/include/hash.h
BitKeeper/deleted/.del-lock.h~a761c1b7de57b77f:
  Delete: bdb/include/lock.h
BitKeeper/deleted/.del-log.h~ff20184238e35e4d:
  Delete: bdb/include/log.h
BitKeeper/deleted/.del-mp.h~7e317597622f3411:
  Delete: bdb/include/mp.h
BitKeeper/deleted/.del-mutex.h~d3ae7a2977a68137:
  Delete: bdb/include/mutex.h
BitKeeper/deleted/.del-os.h~91867cc8757cd0e3:
  Delete: bdb/include/os.h
BitKeeper/deleted/.del-os_jump.h~e1b939fa5151d4be:
  Delete: bdb/include/os_jump.h
BitKeeper/deleted/.del-qam.h~6fad0c1b5723d597:
  Delete: bdb/include/qam.h
BitKeeper/deleted/.del-queue.h~4c72c0826c123d5:
  Delete: bdb/include/queue.h
BitKeeper/deleted/.del-region.h~513fe04d977ca0fc:
  Delete: bdb/include/region.h
BitKeeper/deleted/.del-shqueue.h~525fc3e6c2025c36:
  Delete: bdb/include/shqueue.h
BitKeeper/deleted/.del-tcl_db.h~c536fd61a844f23f:
  Delete: bdb/include/tcl_db.h
BitKeeper/deleted/.del-txn.h~c8d94b221ec147e4:
  Delete: bdb/include/txn.h
BitKeeper/deleted/.del-xa.h~ecc466493aae9d9a:
  Delete: bdb/include/xa.h
BitKeeper/deleted/.del-DbRecoveryInit.java~756b52601a0b9023:
  Delete: bdb/java/src/com/sleepycat/db/DbRecoveryInit.java
BitKeeper/deleted/.del-DbTxnRecover.java~74607cba7ab89d6d:
  Delete: bdb/java/src/com/sleepycat/db/DbTxnRecover.java
BitKeeper/deleted/.del-lock_conflict.c~fc5e0f14cf597a2b:
  Delete: bdb/lock/lock_conflict.c
BitKeeper/deleted/.del-log.src~53ac9e7b5cb023f2:
  Delete: bdb/log/log.src
BitKeeper/deleted/.del-log_findckp.c~24287f008916e81f:
  Delete: bdb/log/log_findckp.c
BitKeeper/deleted/.del-log_rec.c~d51711f2cac09297:
  Delete: bdb/log/log_rec.c
BitKeeper/deleted/.del-log_register.c~b40bb4efac75ca15:
  Delete: bdb/log/log_register.c
BitKeeper/deleted/.del-Design~b3d0f179f2767b:
  Delete: bdb/mp/Design
BitKeeper/deleted/.del-os_finit.c~95dbefc6fe79b26c:
  Delete: bdb/os/os_finit.c
BitKeeper/deleted/.del-os_abs.c~df95d1e7db81924:
  Delete: bdb/os_vxworks/os_abs.c
BitKeeper/deleted/.del-os_finit.c~803b484bdb9d0122:
  Delete: bdb/os_vxworks/os_finit.c
BitKeeper/deleted/.del-os_map.c~3a6d7926398b76d3:
  Delete: bdb/os_vxworks/os_map.c
BitKeeper/deleted/.del-os_finit.c~19a227c6d3c78ad:
  Delete: bdb/os_win32/os_finit.c
BitKeeper/deleted/.del-log-corruption.patch~1cf2ecc7c6408d5d:
  Delete: bdb/patches/log-corruption.patch
BitKeeper/deleted/.del-Btree.pm~af6d0c5eaed4a98e:
  Delete: bdb/perl.BerkeleyDB/BerkeleyDB/Btree.pm
BitKeeper/deleted/.del-BerkeleyDB.pm~7244036d4482643:
  Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pm
BitKeeper/deleted/.del-BerkeleyDB.pod~e7b18fd6132448e3:
  Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pod
BitKeeper/deleted/.del-Hash.pm~10292a26c06a5c95:
  Delete: bdb/perl.BerkeleyDB/BerkeleyDB/Hash.pm
BitKeeper/deleted/.del-BerkeleyDB.pod.P~79f76a1495eda203:
  Delete: bdb/perl.BerkeleyDB/BerkeleyDB.pod.P
BitKeeper/deleted/.del-BerkeleyDB.xs~80c99afbd98e392c:
  Delete: bdb/perl.BerkeleyDB/BerkeleyDB.xs
BitKeeper/deleted/.del-Changes~729c1891efa60de9:
  Delete: bdb/perl.BerkeleyDB/Changes
BitKeeper/deleted/.del-MANIFEST~63a1e34aecf157a0:
  Delete: bdb/perl.BerkeleyDB/MANIFEST
BitKeeper/deleted/.del-Makefile.PL~c68797707d8df87a:
  Delete: bdb/perl.BerkeleyDB/Makefile.PL
BitKeeper/deleted/.del-README~5f2f579b1a241407:
  Delete: bdb/perl.BerkeleyDB/README
BitKeeper/deleted/.del-Todo~dca3c66c193adda9:
  Delete: bdb/perl.BerkeleyDB/Todo
BitKeeper/deleted/.del-config.in~ae81681e450e0999:
  Delete: bdb/perl.BerkeleyDB/config.in
BitKeeper/deleted/.del-dbinfo~28ad67d83be4f68e:
  Delete: bdb/perl.BerkeleyDB/dbinfo
BitKeeper/deleted/.del-mkconsts~543ab60669c7a04e:
  Delete: bdb/perl.BerkeleyDB/mkconsts
BitKeeper/deleted/.del-mkpod~182c0ca54e439afb:
  Delete: bdb/perl.BerkeleyDB/mkpod
BitKeeper/deleted/.del-5.004~e008cb5a48805543:
  Delete: bdb/perl.BerkeleyDB/patches/5.004
BitKeeper/deleted/.del-irix_6_5.pl~61662bb08afcdec8:
  Delete: bdb/perl.BerkeleyDB/hints/irix_6_5.pl
BitKeeper/deleted/.del-solaris.pl~6771e7182394e152:
  Delete: bdb/perl.BerkeleyDB/hints/solaris.pl
BitKeeper/deleted/.del-typemap~783b8f5295b05f3d:
  Delete: bdb/perl.BerkeleyDB/typemap
BitKeeper/deleted/.del-5.004_01~6081ce2fff7b0bc:
  Delete: bdb/perl.BerkeleyDB/patches/5.004_01
BitKeeper/deleted/.del-5.004_02~87214eac35ad9e6:
  Delete: bdb/perl.BerkeleyDB/patches/5.004_02
BitKeeper/deleted/.del-5.004_03~9a672becec7cb40f:
  Delete: bdb/perl.BerkeleyDB/patches/5.004_03
BitKeeper/deleted/.del-5.004_04~e326cb51af09d154:
  Delete: bdb/perl.BerkeleyDB/patches/5.004_04
BitKeeper/deleted/.del-5.004_05~7ab457a1e41a92fe:
  Delete: bdb/perl.BerkeleyDB/patches/5.004_05
BitKeeper/deleted/.del-5.005~f9e2d59b5964cd4b:
  Delete: bdb/perl.BerkeleyDB/patches/5.005
BitKeeper/deleted/.del-5.005_01~3eb9fb7b5842ea8e:
  Delete: bdb/perl.BerkeleyDB/patches/5.005_01
BitKeeper/deleted/.del-5.005_02~67477ce0bef717cb:
  Delete: bdb/perl.BerkeleyDB/patches/5.005_02
BitKeeper/deleted/.del-5.005_03~c4c29a1fb21e290a:
  Delete: bdb/perl.BerkeleyDB/patches/5.005_03
BitKeeper/deleted/.del-5.6.0~e1fb9897d124ee22:
  Delete: bdb/perl.BerkeleyDB/patches/5.6.0
BitKeeper/deleted/.del-btree.t~e4a1a3c675ddc406:
  Delete: bdb/perl.BerkeleyDB/t/btree.t
BitKeeper/deleted/.del-db-3.0.t~d2c60991d84558f2:
  Delete: bdb/perl.BerkeleyDB/t/db-3.0.t
BitKeeper/deleted/.del-db-3.1.t~6ee88cd13f55e018:
  Delete: bdb/perl.BerkeleyDB/t/db-3.1.t
BitKeeper/deleted/.del-db-3.2.t~f73b6461f98fd1cf:
  Delete: bdb/perl.BerkeleyDB/t/db-3.2.t
BitKeeper/deleted/.del-destroy.t~cc6a2ae1980a2ecd:
  Delete: bdb/perl.BerkeleyDB/t/destroy.t
BitKeeper/deleted/.del-env.t~a8604a4499c4bd07:
  Delete: bdb/perl.BerkeleyDB/t/env.t
BitKeeper/deleted/.del-examples.t~2571b77c3cc75574:
  Delete: bdb/perl.BerkeleyDB/t/examples.t
BitKeeper/deleted/.del-examples.t.T~8228bdd75ac78b88:
  Delete: bdb/perl.BerkeleyDB/t/examples.t.T
BitKeeper/deleted/.del-examples3.t.T~66a186897a87026d:
  Delete: bdb/perl.BerkeleyDB/t/examples3.t.T
BitKeeper/deleted/.del-examples3.t~fe3822ba2f2d7f83:
  Delete: bdb/perl.BerkeleyDB/t/examples3.t
BitKeeper/deleted/.del-filter.t~f87b045c1b708637:
  Delete: bdb/perl.BerkeleyDB/t/filter.t
BitKeeper/deleted/.del-hash.t~616bfb4d644de3a3:
  Delete: bdb/perl.BerkeleyDB/t/hash.t
BitKeeper/deleted/.del-join.t~29fc39f74a83ca22:
  Delete: bdb/perl.BerkeleyDB/t/join.t
BitKeeper/deleted/.del-mldbm.t~31f5015341eea040:
  Delete: bdb/perl.BerkeleyDB/t/mldbm.t
BitKeeper/deleted/.del-queue.t~8f338034ce44a641:
  Delete: bdb/perl.BerkeleyDB/t/queue.t
BitKeeper/deleted/.del-recno.t~d4ddbd3743add63e:
  Delete: bdb/perl.BerkeleyDB/t/recno.t
BitKeeper/deleted/.del-strict.t~6885cdd2ea71ca2d:
  Delete: bdb/perl.BerkeleyDB/t/strict.t
BitKeeper/deleted/.del-subdb.t~aab62a5d5864c603:
  Delete: bdb/perl.BerkeleyDB/t/subdb.t
BitKeeper/deleted/.del-txn.t~65033b8558ae1216:
  Delete: bdb/perl.BerkeleyDB/t/txn.t
BitKeeper/deleted/.del-unknown.t~f3710458682665e1:
  Delete: bdb/perl.BerkeleyDB/t/unknown.t
BitKeeper/deleted/.del-Changes~436f74a5c414c65b:
  Delete: bdb/perl.DB_File/Changes
BitKeeper/deleted/.del-DB_File.pm~ae0951c6c7665a82:
  Delete: bdb/perl.DB_File/DB_File.pm
BitKeeper/deleted/.del-DB_File.xs~89e49a0b5556f1d8:
  Delete: bdb/perl.DB_File/DB_File.xs
BitKeeper/deleted/.del-DB_File_BS~290fad5dbbb87069:
  Delete: bdb/perl.DB_File/DB_File_BS
BitKeeper/deleted/.del-MANIFEST~90ee581572bdd4ac:
  Delete: bdb/perl.DB_File/MANIFEST
BitKeeper/deleted/.del-Makefile.PL~ac0567bb5a377e38:
  Delete: bdb/perl.DB_File/Makefile.PL
BitKeeper/deleted/.del-README~77e924a5a9bae6b3:
  Delete: bdb/perl.DB_File/README
BitKeeper/deleted/.del-config.in~ab4c2792b86a810b:
  Delete: bdb/perl.DB_File/config.in
BitKeeper/deleted/.del-dbinfo~461c43b30fab2cb:
  Delete: bdb/perl.DB_File/dbinfo
BitKeeper/deleted/.del-dynixptx.pl~50dcddfae25d17e9:
  Delete: bdb/perl.DB_File/hints/dynixptx.pl
BitKeeper/deleted/.del-typemap~55cffb3288a9e587:
  Delete: bdb/perl.DB_File/typemap
BitKeeper/deleted/.del-version.c~a4df0e646f8b3975:
  Delete: bdb/perl.DB_File/version.c
BitKeeper/deleted/.del-5.004_01~d6830d0082702af7:
  Delete: bdb/perl.DB_File/patches/5.004_01
BitKeeper/deleted/.del-5.004_02~78b082dc80c91031:
  Delete: bdb/perl.DB_File/patches/5.004_02
BitKeeper/deleted/.del-5.004~4411ec2e3c9e008b:
  Delete: bdb/perl.DB_File/patches/5.004
BitKeeper/deleted/.del-sco.pl~1e795fe14fe4dcfe:
  Delete: bdb/perl.DB_File/hints/sco.pl
BitKeeper/deleted/.del-5.004_03~33f274648b160d95:
  Delete: bdb/perl.DB_File/patches/5.004_03
BitKeeper/deleted/.del-5.004_04~8f3d1b3cf18bb20a:
  Delete: bdb/perl.DB_File/patches/5.004_04
BitKeeper/deleted/.del-5.004_05~9c0f02e7331e142:
  Delete: bdb/perl.DB_File/patches/5.004_05
BitKeeper/deleted/.del-5.005~c2108cb2e3c8d951:
  Delete: bdb/perl.DB_File/patches/5.005
BitKeeper/deleted/.del-5.005_01~3b45e9673afc4cfa:
  Delete: bdb/perl.DB_File/patches/5.005_01
BitKeeper/deleted/.del-5.005_02~9fe5766bb02a4522:
  Delete: bdb/perl.DB_File/patches/5.005_02
BitKeeper/deleted/.del-5.005_03~ffa1c38c19ae72ea:
  Delete: bdb/perl.DB_File/patches/5.005_03
BitKeeper/deleted/.del-5.6.0~373be3a5ce47be85:
  Delete: bdb/perl.DB_File/patches/5.6.0
BitKeeper/deleted/.del-db-btree.t~3231595a1c241eb3:
  Delete: bdb/perl.DB_File/t/db-btree.t
BitKeeper/deleted/.del-db-hash.t~7c4ad0c795c7fad2:
  Delete: bdb/perl.DB_File/t/db-hash.t
BitKeeper/deleted/.del-db-recno.t~6c2d3d80b9ba4a50:
  Delete: bdb/perl.DB_File/t/db-recno.t
BitKeeper/deleted/.del-db_server.sed~cdb00ebcd48a64e2:
  Delete: bdb/rpc_server/db_server.sed
BitKeeper/deleted/.del-db_server_proc.c~d46c8f409c3747f4:
  Delete: bdb/rpc_server/db_server_proc.c
BitKeeper/deleted/.del-db_server_svc.sed~3f5e59f334fa4607:
  Delete: bdb/rpc_server/db_server_svc.sed
BitKeeper/deleted/.del-db_server_util.c~a809f3a4629acda:
  Delete: bdb/rpc_server/db_server_util.c
BitKeeper/deleted/.del-log.tcl~ff1b41f1355b97d7:
  Delete: bdb/test/log.tcl
BitKeeper/deleted/.del-mpool.tcl~b0df4dc1b04db26c:
  Delete: bdb/test/mpool.tcl
BitKeeper/deleted/.del-mutex.tcl~52fd5c73a150565:
  Delete: bdb/test/mutex.tcl
BitKeeper/deleted/.del-txn.tcl~c4ff071550b5446e:
  Delete: bdb/test/txn.tcl
BitKeeper/deleted/.del-README~e800a12a5392010a:
  Delete: bdb/test/upgrade/README
BitKeeper/deleted/.del-pack-2.6.6.pl~89d5076d758d3e98:
  Delete: bdb/test/upgrade/generate-2.X/pack-2.6.6.pl
BitKeeper/deleted/.del-test-2.6.patch~4a52dc83d447547b:
  Delete: bdb/test/upgrade/generate-2.X/test-2.6.patch
2002-10-30 15:57:05 +04:00

879 lines
28 KiB
C

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2002
* Sleepycat Software. All rights reserved.
*
* $Id: mutex.h,v 11.71 2002/09/10 01:36:48 bostic 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;
#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_PLAN9
typedef 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_WIN16
typedef 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; \
union { \
HANDLE event; /* Windows event HANDLE for wakeups */ \
u_int32_t id; /* ID used for shared mutexes */ \
} /* anonymous */;
#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_ASSEMBLY
typedef 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_ASSEMBLY
typedef 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 int
MUTEX_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 int
MUTEX_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_ASSEMBLY
typedef 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_ASSEMBLY
typedef 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
typedef unsigned char tsl_t;
#ifdef LOAD_ACTUAL_MUTEX_CODE
/*
* For gcc/ia64, 0 is clear, 1 is set.
*/
#define MUTEX_SET(tsl) ({ \
register tsl_t *__l = (tsl); \
long __r; \
asm volatile("xchg1 %0=%1,%3" : "=r"(__r), "=m"(*__l) : "1"(*__l), "r"(1));\
__r ^ 1; \
})
/*
* Store through a "volatile" pointer so we get a store with "release"
* semantics.
*/
#define MUTEX_UNSET(tsl) (*(volatile unsigned char *)(tsl) = 0)
#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl)
#endif
#endif
/*********************************************************************
* PowerPC/gcc assembly.
*********************************************************************/
#if defined(HAVE_MUTEX_PPC_GENERIC_GCC_ASSEMBLY) || \
(HAVE_MUTEX_PPC_APPLE_GCC_ASSEMBLY)
typedef u_int32_t tsl_t;
#ifdef LOAD_ACTUAL_MUTEX_CODE
/*
* The PowerPC does a sort of pseudo-atomic locking. You set up a
* 'reservation' on a chunk of memory containing a mutex by loading the
* mutex value with LWARX. If the mutex has an 'unlocked' (arbitrary)
* value, you then try storing into it with STWCX. If no other process or
* thread broke your 'reservation' by modifying the memory containing the
* mutex, then the STCWX succeeds; otherwise it fails and you try to get
* a reservation again.
*
* While mutexes are explicitly 4 bytes, a 'reservation' applies to an
* entire cache line, normally 32 bytes, aligned naturally. If the mutex
* lives near data that gets changed a lot, there's a chance that you'll
* see more broken reservations than you might otherwise. The only
* situation in which this might be a problem is if one processor is
* beating on a variable in the same cache block as the mutex while another
* processor tries to acquire the mutex. That's bad news regardless
* because of the way it bashes caches, but if you can't guarantee that a
* mutex will reside in a relatively quiescent cache line, you might
* consider padding the mutex to force it to live in a cache line by
* itself. No, you aren't guaranteed that cache lines are 32 bytes. Some
* embedded processors use 16-byte cache lines, while some 64-bit
* processors use 128-bit cache lines. But assuming a 32-byte cache line
* won't get you into trouble for now.
*
* If mutex locking is a bottleneck, then you can speed it up by adding a
* regular LWZ load before the LWARX load, so that you can test for the
* common case of a locked mutex without wasting cycles making a reservation.
*
* 'set' mutexes have the value 1, like on Intel; the returned value from
* MUTEX_SET() is 1 if the mutex previously had its low bit clear, 0 otherwise.
*
* Mutexes on Mac OS X work the same way as the standard PowerPC version, but
* the assembler syntax is subtly different -- the standard PowerPC version
* assembles but doesn't work correctly. This version makes (unnecessary?)
* use of a stupid linker trick: __db_mutex_tas_dummy is never called, but the
* ___db_mutex_set label is used as a function name.
*/
#ifdef HAVE_MUTEX_PPC_APPLE_GCC_ASSEMBLY
extern int __db_mutex_set __P((volatile tsl_t *));
void
__db_mutex_tas_dummy()
{
__asm__ __volatile__(" \n\
.globl ___db_mutex_set \n\
___db_mutex_set: \n\
lwarx r5,0,r3 \n\
cmpwi r5,0 \n\
bne fail \n\
addi r5,r5,1 \n\
stwcx. r5,0,r3 \n\
beq success \n\
fail: \n\
li r3,0 \n\
blr \n\
success: \n\
li r3,1 \n\
blr");
}
#define MUTEX_SET(tsl) __db_mutex_set(tsl)
#endif
#ifdef HAVE_MUTEX_PPC_GENERIC_GCC_ASSEMBLY
#define MUTEX_SET(tsl) ({ \
int __one = 1; \
int __r; \
tsl_t *__l = (tsl); \
asm volatile (" \
0: \
lwarx %0,0,%1; \
cmpwi %0,0; \
bne 1f; \
stwcx. %2,0,%1; \
bne- 0b; \
1:" \
: "=&r" (__r) \
: "r" (__l), "r" (__one)); \
!(__r & 1); \
})
#endif
#define MUTEX_UNSET(tsl) (*(tsl) = 0)
#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl)
#endif
#endif
/*********************************************************************
* S/390 32-bit assembly.
*********************************************************************/
#ifdef HAVE_MUTEX_S390_GCC_ASSEMBLY
typedef int tsl_t;
#ifdef LOAD_ACTUAL_MUTEX_CODE
/*
* For gcc/S390, 0 is clear, 1 is set.
*/
static inline int
MUTEX_SET(tsl_t *tsl) { \
register tsl_t *__l = (tsl); \
int __r; \
asm volatile( \
" la 1,%1\n" \
" lhi 0,1\n" \
" l %0,%1\n" \
"0: cs %0,0,0(1)\n" \
" jl 0b" \
: "=&d" (__r), "+m" (*__l) \
: : "0", "1", "cc"); \
return !__r; \
}
#define MUTEX_UNSET(tsl) (*(tsl) = 0)
#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl)
#endif
#endif
/*********************************************************************
* SCO/cc assembly.
*********************************************************************/
#ifdef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY
typedef unsigned char tsl_t;
#ifdef LOAD_ACTUAL_MUTEX_CODE
/*
* UnixWare has threads in libthread, but OpenServer doesn't (yet).
*
* For 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_ASSEMBLY
typedef 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.
*
* For 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_ASSEMBLY
typedef int tsl_t;
#define MUTEX_ALIGN sizeof(int)
#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_ASSEMBLY
typedef unsigned char tsl_t;
#ifdef LOAD_ACTUAL_MUTEX_CODE
/*
* For 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)
#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
/*
* !!!
* These defines are separated into the u_int8_t flags stored in the
* mutex below, and the 32 bit flags passed to __db_mutex_setup.
* But they must co-exist and not overlap. Flags to __db_mutex_setup are:
*
* 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_IGNORE 0x001 /* Ignore, no lock required. */
#define MUTEX_INITED 0x002 /* Mutex is successfully initialized */
#define MUTEX_MPOOL 0x004 /* Allocated from mpool. */
#define MUTEX_SELF_BLOCK 0x008 /* Must block self. */
/* Flags only, may be larger than 0xff. */
#define MUTEX_ALLOC 0x00000100 /* Allocate and init a mutex */
#define MUTEX_NO_RECORD 0x00000200 /* Do not record lock */
#define MUTEX_NO_RLOCK 0x00000400 /* Do not acquire region lock */
#define MUTEX_THREAD 0x00000800 /* 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 spins; /* Spins before block. */
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
u_int8_t flags; /* MUTEX_XXX */
};
/* 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)
#elif defined(HAVE_MUTEX_WIN32)
#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
#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_ */