summaryrefslogtreecommitdiff
path: root/db/mutex
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2007-07-30 11:58:31 +0300
committerPanu Matilainen <pmatilai@redhat.com>2007-07-30 11:58:31 +0300
commitcab228435bde1b5496522c03a4ce9840f2ef3701 (patch)
tree2c37b65d176e2de097603333f4de071c31eeff3d /db/mutex
parent2d07882d45e9e575c00f8f402d4c7271bb65cfe9 (diff)
downloadlibrpm-tizen-cab228435bde1b5496522c03a4ce9840f2ef3701.tar.gz
librpm-tizen-cab228435bde1b5496522c03a4ce9840f2ef3701.tar.bz2
librpm-tizen-cab228435bde1b5496522c03a4ce9840f2ef3701.zip
Update internal BDB to version 4.6.18.
Diffstat (limited to 'db/mutex')
-rw-r--r--db/mutex/mut_alloc.c6
-rw-r--r--db/mutex/mut_failchk.c5
-rw-r--r--db/mutex/mut_fcntl.c7
-rw-r--r--db/mutex/mut_method.c5
-rw-r--r--db/mutex/mut_pthread.c29
-rw-r--r--db/mutex/mut_region.c99
-rw-r--r--db/mutex/mut_stat.c99
-rw-r--r--db/mutex/mut_stub.c234
-rw-r--r--db/mutex/mut_tas.c45
-rw-r--r--db/mutex/mut_win32.c24
-rw-r--r--db/mutex/mutex.c392
-rw-r--r--db/mutex/test_mutex.c (renamed from db/mutex/tm.c)435
-rw-r--r--db/mutex/uts4_cc.s5
13 files changed, 678 insertions, 707 deletions
diff --git a/db/mutex/mut_alloc.c b/db/mutex/mut_alloc.c
index bfc453dc6..12789cce1 100644
--- a/db/mutex/mut_alloc.c
+++ b/db/mutex/mut_alloc.c
@@ -1,10 +1,9 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 1999,2007 Oracle. All rights reserved.
*
- * $Id: mut_alloc.c,v 12.15 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_alloc.c,v 12.18 2007/05/17 15:15:45 bostic Exp $
*/
#include "db_config.h"
@@ -119,6 +118,7 @@ __mutex_alloc_int(dbenv, locksys, alloc_id, flags, indxp)
*indxp = mtxregion->mutex_next;
mutexp = MUTEXP_SET(*indxp);
+ DB_ASSERT(dbenv, ((uintptr_t)mutexp & (dbenv->mutex_align - 1)) == 0);
mtxregion->mutex_next = mutexp->mutex_next_link;
--mtxregion->stat.st_mutex_free;
diff --git a/db/mutex/mut_failchk.c b/db/mutex/mut_failchk.c
index 3d9d46a98..707dc57cf 100644
--- a/db/mutex/mut_failchk.c
+++ b/db/mutex/mut_failchk.c
@@ -1,10 +1,9 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 2005,2007 Oracle. All rights reserved.
*
- * $Id: mut_failchk.c,v 12.3 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_failchk.c,v 12.5 2007/05/17 15:15:45 bostic Exp $
*/
#include "db_config.h"
diff --git a/db/mutex/mut_fcntl.c b/db/mutex/mut_fcntl.c
index eb4c6ef7f..03a55a6fc 100644
--- a/db/mutex/mut_fcntl.c
+++ b/db/mutex/mut_fcntl.c
@@ -1,10 +1,9 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 1996,2007 Oracle. All rights reserved.
*
- * $Id: mut_fcntl.c,v 12.20 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_fcntl.c,v 12.23 2007/05/17 15:15:45 bostic Exp $
*/
#include "db_config.h"
@@ -73,7 +72,7 @@ __db_fcntl_mutex_lock(dbenv, mutex)
* up to 1 second.
*/
for (ms = 1; F_ISSET(mutexp, DB_MUTEX_LOCKED);) {
- __os_sleep(NULL, 0, ms * USEC_PER_MS);
+ __os_sleep(NULL, 0, ms * US_PER_MS);
if ((ms <<= 1) > MS_PER_SEC)
ms = MS_PER_SEC;
}
diff --git a/db/mutex/mut_method.c b/db/mutex/mut_method.c
index 08da11d94..47a2aebf5 100644
--- a/db/mutex/mut_method.c
+++ b/db/mutex/mut_method.c
@@ -1,10 +1,9 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 1996,2007 Oracle. All rights reserved.
*
- * $Id: mut_method.c,v 12.12 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_method.c,v 12.14 2007/05/17 15:15:45 bostic Exp $
*/
#include "db_config.h"
diff --git a/db/mutex/mut_pthread.c b/db/mutex/mut_pthread.c
index 08c7b388b..58c916e1c 100644
--- a/db/mutex/mut_pthread.c
+++ b/db/mutex/mut_pthread.c
@@ -1,15 +1,19 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 1999,2007 Oracle. All rights reserved.
*
- * $Id: mut_pthread.c,v 12.19 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_pthread.c,v 12.24 2007/06/21 16:39:20 ubell Exp $
*/
#include "db_config.h"
#include "db_int.h"
+
+/*
+ * This is where we load in architecture/compiler specific mutex code.
+ */
+#define LOAD_ACTUAL_MUTEX_CODE
#include "dbinc/mutex_int.h"
#ifdef HAVE_MUTEX_SOLARIS_LWP
@@ -181,7 +185,7 @@ __db_pthread_mutex_lock(dbenv, mutex)
mtxregion = mtxmgr->reginfo.primary;
mutexp = MUTEXP_SET(mutex);
-#ifdef HAVE_STATISTICS
+#if defined(HAVE_STATISTICS) && !defined(HAVE_MUTEX_HYBRID)
/*
* We want to know which mutexes are contentious, but don't want to
* do an interlocked test here -- that's slower when the underlying
@@ -200,6 +204,17 @@ __db_pthread_mutex_lock(dbenv, mutex)
goto err;
if (F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK)) {
+ /*
+ * If we are using hybrid mutexes then the pthread mutexes
+ * are only used to wait after spinning on the TAS mutex.
+ * Set the wait flag before checking to see if the mutex
+ * is still locked. The holder will clear the bit before
+ * checking the wait flag.
+ */
+#ifdef HAVE_MUTEX_HYBRID
+ mutexp->wait++;
+ MUTEX_MEMBAR(mutexp->wait);
+#endif
while (F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
RET_SET((pthread_cond_wait(
&mutexp->cond, &mutexp->mutex)), ret);
@@ -223,9 +238,13 @@ __db_pthread_mutex_lock(dbenv, mutex)
}
}
+#ifdef HAVE_MUTEX_HYBRID
+ mutexp->wait--;
+#else
F_SET(mutexp, DB_MUTEX_LOCKED);
dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
CHECK_MTX_THREAD(dbenv, mutexp);
+#endif
/*
* According to HP-UX engineers contacted by Netscape,
@@ -297,7 +316,7 @@ __db_pthread_mutex_unlock(dbenv, mutex)
mtxregion = mtxmgr->reginfo.primary;
mutexp = MUTEXP_SET(mutex);
-#ifdef DIAGNOSTIC
+#if !defined(HAVE_MUTEX_HYBRID) && defined(DIAGNOSTIC)
if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
__db_errx(
dbenv, "pthread unlock failed: lock already unlocked");
diff --git a/db/mutex/mut_region.c b/db/mutex/mut_region.c
index 6e1b4f3ad..99ad80c70 100644
--- a/db/mutex/mut_region.c
+++ b/db/mutex/mut_region.c
@@ -1,10 +1,9 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 1996,2007 Oracle. All rights reserved.
*
- * $Id: mut_region.c,v 12.18 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_region.c,v 12.25 2007/05/17 15:15:45 bostic Exp $
*/
#include "db_config.h"
@@ -13,8 +12,10 @@
#include "dbinc/log.h"
#include "dbinc/lock.h"
#include "dbinc/mp.h"
+#include "dbinc/txn.h"
#include "dbinc/mutex_int.h"
+static size_t __mutex_align_size __P((DB_ENV *));
static int __mutex_region_init __P((DB_ENV *, DB_MUTEXMGR *));
static size_t __mutex_region_size __P((DB_ENV *));
@@ -22,11 +23,12 @@ static size_t __mutex_region_size __P((DB_ENV *));
* __mutex_open --
* Open a mutex region.
*
- * PUBLIC: int __mutex_open __P((DB_ENV *));
+ * PUBLIC: int __mutex_open __P((DB_ENV *, int));
*/
int
-__mutex_open(dbenv)
+__mutex_open(dbenv, create_ok)
DB_ENV *dbenv;
+ int create_ok;
{
DB_MUTEXMGR *mtxmgr;
DB_MUTEXREGION *mtxregion;
@@ -57,20 +59,21 @@ __mutex_open(dbenv)
__lock_region_mutex_count(dbenv) +
__log_region_mutex_count(dbenv) +
__memp_region_mutex_count(dbenv) +
+ __txn_region_mutex_count(dbenv) +
dbenv->mutex_inc + 100;
/* Create/initialize the mutex manager structure. */
if ((ret = __os_calloc(dbenv, 1, sizeof(DB_MUTEXMGR), &mtxmgr)) != 0)
return (ret);
- /* Join/create the txn region. */
+ /* Join/create the mutex region. */
mtxmgr->reginfo.dbenv = dbenv;
mtxmgr->reginfo.type = REGION_TYPE_MUTEX;
mtxmgr->reginfo.id = INVALID_REGION_ID;
mtxmgr->reginfo.flags = REGION_JOIN_OK;
- if (F_ISSET(dbenv, DB_ENV_CREATE))
+ if (create_ok)
F_SET(&mtxmgr->reginfo, REGION_CREATE_OK);
- if ((ret = __db_r_attach(dbenv,
+ if ((ret = __env_region_attach(dbenv,
&mtxmgr->reginfo, __mutex_region_size(dbenv))) != 0)
goto err;
@@ -82,7 +85,7 @@ __mutex_open(dbenv)
/* Set the local addresses. */
mtxregion = mtxmgr->reginfo.primary =
R_ADDR(&mtxmgr->reginfo, mtxmgr->reginfo.rp->primary);
- mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_offset);
+ mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_off);
dbenv->mutex_handle = mtxmgr;
@@ -123,20 +126,11 @@ __mutex_open(dbenv)
}
}
- /*
- * Initialize thread tracking. We want to do this as early
- * as possible in case we die. This sits in the mutex region
- * so do it now.
- */
- if ((ret = __env_thread_init(dbenv,
- F_ISSET(&mtxmgr->reginfo, REGION_CREATE))) != 0)
- goto err;
-
return (0);
err: dbenv->mutex_handle = NULL;
if (mtxmgr->reginfo.addr != NULL)
- (void)__db_r_detach(dbenv, &mtxmgr->reginfo, 0);
+ (void)__env_region_detach(dbenv, &mtxmgr->reginfo, 0);
__os_free(dbenv, mtxmgr);
return (ret);
@@ -159,8 +153,8 @@ __mutex_region_init(dbenv, mtxmgr)
COMPQUIET(mutexp, NULL);
- if ((ret = __db_shalloc(&mtxmgr->reginfo,
- sizeof(DB_MUTEXREGION), 0, &mtxmgr->reginfo.primary)) != 0) {
+ if ((ret = __env_alloc(&mtxmgr->reginfo,
+ sizeof(DB_MUTEXREGION), &mtxmgr->reginfo.primary)) != 0) {
__db_errx(dbenv,
"Unable to allocate memory for the mutex region");
return (ret);
@@ -174,8 +168,7 @@ __mutex_region_init(dbenv, mtxmgr)
dbenv, MTX_MUTEX_REGION, 0, &mtxregion->mtx_region)) != 0)
return (ret);
- mtxregion->mutex_size =
- (size_t)DB_ALIGN(sizeof(DB_MUTEX), dbenv->mutex_align);
+ mtxregion->mutex_size = __mutex_align_size(dbenv);
mtxregion->stat.st_mutex_align = dbenv->mutex_align;
mtxregion->stat.st_mutex_cnt = dbenv->mutex_cnt;
@@ -183,22 +176,29 @@ __mutex_region_init(dbenv, mtxmgr)
/*
* Get a chunk of memory to be used for the mutexes themselves. Each
- * piece of the memory must be properly aligned.
+ * piece of the memory must be properly aligned, and that alignment
+ * may be more restrictive than the memory alignment returned by the
+ * underlying allocation code. We already know how much memory each
+ * mutex in the array will take up, but we need to offset the first
+ * mutex in the array so the array begins properly aligned.
*
* The OOB mutex (MUTEX_INVALID) is 0. To make this work, we ignore
* the first allocated slot when we build the free list. We have to
* correct the count by 1 here, though, otherwise our counter will be
* off by 1.
*/
- if ((ret = __db_shalloc(&mtxmgr->reginfo,
+ if ((ret = __env_alloc(&mtxmgr->reginfo,
+ mtxregion->stat.st_mutex_align +
(mtxregion->stat.st_mutex_cnt + 1) * mtxregion->mutex_size,
- mtxregion->stat.st_mutex_align, &mutex_array)) != 0) {
+ &mutex_array)) != 0) {
__db_errx(dbenv,
"Unable to allocate memory for mutexes from the region");
return (ret);
}
- mtxregion->mutex_offset = R_OFFSET(&mtxmgr->reginfo, mutex_array);
+ mtxregion->mutex_off_alloc = R_OFFSET(&mtxmgr->reginfo, mutex_array);
+ mutex_array = ALIGNP_INC(mutex_array, mtxregion->stat.st_mutex_align);
+ mtxregion->mutex_off = R_OFFSET(&mtxmgr->reginfo, mutex_array);
mtxmgr->mutex_array = mutex_array;
/*
@@ -225,13 +225,13 @@ __mutex_region_init(dbenv, mtxmgr)
}
/*
- * __mutex_dbenv_refresh --
+ * __mutex_env_refresh --
* Clean up after the mutex region on a close or failed open.
*
- * PUBLIC: int __mutex_dbenv_refresh __P((DB_ENV *));
+ * PUBLIC: int __mutex_env_refresh __P((DB_ENV *));
*/
int
-__mutex_dbenv_refresh(dbenv)
+__mutex_env_refresh(dbenv)
DB_ENV *dbenv;
{
DB_MUTEXMGR *mtxmgr;
@@ -257,12 +257,12 @@ __mutex_dbenv_refresh(dbenv)
__mutex_resource_return(dbenv, reginfo);
#endif
/* Discard the mutex array. */
- __db_shalloc_free(
- reginfo, R_ADDR(reginfo, mtxregion->mutex_offset));
+ __env_alloc_free(
+ reginfo, R_ADDR(reginfo, mtxregion->mutex_off_alloc));
}
/* Detach from the region. */
- ret = __db_r_detach(dbenv, reginfo, 0);
+ ret = __env_region_detach(dbenv, reginfo, 0);
__os_free(dbenv, mtxmgr);
@@ -272,6 +272,18 @@ __mutex_dbenv_refresh(dbenv)
}
/*
+ * __mutex_align_size --
+ * Return how much memory each mutex will take up if an array of them
+ * are to be properly aligned, individually, within the array.
+ */
+static size_t
+__mutex_align_size(dbenv)
+ DB_ENV *dbenv;
+{
+ return ((size_t)DB_ALIGN(sizeof(DB_MUTEX), (dbenv)->mutex_align));
+}
+
+/*
* __mutex_region_size --
* Return the amount of space needed for the mutex region.
*/
@@ -282,16 +294,11 @@ __mutex_region_size(dbenv)
size_t s;
s = sizeof(DB_MUTEXMGR) + 1024;
- s += dbenv->mutex_cnt *
- __db_shalloc_size(sizeof(DB_MUTEX), dbenv->mutex_align);
- /*
- * Allocate space for thread info blocks. Max is only advisory,
- * so we allocate 25% more.
- */
- s += (dbenv->thr_max + dbenv->thr_max/4) *
- __db_shalloc_size(sizeof(DB_THREAD_INFO), sizeof(roff_t));
- s += dbenv->thr_nbucket *
- __db_shalloc_size(sizeof(DB_HASHTAB), sizeof(roff_t));
+
+ /* We discard one mutex for the OOB slot. */
+ s += __env_alloc_size(
+ (dbenv->mutex_cnt + 1) *__mutex_align_size(dbenv));
+
return (s);
}
@@ -320,8 +327,8 @@ __mutex_resource_return(dbenv, infop)
*
* Walk the list of mutexes and destroy any live ones.
*
- * This is just like joining a region -- the REGINFO we're handed
- * is the same as the one returned by __db_r_attach(), all we have
+ * This is just like joining a region -- the REGINFO we're handed is
+ * the same as the one returned by __env_region_attach(), all we have
* to do is fill in the links.
*
* !!!
@@ -334,7 +341,7 @@ __mutex_resource_return(dbenv, infop)
mtxmgr->reginfo = *infop;
mtxregion = mtxmgr->reginfo.primary =
R_ADDR(&mtxmgr->reginfo, mtxmgr->reginfo.rp->primary);
- mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_offset);
+ mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_off);
/*
* This is a little strange, but the mutex_handle is what all of the
diff --git a/db/mutex/mut_stat.c b/db/mutex/mut_stat.c
index 1e642fe2f..829d54a8f 100644
--- a/db/mutex/mut_stat.c
+++ b/db/mutex/mut_stat.c
@@ -1,10 +1,9 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 1996,2007 Oracle. All rights reserved.
*
- * $Id: mut_stat.c,v 12.17 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_stat.c,v 12.26 2007/05/17 17:18:01 bostic Exp $
*/
#include "db_config.h"
@@ -19,22 +18,21 @@ static int __mutex_print_all __P((DB_ENV *, u_int32_t));
static const char *__mutex_print_id __P((int));
static int __mutex_print_stats __P((DB_ENV *, u_int32_t));
static void __mutex_print_summary __P((DB_ENV *));
+static int __mutex_stat __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t));
/*
- * __mutex_stat --
- * DB_ENV->mutex_stat.
+ * __mutex_stat_pp --
+ * DB_ENV->mutex_stat pre/post processing.
*
- * PUBLIC: int __mutex_stat __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t));
+ * PUBLIC: int __mutex_stat_pp __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t));
*/
int
-__mutex_stat(dbenv, statp, flags)
+__mutex_stat_pp(dbenv, statp, flags)
DB_ENV *dbenv;
DB_MUTEX_STAT **statp;
u_int32_t flags;
{
- DB_MUTEXMGR *mtxmgr;
- DB_MUTEXREGION *mtxregion;
- DB_MUTEX_STAT *stats;
+ DB_THREAD_INFO *ip;
int ret;
PANIC_CHECK(dbenv);
@@ -43,6 +41,29 @@ __mutex_stat(dbenv, statp, flags)
"DB_ENV->mutex_stat", flags, DB_STAT_CLEAR)) != 0)
return (ret);
+ ENV_ENTER(dbenv, ip);
+ REPLICATION_WRAP(dbenv, (__mutex_stat(dbenv, statp, flags)), ret);
+ ENV_LEAVE(dbenv, ip);
+ return (ret);
+}
+
+/*
+ * __mutex_stat --
+ * DB_ENV->mutex_stat.
+ */
+static int
+__mutex_stat(dbenv, statp, flags)
+ DB_ENV *dbenv;
+ DB_MUTEX_STAT **statp;
+ u_int32_t flags;
+{
+ DB_MUTEXMGR *mtxmgr;
+ DB_MUTEXREGION *mtxregion;
+ DB_MUTEX_STAT *stats;
+ int ret;
+
+ PANIC_CHECK(dbenv);
+
*statp = NULL;
mtxmgr = dbenv->mutex_handle;
mtxregion = mtxmgr->reginfo.primary;
@@ -70,17 +91,17 @@ __mutex_stat(dbenv, statp, flags)
}
/*
- * __mutex_stat_print
- * DB_ENV->mutex_stat_print method.
+ * __mutex_stat_print_pp --
+ * DB_ENV->mutex_stat_print pre/post processing.
*
- * PUBLIC: int __mutex_stat_print __P((DB_ENV *, u_int32_t));
+ * PUBLIC: int __mutex_stat_print_pp __P((DB_ENV *, u_int32_t));
*/
int
-__mutex_stat_print(dbenv, flags)
+__mutex_stat_print_pp(dbenv, flags)
DB_ENV *dbenv;
u_int32_t flags;
{
- u_int32_t orig_flags;
+ DB_THREAD_INFO *ip;
int ret;
PANIC_CHECK(dbenv);
@@ -89,8 +110,28 @@ __mutex_stat_print(dbenv, flags)
flags, DB_STAT_ALL | DB_STAT_CLEAR)) != 0)
return (ret);
+ ENV_ENTER(dbenv, ip);
+ REPLICATION_WRAP(dbenv, (__mutex_stat_print(dbenv, flags)), ret);
+ ENV_LEAVE(dbenv, ip);
+ return (ret);
+}
+
+/*
+ * __mutex_stat_print
+ * DB_ENV->mutex_stat_print method.
+ *
+ * PUBLIC: int __mutex_stat_print __P((DB_ENV *, u_int32_t));
+ */
+int
+__mutex_stat_print(dbenv, flags)
+ DB_ENV *dbenv;
+ u_int32_t flags;
+{
+ u_int32_t orig_flags;
+ int ret;
+
orig_flags = flags;
- LF_CLR(DB_STAT_CLEAR);
+ LF_CLR(DB_STAT_CLEAR | DB_STAT_SUBSYSTEM);
if (flags == 0 || LF_ISSET(DB_STAT_ALL)) {
ret = __mutex_print_stats(dbenv, orig_flags);
__mutex_print_summary(dbenv);
@@ -149,10 +190,6 @@ __mutex_print_stats(dbenv, flags)
u_int32_t flags;
{
DB_MUTEX_STAT *sp;
- DB_MUTEXMGR *mtxmgr;
- DB_MUTEXREGION *mtxregion;
- REGINFO *infop;
- THREAD_INFO *thread;
int ret;
if ((ret = __mutex_stat(dbenv, &sp, LF_ISSET(DB_STAT_CLEAR))) != 0)
@@ -176,20 +213,6 @@ __mutex_print_stats(dbenv, flags)
__os_ufree(dbenv, sp);
- /*
- * Dump out the info we have on thread tracking, we do it here only
- * because we share the region.
- */
- if (dbenv->thr_hashtab != NULL) {
- mtxmgr = dbenv->mutex_handle;
- mtxregion = mtxmgr->reginfo.primary;
- infop = &mtxmgr->reginfo;
- thread = R_ADDR(infop, mtxregion->thread_off);
- STAT_ULONG("Thread blocks allocated", thread->thr_count);
- STAT_ULONG("Thread allocation threshold", thread->thr_max);
- STAT_ULONG("Thread hash buckets", thread->thr_nbucket);
- }
-
return (0);
}
@@ -222,7 +245,7 @@ __mutex_print_all(dbenv, flags)
mtxmgr = dbenv->mutex_handle;
mtxregion = mtxmgr->reginfo.primary;
- __db_print_reginfo(dbenv, &mtxmgr->reginfo, "Mutex");
+ __db_print_reginfo(dbenv, &mtxmgr->reginfo, "Mutex", flags);
__db_msg(dbenv, "%s", DB_GLOBAL(db_line));
__db_msg(dbenv, "DB_MUTEXREGION structure:");
@@ -282,6 +305,8 @@ __mutex_print_debug_single(dbenv, tag, mutex, flags)
DB_MSGBUF_INIT(&mb);
mbp = &mb;
+ if (LF_ISSET(DB_STAT_SUBSYSTEM))
+ LF_CLR(DB_STAT_CLEAR);
__db_msgadd(dbenv, mbp, "%lu\t%s ", (u_long)mutex, tag);
__mutex_print_debug_stats(dbenv, mbp, mutex, flags);
DB_MSGBUF_FLUSH(dbenv, mbp);
@@ -427,7 +452,7 @@ __mutex_clear(dbenv, mutex)
#else /* !HAVE_STATISTICS */
int
-__mutex_stat(dbenv, statp, flags)
+__mutex_stat_pp(dbenv, statp, flags)
DB_ENV *dbenv;
DB_MUTEX_STAT **statp;
u_int32_t flags;
@@ -439,7 +464,7 @@ __mutex_stat(dbenv, statp, flags)
}
int
-__mutex_stat_print(dbenv, flags)
+__mutex_stat_print_pp(dbenv, flags)
DB_ENV *dbenv;
u_int32_t flags;
{
diff --git a/db/mutex/mut_stub.c b/db/mutex/mut_stub.c
new file mode 100644
index 000000000..d4620c771
--- /dev/null
+++ b/db/mutex/mut_stub.c
@@ -0,0 +1,234 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996,2007 Oracle. All rights reserved.
+ *
+ * $Id: mut_stub.c,v 12.4 2007/05/17 15:15:45 bostic Exp $
+ */
+
+#ifndef HAVE_MUTEX_SUPPORT
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+
+/*
+ * If the library wasn't compiled with mutex support, various routines
+ * aren't available. Stub them here, returning an appropriate error.
+ */
+static int __db_nomutex __P((DB_ENV *));
+
+/*
+ * __db_nomutex --
+ * Error when a Berkeley DB build doesn't include mutexes.
+ */
+static int
+__db_nomutex(dbenv)
+ DB_ENV *dbenv;
+{
+ __db_errx(dbenv,
+ "library build did not include support for mutexes");
+ return (DB_OPNOTSUP);
+}
+
+int
+__mutex_alloc_pp(dbenv, flags, indxp)
+ DB_ENV *dbenv;
+ u_int32_t flags;
+ db_mutex_t *indxp;
+{
+ COMPQUIET(flags, 0);
+ COMPQUIET(indxp, NULL);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_alloc(dbenv, alloc_id, flags, indxp)
+ DB_ENV *dbenv;
+ int alloc_id;
+ u_int32_t flags;
+ db_mutex_t *indxp;
+{
+ COMPQUIET(dbenv, NULL);
+ COMPQUIET(alloc_id, 0);
+ COMPQUIET(flags, 0);
+ *indxp = MUTEX_INVALID;
+ return (0);
+}
+
+void
+__mutex_clear(dbenv, mutex)
+ DB_ENV *dbenv;
+ db_mutex_t mutex;
+{
+ COMPQUIET(dbenv, NULL);
+ COMPQUIET(mutex, MUTEX_INVALID);
+}
+
+int
+__mutex_free_pp(dbenv, indx)
+ DB_ENV *dbenv;
+ db_mutex_t indx;
+{
+ COMPQUIET(indx, 0);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_free(dbenv, indxp)
+ DB_ENV *dbenv;
+ db_mutex_t *indxp;
+{
+ COMPQUIET(dbenv, NULL);
+ *indxp = MUTEX_INVALID;
+ return (0);
+}
+
+int
+__mutex_get_align(dbenv, alignp)
+ DB_ENV *dbenv;
+ u_int32_t *alignp;
+{
+ COMPQUIET(alignp, NULL);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_get_increment(dbenv, incrementp)
+ DB_ENV *dbenv;
+ u_int32_t *incrementp;
+{
+ COMPQUIET(incrementp, NULL);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_get_max(dbenv, maxp)
+ DB_ENV *dbenv;
+ u_int32_t *maxp;
+{
+ COMPQUIET(maxp, NULL);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_get_tas_spins(dbenv, tas_spinsp)
+ DB_ENV *dbenv;
+ u_int32_t *tas_spinsp;
+{
+ COMPQUIET(tas_spinsp, NULL);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_lock_pp(dbenv, indx)
+ DB_ENV *dbenv;
+ db_mutex_t indx;
+{
+ COMPQUIET(indx, 0);
+ return (__db_nomutex(dbenv));
+}
+
+void
+__mutex_print_debug_single(dbenv, tag, mutex, flags)
+ DB_ENV *dbenv;
+ const char *tag;
+ db_mutex_t mutex;
+ u_int32_t flags;
+{
+ COMPQUIET(dbenv, NULL);
+ COMPQUIET(tag, NULL);
+ COMPQUIET(mutex, MUTEX_INVALID);
+ COMPQUIET(flags, 0);
+}
+
+void
+__mutex_print_debug_stats(dbenv, mbp, mutex, flags)
+ DB_ENV *dbenv;
+ DB_MSGBUF *mbp;
+ db_mutex_t mutex;
+ u_int32_t flags;
+{
+ COMPQUIET(dbenv, NULL);
+ COMPQUIET(mbp, NULL);
+ COMPQUIET(mutex, MUTEX_INVALID);
+ COMPQUIET(flags, 0);
+}
+
+int
+__mutex_set_align(dbenv, align)
+ DB_ENV *dbenv;
+ u_int32_t align;
+{
+ COMPQUIET(align, 0);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_set_increment(dbenv, increment)
+ DB_ENV *dbenv;
+ u_int32_t increment;
+{
+ COMPQUIET(increment, 0);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_set_max(dbenv, max)
+ DB_ENV *dbenv;
+ u_int32_t max;
+{
+ COMPQUIET(max, 0);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_set_tas_spins(dbenv, tas_spins)
+ DB_ENV *dbenv;
+ u_int32_t tas_spins;
+{
+ COMPQUIET(tas_spins, 0);
+ return (__db_nomutex(dbenv));
+}
+
+void
+__mutex_set_wait_info(dbenv, mutex, waitp, nowaitp)
+ DB_ENV *dbenv;
+ db_mutex_t mutex;
+ u_int32_t *waitp, *nowaitp;
+{
+ COMPQUIET(dbenv, NULL);
+ COMPQUIET(mutex, MUTEX_INVALID);
+ *waitp = *nowaitp = 0;
+}
+
+int
+__mutex_stat_pp(dbenv, statp, flags)
+ DB_ENV *dbenv;
+ DB_MUTEX_STAT **statp;
+ u_int32_t flags;
+{
+ COMPQUIET(statp, NULL);
+ COMPQUIET(flags, 0);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_stat_print_pp(dbenv, flags)
+ DB_ENV *dbenv;
+ u_int32_t flags;
+{
+ COMPQUIET(flags, 0);
+ return (__db_nomutex(dbenv));
+}
+
+int
+__mutex_unlock_pp(dbenv, indx)
+ DB_ENV *dbenv;
+ db_mutex_t indx;
+{
+ COMPQUIET(indx, 0);
+ return (__db_nomutex(dbenv));
+}
+#endif /* !HAVE_MUTEX_SUPPORT */
diff --git a/db/mutex/mut_tas.c b/db/mutex/mut_tas.c
index bbe25fa8e..c9f3cddcf 100644
--- a/db/mutex/mut_tas.c
+++ b/db/mutex/mut_tas.c
@@ -1,10 +1,9 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 1996,2007 Oracle. All rights reserved.
*
- * $Id: mut_tas.c,v 12.20 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_tas.c,v 12.27 2007/06/21 16:39:20 ubell Exp $
*/
#include "db_config.h"
@@ -12,7 +11,7 @@
#include "db_int.h"
/*
- * This is where we load in the actual test-and-set mutex code.
+ * This is where we load in architecture/compiler specific mutex code.
*/
#define LOAD_ACTUAL_MUTEX_CODE
#include "dbinc/mutex_int.h"
@@ -51,6 +50,11 @@ __db_tas_mutex_init(dbenv, mutex, flags)
__db_syserr(dbenv, ret, "TAS: mutex initialize");
return (__os_posix_err(ret));
}
+#ifdef HAVE_MUTEX_HYBRID
+ if ((ret = __db_pthread_mutex_init(dbenv,
+ mutex, flags | DB_MUTEX_SELF_BLOCK)) != 0)
+ return (ret);
+#endif
return (0);
}
@@ -69,8 +73,11 @@ __db_tas_mutex_lock(dbenv, mutex)
DB_MUTEXMGR *mtxmgr;
DB_MUTEXREGION *mtxregion;
u_int32_t nspins;
+#ifdef HAVE_MUTEX_HYBRID
+ int ret;
+#else
u_long ms, max_ms;
-
+#endif
if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
return (0);
@@ -85,6 +92,7 @@ __db_tas_mutex_lock(dbenv, mutex)
++mutexp->mutex_set_nowait;
#endif
+#ifndef HAVE_MUTEX_HYBRID
/*
* Wait 1ms initially, up to 10ms for mutexes backing logical database
* locks, and up to 25 ms for mutual exclusion data structure mutexes.
@@ -92,6 +100,7 @@ __db_tas_mutex_lock(dbenv, mutex)
*/
ms = 1;
max_ms = F_ISSET(mutexp, DB_MUTEX_LOGICAL_LOCK) ? 10 : 25;
+#endif
loop: /* Attempt to acquire the resource for N spins. */
for (nspins =
@@ -167,9 +176,14 @@ relock:
}
/* Wait for the lock to become available. */
- __os_sleep(dbenv, 0, ms * USEC_PER_MS);
+#ifdef HAVE_MUTEX_HYBRID
+ if ((ret = __db_pthread_mutex_lock(dbenv, mutex)) != 0)
+ return (ret);
+#else
+ __os_sleep(dbenv, 0, ms * US_PER_MS);
if ((ms <<= 1) > max_ms)
ms = max_ms;
+#endif
/*
* We're spinning. The environment might be hung, and somebody else
@@ -196,6 +210,9 @@ __db_tas_mutex_unlock(dbenv, mutex)
DB_MUTEX *mutexp;
DB_MUTEXMGR *mtxmgr;
DB_MUTEXREGION *mtxregion;
+#ifdef HAVE_MUTEX_HYBRID
+ int ret;
+#endif
if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
return (0);
@@ -210,8 +227,15 @@ __db_tas_mutex_unlock(dbenv, mutex)
return (__db_panic(dbenv, EACCES));
}
#endif
+
F_CLR(mutexp, DB_MUTEX_LOCKED);
+#ifdef HAVE_MUTEX_HYBRID
+ MUTEX_MEMBAR(mutexp->flags);
+ if (mutexp->wait &&
+ (ret = __db_pthread_mutex_unlock(dbenv, mutex)) != 0)
+ return (ret);
+#endif
MUTEX_UNSET(&mutexp->tas);
return (0);
@@ -231,6 +255,9 @@ __db_tas_mutex_destroy(dbenv, mutex)
DB_MUTEX *mutexp;
DB_MUTEXMGR *mtxmgr;
DB_MUTEXREGION *mtxregion;
+#ifdef HAVE_MUTEX_HYBRID
+ int ret;
+#endif
if (!MUTEX_ON(dbenv))
return (0);
@@ -241,5 +268,11 @@ __db_tas_mutex_destroy(dbenv, mutex)
MUTEX_DESTROY(&mutexp->tas);
+#ifdef HAVE_MUTEX_HYBRID
+ if ((ret = __db_pthread_mutex_destroy(dbenv, mutex)) != 0)
+ return (ret);
+#endif
+
+ COMPQUIET(mutexp, NULL); /* MUTEX_DESTROY may not be defined. */
return (0);
}
diff --git a/db/mutex/mut_win32.c b/db/mutex/mut_win32.c
index 083784310..2d0385e90 100644
--- a/db/mutex/mut_win32.c
+++ b/db/mutex/mut_win32.c
@@ -1,10 +1,9 @@
/*
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2002-2006
- * Oracle Corporation. All rights reserved.
+ * Copyright (c) 2002,2007 Oracle. All rights reserved.
*
- * $Id: mut_win32.c,v 12.21 2006/08/24 14:46:16 bostic Exp $
+ * $Id: mut_win32.c,v 12.25 2007/06/28 11:14:04 alexg Exp $
*/
#include "db_config.h"
@@ -48,6 +47,7 @@ static __inline int get_handle(dbenv, mutexp, eventp)
for (id = (mutexp)->id; id != 0; id >>= 4)
*--p = hex_digits[id & 0xf];
+#ifndef DB_WINCE
if (!security_initialized) {
InitializeSecurityDescriptor(&null_sd,
SECURITY_DESCRIPTOR_REVISION);
@@ -57,6 +57,7 @@ static __inline int get_handle(dbenv, mutexp, eventp)
all_sa.lpSecurityDescriptor = &null_sd;
security_initialized = 1;
}
+#endif
if ((*eventp = CreateEvent(&all_sa, FALSE, FALSE, idbuf)) == NULL) {
ret = __os_get_syserr();
@@ -111,6 +112,9 @@ __db_win32_mutex_lock(dbenv, mutex)
#ifdef MUTEX_DIAG
LARGE_INTEGER now;
#endif
+#ifdef DB_WINCE
+ volatile db_threadid_t tmp_tid;
+#endif
if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
return (0);
@@ -130,6 +134,20 @@ loop: /* Attempt to acquire the resource for N spins. */
* We can avoid the (expensive) interlocked instructions if
* the mutex is already "set".
*/
+#ifdef DB_WINCE
+ /*
+ * Memory mapped regions on Windows CE cause problems with
+ * InterlockedExchange calls. Each page in a mapped region
+ * needs to have been written to prior to an
+ * InterlockedExchange call, or the InterlockedExchange call
+ * hangs. This does not seem to be documented anywhere. For
+ * now, read/write a non-critical piece of memory from the
+ * shared region prior to attempting an InterlockedExchange
+ * operation.
+ */
+ tmp_tid = mutexp->tid;
+ mutexp->tid = tmp_tid;
+#endif
if (mutexp->tas || !MUTEX_SET(&mutexp->tas)) {
/*
* Some systems (notably those with newer Intel CPUs)
diff --git a/db/mutex/mutex.c b/db/mutex/mutex.c
deleted file mode 100644
index 9d925d113..000000000
--- a/db/mutex/mutex.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
- *
- * $Id: mutex.c,v 11.43 2004/10/15 16:59:44 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <string.h>
-#endif
-
-#include "db_int.h"
-
-#if defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)
-#include "dbinc/db_shash.h"
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-#include "dbinc/txn.h"
-#endif
-
-static int __db_mutex_alloc_int __P((DB_ENV *, REGINFO *, DB_MUTEX **));
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
-static REGMAINT * __db_mutex_maint __P((DB_ENV *, REGINFO *));
-#endif
-
-/*
- * __db_mutex_setup --
- * External interface to allocate, and/or initialize, record
- * mutexes.
- *
- * PUBLIC: int __db_mutex_setup __P((DB_ENV *, REGINFO *, void *, u_int32_t));
- */
-int
-__db_mutex_setup(dbenv, infop, ptr, flags)
- DB_ENV *dbenv;
- REGINFO *infop;
- void *ptr;
- u_int32_t flags;
-{
- DB_MUTEX *mutex;
- REGMAINT *maint;
- u_int32_t iflags, offset;
- int ret;
-
- ret = 0;
- /*
- * If they indicated the region is not locked, then lock it.
- * This is only needed when we have unusual mutex resources.
- * (I.e. MUTEX_NO_MALLOC_LOCKS or HAVE_MUTEX_SYSTEM_RESOURCES)
- */
-#if defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)
- if (!LF_ISSET(MUTEX_NO_RLOCK))
- R_LOCK(dbenv, infop);
-#endif
- /*
- * Allocate the mutex if they asked us to.
- */
- mutex = NULL;
- if (LF_ISSET(MUTEX_ALLOC)) {
- if ((ret = __db_mutex_alloc_int(dbenv, infop, ptr)) != 0)
- goto err;
- mutex = *(DB_MUTEX **)ptr;
- } else
- mutex = (DB_MUTEX *)ptr;
-
- /*
- * Set up to initialize the mutex.
- */
- iflags = LF_ISSET(MUTEX_LOGICAL_LOCK | MUTEX_THREAD | MUTEX_SELF_BLOCK);
- switch (infop->type) {
- case REGION_TYPE_LOCK:
- offset = P_TO_UINT32(mutex) + DB_FCNTL_OFF_LOCK;
- break;
- case REGION_TYPE_MPOOL:
- offset = P_TO_UINT32(mutex) + DB_FCNTL_OFF_MPOOL;
- break;
- default:
- offset = P_TO_UINT32(mutex) + DB_FCNTL_OFF_GEN;
- break;
- }
- maint = NULL;
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
- if (!LF_ISSET(MUTEX_NO_RECORD))
- maint = (REGMAINT *)__db_mutex_maint(dbenv, infop);
-#endif
-
- ret = __db_mutex_init(dbenv, mutex, offset, iflags, infop, maint);
-err:
-#if defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)
- if (!LF_ISSET(MUTEX_NO_RLOCK))
- R_UNLOCK(dbenv, infop);
-#endif
- /*
- * If we allocated the mutex but had an error on init'ing,
- * then we must free it before returning.
- * !!!
- * Free must be done after releasing region lock.
- */
- if (ret != 0 && LF_ISSET(MUTEX_ALLOC) && mutex != NULL) {
- __db_mutex_free(dbenv, infop, mutex);
- *(DB_MUTEX **)ptr = NULL;
- }
- return (ret);
-}
-
-/*
- * __db_mutex_alloc_int --
- * Allocate and initialize a mutex.
- */
-static int
-__db_mutex_alloc_int(dbenv, infop, storep)
- DB_ENV *dbenv;
- REGINFO *infop;
- DB_MUTEX **storep;
-{
- int ret;
-
- /*
- * If the architecture supports mutexes in heap memory, use heap memory.
- * If it doesn't, we have to allocate space in a region. If allocation
- * in the region fails, fallback to allocating from the mpool region,
- * because it's big, it almost always exists and if it's entirely dirty,
- * we can free buffers until memory is available.
- */
-#if defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)
- ret = __db_shalloc(infop, sizeof(DB_MUTEX), MUTEX_ALIGN, storep);
-
- if (ret == ENOMEM && MPOOL_ON(dbenv)) {
- DB_MPOOL *dbmp;
-
- dbmp = dbenv->mp_handle;
- if ((ret = __memp_alloc(dbmp,
- dbmp->reginfo, NULL, sizeof(DB_MUTEX), NULL, storep)) == 0)
- (*storep)->flags = MUTEX_MPOOL;
- } else
- (*storep)->flags = 0;
-#else
- COMPQUIET(dbenv, NULL);
- COMPQUIET(infop, NULL);
- ret = __os_calloc(dbenv, 1, sizeof(DB_MUTEX), storep);
-#endif
- if (ret != 0)
- __db_err(dbenv, "Unable to allocate memory for mutex");
- return (ret);
-}
-
-/*
- * __db_mutex_free --
- * Free a mutex.
- *
- * PUBLIC: void __db_mutex_free __P((DB_ENV *, REGINFO *, DB_MUTEX *));
- */
-void
-__db_mutex_free(dbenv, infop, mutexp)
- DB_ENV *dbenv;
- REGINFO *infop;
- DB_MUTEX *mutexp;
-{
-#if defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)
- R_LOCK(dbenv, infop);
-#if defined(HAVE_MUTEX_SYSTEM_RESOURCES)
- if (F_ISSET(mutexp, MUTEX_INITED))
- __db_shlocks_clear(mutexp, infop, NULL);
-#endif
- if (F_ISSET(mutexp, MUTEX_MPOOL)) {
- DB_MPOOL *dbmp;
-
- dbmp = dbenv->mp_handle;
- R_LOCK(dbenv, dbmp->reginfo);
- __db_shalloc_free(&dbmp->reginfo[0], mutexp);
- R_UNLOCK(dbenv, dbmp->reginfo);
- } else
- __db_shalloc_free(infop, mutexp);
- R_UNLOCK(dbenv, infop);
-#else
- COMPQUIET(dbenv, NULL);
- COMPQUIET(infop, NULL);
- __os_free(dbenv, mutexp);
-#endif
-}
-
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
-/*
- * __db_shreg_locks_record --
- * Record an entry in the shared locks area.
- * Region lock must be held in caller.
- */
-static int
-__db_shreg_locks_record(dbenv, mutexp, infop, rp)
- DB_ENV *dbenv;
- DB_MUTEX *mutexp;
- REGINFO *infop;
- REGMAINT *rp;
-{
- u_int i;
-
- if (!F_ISSET(mutexp, MUTEX_INITED))
- return (0);
- DB_ASSERT(mutexp->reg_off == INVALID_ROFF);
- rp->stat.st_records++;
- i = (roff_t *)R_ADDR(infop, rp->regmutex_hint) - &rp->regmutexes[0];
- if (rp->regmutexes[i] != INVALID_ROFF) {
- /*
- * Our hint failed, search for an open slot.
- */
- rp->stat.st_hint_miss++;
- for (i = 0; i < rp->reglocks; i++)
- if (rp->regmutexes[i] == INVALID_ROFF)
- break;
- if (i == rp->reglocks) {
- rp->stat.st_max_locks++;
- __db_err(dbenv,
- "Region mutexes: Exceeded maximum lock slots %lu",
- (u_long)rp->reglocks);
- return (ENOMEM);
- }
- } else
- rp->stat.st_hint_hit++;
- /*
- * When we get here, i is an empty slot. Record this
- * mutex, set hint to point to the next slot and we are done.
- */
- rp->regmutexes[i] = R_OFFSET(infop, mutexp);
- mutexp->reg_off = R_OFFSET(infop, &rp->regmutexes[i]);
- rp->regmutex_hint = (i < rp->reglocks - 1) ?
- R_OFFSET(infop, &rp->regmutexes[i+1]) :
- R_OFFSET(infop, &rp->regmutexes[0]);
- return (0);
-}
-
-/*
- * __db_shreg_locks_clear --
- * Erase an entry in the shared locks area.
- *
- * PUBLIC: void __db_shreg_locks_clear __P((DB_MUTEX *, REGINFO *, REGMAINT *));
- */
-void
-__db_shreg_locks_clear(mutexp, infop, rp)
- DB_MUTEX *mutexp;
- REGINFO *infop;
- REGMAINT *rp;
-{
- /*
- * !!!
- * Assumes the caller's region lock is held.
- */
- if (!F_ISSET(mutexp, MUTEX_INITED))
- return;
- /*
- * This function is generally only called on a forcible remove of an
- * environment. We recorded our index in the mutex, find and clear it.
- */
- DB_ASSERT(mutexp->reg_off != INVALID_ROFF);
- DB_ASSERT(*(roff_t *)R_ADDR(infop, mutexp->reg_off) == \
- R_OFFSET(infop, mutexp));
- *(roff_t *)R_ADDR(infop, mutexp->reg_off) = 0;
- if (rp != NULL) {
- rp->regmutex_hint = mutexp->reg_off;
- rp->stat.st_clears++;
- }
- mutexp->reg_off = INVALID_ROFF;
- __db_mutex_destroy(mutexp);
-}
-
-/*
- * __db_shreg_locks_destroy --
- * Destroy all mutexes in a region's range.
- *
- * PUBLIC: void __db_shreg_locks_destroy __P((REGINFO *, REGMAINT *));
- */
-void
-__db_shreg_locks_destroy(infop, rp)
- REGINFO *infop;
- REGMAINT *rp;
-{
- u_int32_t i;
-
- /*
- * Go through the list of all mutexes and destroy them.
- */
- for (i = 0; i < rp->reglocks; i++)
- if (rp->regmutexes[i] != 0) {
- rp->stat.st_destroys++;
- __db_mutex_destroy(R_ADDR(infop, rp->regmutexes[i]));
- }
-}
-
-/*
- * __db_shreg_mutex_init --
- * Initialize a shared memory mutex.
- *
- * PUBLIC: int __db_shreg_mutex_init __P((DB_ENV *, DB_MUTEX *, u_int32_t,
- * PUBLIC: u_int32_t, REGINFO *, REGMAINT *));
- */
-int
-__db_shreg_mutex_init(dbenv, mutexp, offset, flags, infop, rp)
- DB_ENV *dbenv;
- DB_MUTEX *mutexp;
- u_int32_t offset;
- u_int32_t flags;
- REGINFO *infop;
- REGMAINT *rp;
-{
- int ret;
-
- if ((ret = __db_mutex_init_int(dbenv, mutexp, offset, flags)) != 0)
- return (ret);
- /*
- * Some mutexes cannot be recorded, but we want one interface.
- * So, if we have no REGMAINT, then just return.
- */
- if (rp == NULL)
- return (ret);
- /*
- * !!!
- * Since __db_mutex_init_int is a macro, we may not be
- * using the 'offset' as it is only used for one type
- * of mutex. We COMPQUIET it here, after the call above.
- */
- COMPQUIET(offset, 0);
- ret = __db_shreg_locks_record(dbenv, mutexp, infop, rp);
-
- /*
- * If we couldn't record it and we are returning an error,
- * we need to destroy the mutex we just created.
- */
- if (ret)
- __db_mutex_destroy(mutexp);
-
- return (ret);
-}
-
-/*
- * __db_shreg_maintinit --
- * Initialize a region's maintenance information.
- *
- * PUBLIC: void __db_shreg_maintinit __P((REGINFO *, void *addr, size_t));
- */
-void
-__db_shreg_maintinit(infop, addr, size)
- REGINFO *infop;
- void *addr;
- size_t size;
-{
- REGMAINT *rp;
- u_int32_t i;
-
- rp = (REGMAINT *)addr;
- memset(addr, 0, sizeof(REGMAINT));
- rp->reglocks = size / sizeof(roff_t);
- rp->regmutex_hint = R_OFFSET(infop, &rp->regmutexes[0]);
- for (i = 0; i < rp->reglocks; i++)
- rp->regmutexes[i] = INVALID_ROFF;
-}
-
-static REGMAINT *
-__db_mutex_maint(dbenv, infop)
- DB_ENV *dbenv;
- REGINFO *infop;
-{
- roff_t moff;
-
- switch (infop->type) {
- case REGION_TYPE_LOCK:
- moff = ((DB_LOCKREGION *)
- R_ADDR(infop, infop->rp->primary))->maint_off;
- break;
- case REGION_TYPE_LOG:
- moff = ((LOG *)R_ADDR(infop, infop->rp->primary))->maint_off;
- break;
- case REGION_TYPE_MPOOL:
- moff = ((MPOOL *)R_ADDR(infop, infop->rp->primary))->maint_off;
- break;
- case REGION_TYPE_TXN:
- moff = ((DB_TXNREGION *)
- R_ADDR(infop, infop->rp->primary))->maint_off;
- break;
- default:
- __db_err(dbenv,
- "Attempting to record mutex in a region not set up to do so");
- return (NULL);
- }
- return ((REGMAINT *)R_ADDR(infop, moff));
-}
-#endif /* HAVE_MUTEX_SYSTEM_RESOURCES */
diff --git a/db/mutex/tm.c b/db/mutex/test_mutex.c
index de647fa1f..b0fc8397b 100644
--- a/db/mutex/tm.c
+++ b/db/mutex/test_mutex.c
@@ -1,7 +1,7 @@
/*
* Standalone mutex tester for Berkeley DB mutexes.
*
- * $Id: tm.c,v 12.14 2006/07/17 15:16:46 bostic Exp $
+ * $Id: test_mutex.c,v 12.21 2007/06/21 16:02:29 bostic Exp $
*/
#include "db_config.h"
@@ -10,11 +10,9 @@
#include <sys/wait.h>
-#if defined(MUTEX_THREAD_TEST)
-#include <pthread.h>
-#endif
-
#ifdef DB_WIN32
+#define MUTEX_THREAD_TEST 1
+
extern int getopt(int, char * const *, const char *);
typedef HANDLE os_pid_t;
@@ -32,24 +30,38 @@ typedef HANDLE os_thread_t;
typedef pid_t os_pid_t;
-#ifdef MUTEX_THREAD_TEST
+/*
+ * There's only one mutex implementation that can't support thread-level
+ * locking: UNIX/fcntl mutexes.
+ *
+ * The general Berkeley DB library configuration doesn't look for the POSIX
+ * pthread functions, with one exception -- pthread_yield.
+ *
+ * Use these two facts to decide if we're going to build with or without
+ * threads.
+ */
+#if !defined(HAVE_MUTEX_FCNTL) && defined(HAVE_PTHREAD_YIELD)
+#define MUTEX_THREAD_TEST 1
+
+#include <pthread.h>
+
typedef pthread_t os_thread_t;
-#endif
#define os_thread_create(thrp, attr, func, arg) \
pthread_create((thrp), (attr), (func), (arg))
#define os_thread_join(thr, statusp) pthread_join((thr), (statusp))
#define os_thread_self() pthread_self()
-#endif
+#endif /* HAVE_PTHREAD_YIELD */
+#endif /* !DB_WIN32 */
-#define OS_BAD_PID (os_pid_t)-1
+#define OS_BAD_PID ((os_pid_t)-1)
#define TESTDIR "TESTDIR" /* Working area */
#define MT_FILE "TESTDIR/mutex.file"
#define MT_FILE_QUIT "TESTDIR/mutex.file.quit"
/*
- * The backing file layout:
+ * The backing data layout:
* TM[1] per-thread mutex array lock
* TM[nthreads] per-thread mutex array
* TM[maxlocks] per-lock mutex array
@@ -61,7 +73,7 @@ typedef struct {
} TM;
DB_ENV *dbenv; /* Backing environment */
-size_t len; /* Backing file size. */
+size_t len; /* Backing data chunk size. */
u_int8_t *gm_addr; /* Global mutex */
u_int8_t *lm_addr; /* Locker mutexes */
@@ -72,27 +84,37 @@ os_thread_t *kidsp; /* Locker threads */
os_thread_t wakep; /* Wakeup thread */
#endif
-int maxlocks = 20; /* -l: Backing locks. */
-int nlocks = 10000; /* -n: Locks per processes. */
-int nprocs = 20; /* -p: Processes. */
-int nthreads = 1; /* -t: Threads. */
-int verbose; /* -v: Verbosity. */
+#ifndef HAVE_MMAP
+u_int nprocs = 1; /* -p: Processes. */
+u_int nthreads = 20; /* -t: Threads. */
+#elif MUTEX_THREAD_TEST
+u_int nprocs = 5; /* -p: Processes. */
+u_int nthreads = 4; /* -t: Threads. */
+#else
+u_int nprocs = 20; /* -p: Processes. */
+u_int nthreads = 1; /* -t: Threads. */
+#endif
+
+u_int maxlocks = 20; /* -l: Backing locks. */
+u_int nlocks = 10000; /* -n: Locks per process. */
+int verbose; /* -v: Verbosity. */
+const char *progname;
+
+void data_off(u_int8_t *, DB_FH *);
+void data_on(u_int8_t **, u_int8_t **, u_int8_t **, DB_FH **, int);
int locker_start(u_long);
int locker_wait(void);
-void map_file(u_int8_t **, u_int8_t **, u_int8_t **, DB_FH **);
os_pid_t os_spawn(const char *, char *const[]);
-int os_wait(os_pid_t *, int);
+int os_wait(os_pid_t *, u_int);
void *run_lthread(void *);
void *run_wthread(void *);
os_pid_t spawn_proc(u_long, char *, char *);
void tm_env_close(void);
int tm_env_init(void);
-void tm_file_init(void);
void tm_mutex_destroy(void);
void tm_mutex_init(void);
void tm_mutex_stats(void);
-void unmap_file(u_int8_t *, DB_FH *);
int usage(void);
int wakeup_start(u_long);
int wakeup_wait(void);
@@ -107,31 +129,38 @@ main(argc, argv)
extern char *optarg;
os_pid_t wakeup_pid, *pids;
u_long id;
+ u_int i;
DB_FH *fhp, *map_fhp;
- int ch, err, i;
+ int ch, err;
char *p, *tmpath, cmd[1024];
+ if ((progname = __db_rpath(argv[0])) == NULL)
+ progname = argv[0];
+ else
+ ++progname;
+
rtype = PARENT;
id = 0;
tmpath = argv[0];
while ((ch = getopt(argc, argv, "l:n:p:T:t:v")) != EOF)
switch (ch) {
case 'l':
- maxlocks = atoi(optarg);
+ maxlocks = (u_int)atoi(optarg);
break;
case 'n':
- nlocks = atoi(optarg);
+ nlocks = (u_int)atoi(optarg);
break;
case 'p':
- nprocs = atoi(optarg);
+ nprocs = (u_int)atoi(optarg);
break;
case 't':
- if ((nthreads = atoi(optarg)) == 0)
+ if ((nthreads = (u_int)atoi(optarg)) == 0)
nthreads = 1;
#if !defined(MUTEX_THREAD_TEST)
if (nthreads != 1) {
- (void)fprintf(stderr,
- "tm: thread support not available or not compiled for this platform.\n");
+ fprintf(stderr,
+ "%s: thread support not available or not compiled for this platform.\n",
+ progname);
return (EXIT_FAILURE);
}
#endif
@@ -146,7 +175,7 @@ main(argc, argv)
return (usage());
if ((p = strchr(optarg, '=')) == NULL)
return (usage());
- id = atoi(p + 1);
+ id = (u_long)atoi(p + 1);
break;
case 'v':
verbose = 1;
@@ -164,7 +193,8 @@ main(argc, argv)
*/
if (nprocs == 1 && nthreads == 1) {
fprintf(stderr,
- "tm: running in a single process requires multiple threads\n");
+ "%s: running in a single process requires multiple threads\n",
+ progname);
return (EXIT_FAILURE);
}
@@ -178,12 +208,12 @@ main(argc, argv)
if (rtype == LOCKER || rtype == WAKEUP) {
__os_sleep(dbenv, 3, 0); /* Let everyone catch up. */
/* Initialize random numbers. */
- srand((u_int)time(NULL) % getpid());
+ srand((u_int)time(NULL) % (u_int)getpid());
if (tm_env_init() != 0) /* Join the environment. */
exit(EXIT_FAILURE);
- /* Join the backing file. */
- map_file(&gm_addr, &tm_addr, &lm_addr, &map_fhp);
+ /* Join the backing data. */
+ data_on(&gm_addr, &tm_addr, &lm_addr, &map_fhp, 0);
if (verbose)
printf(
"Backing file: global (%#lx), threads (%#lx), locks (%#lx)\n",
@@ -195,7 +225,7 @@ main(argc, argv)
if ((rtype == LOCKER ? locker_wait() : wakeup_wait()) != 0)
exit(EXIT_FAILURE);
- unmap_file(gm_addr, map_fhp); /* Detach from backing file. */
+ data_off(gm_addr, map_fhp); /* Detach from backing data. */
tm_env_close(); /* Detach from environment. */
@@ -213,20 +243,17 @@ main(argc, argv)
(void)system(cmd);
printf(
- "tm: %d processes, %d threads/process, %d lock requests from %d locks\n",
- nprocs, nthreads, nlocks, maxlocks);
- printf("tm: backing file %lu bytes\n", (u_long)len);
+ "%s: %u processes, %u threads/process, %u lock requests from %u locks\n",
+ progname, nprocs, nthreads, nlocks, maxlocks);
+ printf("%s: backing data %lu bytes\n", progname, (u_long)len);
if (tm_env_init() != 0) /* Create the environment. */
exit(EXIT_FAILURE);
-
- tm_file_init(); /* Initialize backing file. */
-
- /* Map in the backing file. */
- map_file(&gm_addr, &tm_addr, &lm_addr, &map_fhp);
+ /* Create the backing data. */
+ data_on(&gm_addr, &tm_addr, &lm_addr, &map_fhp, 1);
if (verbose)
printf(
- "backing file: global (%#lx), threads (%#lx), locks (%#lx)\n",
+ "backing data: global (%#lx), threads (%#lx), locks (%#lx)\n",
(u_long)gm_addr, (u_long)tm_addr, (u_long)lm_addr);
tm_mutex_init(); /* Initialize mutexes. */
@@ -234,7 +261,7 @@ main(argc, argv)
if (nprocs > 1) { /* Run the multi-process test. */
/* Allocate array of locker process IDs. */
if ((pids = calloc(nprocs, sizeof(os_pid_t))) == NULL) {
- fprintf(stderr, "tm: %s\n", strerror(errno));
+ fprintf(stderr, "%s: %s\n", progname, strerror(errno));
goto fail;
}
@@ -243,7 +270,7 @@ main(argc, argv)
if ((pids[i] =
spawn_proc(id, tmpath, "locker")) == OS_BAD_PID) {
fprintf(stderr,
- "tm: failed to spawn a locker\n");
+ "%s: failed to spawn a locker\n", progname);
goto fail;
}
id += nthreads;
@@ -252,29 +279,32 @@ main(argc, argv)
/* Spawn wakeup process/thread. */
if ((wakeup_pid =
spawn_proc(id, tmpath, "wakeup")) == OS_BAD_PID) {
- fprintf(stderr, "tm: failed to spawn waker\n");
+ fprintf(stderr,
+ "%s: failed to spawn waker\n", progname);
goto fail;
}
++id;
/* Wait for all lockers to exit. */
if ((err = os_wait(pids, nprocs)) != 0) {
- fprintf(stderr, "locker wait failed with %d\n", err);
+ fprintf(stderr, "%s: locker wait failed with %d\n",
+ progname, err);
goto fail;
}
/* Signal wakeup process to exit. */
if ((err = __os_open(
- dbenv, MT_FILE_QUIT, DB_OSO_CREATE, 0664, &fhp)) != 0) {
- fprintf(stderr, "tm: open %s\n", db_strerror(err));
+ dbenv, MT_FILE_QUIT, 0, DB_OSO_CREATE, 0664, &fhp)) != 0) {
+ fprintf(stderr,
+ "%s: open %s\n", progname, db_strerror(err));
goto fail;
}
(void)__os_closehandle(dbenv, fhp);
/* Wait for wakeup process/thread. */
if ((err = os_wait(&wakeup_pid, 1)) != 0) {
- fprintf(stderr,
- "%lu: exited %d\n", (u_long)wakeup_pid, err);
+ fprintf(stderr, "%s: %lu: exited %d\n",
+ progname, (u_long)wakeup_pid, err);
goto fail;
}
} else { /* Run the single-process test. */
@@ -292,8 +322,9 @@ main(argc, argv)
/* Signal wakeup process to exit. */
if ((err = __os_open(
- dbenv, MT_FILE_QUIT, DB_OSO_CREATE, 0664, &fhp)) != 0) {
- fprintf(stderr, "tm: open %s\n", db_strerror(err));
+ dbenv, MT_FILE_QUIT, 0, DB_OSO_CREATE, 0664, &fhp)) != 0) {
+ fprintf(stderr,
+ "%s: open %s\n", progname, db_strerror(err));
goto fail;
}
(void)__os_closehandle(dbenv, fhp);
@@ -306,14 +337,14 @@ main(argc, argv)
tm_mutex_stats(); /* Display run statistics. */
tm_mutex_destroy(); /* Destroy mutexes. */
- unmap_file(gm_addr, map_fhp); /* Detach from backing file. */
+ data_off(gm_addr, map_fhp); /* Detach from backing data. */
tm_env_close(); /* Detach from environment. */
- printf("tm: test succeeded\n");
+ printf("%s: test succeeded\n", progname);
return (EXIT_SUCCESS);
-fail: printf("tm: FAILED!\n");
+fail: printf("%s: FAILED!\n", progname);
return (EXIT_FAILURE);
}
@@ -322,7 +353,8 @@ locker_start(id)
u_long id;
{
#if defined(MUTEX_THREAD_TEST)
- int err, i;
+ u_int i;
+ int err;
/*
* Spawn off threads. We have nthreads all locking and going to
@@ -330,14 +362,14 @@ locker_start(id)
*/
if ((kidsp =
(os_thread_t *)calloc(sizeof(os_thread_t), nthreads)) == NULL) {
- fprintf(stderr, "tm: %s\n", strerror(errno));
+ fprintf(stderr, "%s: %s\n", progname, strerror(errno));
return (1);
}
for (i = 0; i < nthreads; i++)
if ((err = os_thread_create(
&kidsp[i], NULL, run_lthread, (void *)(id + i))) != 0) {
- fprintf(stderr, "tm: failed spawning thread: %s\n",
- db_strerror(err));
+ fprintf(stderr, "%s: failed spawning thread: %s\n",
+ progname, db_strerror(err));
return (1);
}
return (0);
@@ -350,14 +382,15 @@ int
locker_wait()
{
#if defined(MUTEX_THREAD_TEST)
- int i;
+ u_int i;
void *retp;
/* Wait for the threads to exit. */
for (i = 0; i < nthreads; i++) {
- os_thread_join(kidsp[i], &retp);
+ (void)os_thread_join(kidsp[i], &retp);
if (retp != NULL) {
- fprintf(stderr, "tm: thread exited with error\n");
+ fprintf(stderr,
+ "%s: thread exited with error\n", progname);
return (1);
}
}
@@ -372,7 +405,8 @@ run_lthread(arg)
{
TM *gp, *mp, *tp;
u_long id, tid;
- int err, i, lock, nl;
+ u_int lock, nl;
+ int err, i;
id = (uintptr_t)arg;
#if defined(MUTEX_THREAD_TEST)
@@ -388,21 +422,21 @@ run_lthread(arg)
for (nl = nlocks; nl > 0;) {
/* Select and acquire a data lock. */
- lock = rand() % maxlocks;
+ lock = (u_int)rand() % maxlocks;
mp = (TM *)(lm_addr + lock * sizeof(TM));
if (verbose)
printf("%03lu: lock %d (mtx: %lu)\n",
id, lock, (u_long)mp->mutex);
if ((err = dbenv->mutex_lock(dbenv, mp->mutex)) != 0) {
- fprintf(stderr, "%03lu: never got lock %d: %s\n",
- id, lock, db_strerror(err));
+ fprintf(stderr, "%s: %03lu: never got lock %d: %s\n",
+ progname, id, lock, db_strerror(err));
return ((void *)1);
}
if (mp->id != 0) {
fprintf(stderr,
- "RACE! (%03lu granted lock %d held by %03lu)\n",
- id, lock, mp->id);
+ "%s: RACE! (%03lu granted lock %d held by %03lu)\n",
+ progname, id, lock, mp->id);
return ((void *)1);
}
mp->id = id;
@@ -412,11 +446,11 @@ run_lthread(arg)
* we still hold the mutex.
*/
for (i = 0; i < 3; ++i) {
- __os_sleep(dbenv, 0, rand() % 3);
+ __os_sleep(dbenv, 0, (u_long)rand() % 3);
if (mp->id != id) {
fprintf(stderr,
- "RACE! (%03lu stole lock %d from %03lu)\n",
- mp->id, lock, id);
+ "%s: RACE! (%03lu stole lock %d from %03lu)\n",
+ progname, mp->id, lock, id);
return ((void *)1);
}
}
@@ -432,14 +466,14 @@ run_lthread(arg)
* The wakeup thread will wake us up.
*/
if ((err = dbenv->mutex_lock(dbenv, gp->mutex)) != 0) {
- fprintf(stderr,
- "%03lu: global lock: %s\n", id, db_strerror(err));
+ fprintf(stderr, "%s: %03lu: global lock: %s\n",
+ progname, id, db_strerror(err));
return ((void *)1);
}
if (tp->id != 0 && tp->id != id) {
fprintf(stderr,
- "%03lu: per-thread mutex isn't mine, owned by %03lu\n",
- id, tp->id);
+ "%s: %03lu: per-thread mutex isn't mine, owned by %03lu\n",
+ progname, id, tp->id);
return ((void *)1);
}
tp->id = id;
@@ -448,23 +482,26 @@ run_lthread(arg)
id, (u_long)tp->mutex);
if (tp->wakeme) {
fprintf(stderr,
- "%03lu: wakeup flag incorrectly set\n", id);
+ "%s: %03lu: wakeup flag incorrectly set\n",
+ progname, id);
return ((void *)1);
}
tp->wakeme = 1;
if ((err = dbenv->mutex_unlock(dbenv, gp->mutex)) != 0) {
fprintf(stderr,
- "%03lu: global unlock: %s\n", id, db_strerror(err));
+ "%s: %03lu: global unlock: %s\n",
+ progname, id, db_strerror(err));
return ((void *)1);
}
if ((err = dbenv->mutex_lock(dbenv, tp->mutex)) != 0) {
- fprintf(stderr, "%03lu: per-thread lock: %s\n",
- id, db_strerror(err));
+ fprintf(stderr, "%s: %03lu: per-thread lock: %s\n",
+ progname, id, db_strerror(err));
return ((void *)1);
}
/* Time passes... */
if (tp->wakeme) {
- fprintf(stderr, "%03lu: wakeup flag not cleared\n", id);
+ fprintf(stderr, "%s: %03lu: wakeup flag not cleared\n",
+ progname, id);
return ((void *)1);
}
@@ -476,18 +513,13 @@ run_lthread(arg)
mp->id = 0;
if ((err = dbenv->mutex_unlock(dbenv, mp->mutex)) != 0) {
fprintf(stderr,
- "%03lu: lock release: %s\n", id, db_strerror(err));
+ "%s: %03lu: lock release: %s\n",
+ progname, id, db_strerror(err));
return ((void *)1);
}
- if (--nl % 100 == 0) {
- fprintf(stderr, "%03lu: %d\n", id, nl);
- /*
- * Windows buffers stderr and the output looks wrong
- * without this.
- */
- fflush(stderr);
- }
+ if (--nl % 100 == 0)
+ printf("%03lu: %d\n", id, nl);
}
return (NULL);
@@ -505,8 +537,8 @@ wakeup_start(id)
*/
if ((err = os_thread_create(
&wakep, NULL, run_wthread, (void *)id)) != 0) {
- fprintf(stderr, "tm: failed spawning wakeup thread: %s\n",
- db_strerror(err));
+ fprintf(stderr, "%s: failed spawning wakeup thread: %s\n",
+ progname, db_strerror(err));
return (1);
}
return (0);
@@ -524,9 +556,10 @@ wakeup_wait()
/*
* A file is created when the wakeup thread is no longer needed.
*/
- os_thread_join(wakep, &retp);
+ (void)os_thread_join(wakep, &retp);
if (retp != NULL) {
- fprintf(stderr, "tm: wakeup thread exited with error\n");
+ fprintf(stderr,
+ "%s: wakeup thread exited with error\n", progname);
return (1);
}
#endif
@@ -543,7 +576,8 @@ run_wthread(arg)
{
TM *gp, *tp;
u_long id, tid;
- int check_id, err;
+ u_int check_id;
+ int err;
id = (uintptr_t)arg;
#if defined(MUTEX_THREAD_TEST)
@@ -574,30 +608,30 @@ run_wthread(arg)
if (verbose) {
printf("%03lu: wakeup thread %03lu (mtx: %lu)\n",
id, tp->id, (u_long)tp->mutex);
- fflush(stdout);
+ (void)fflush(stdout);
}
/* Acquire the global lock. */
if ((err = dbenv->mutex_lock(dbenv, gp->mutex)) != 0) {
- fprintf(stderr,
- "wakeup: global lock: %s\n", db_strerror(err));
+ fprintf(stderr, "%s: wakeup: global lock: %s\n",
+ progname, db_strerror(err));
return ((void *)1);
}
tp->wakeme = 0;
if ((err = dbenv->mutex_unlock(dbenv, tp->mutex)) != 0) {
- fprintf(stderr,
- "wakeup: unlock: %s\n", db_strerror(err));
+ fprintf(stderr, "%s: wakeup: unlock: %s\n",
+ progname, db_strerror(err));
return ((void *)1);
}
- if ((err = dbenv->mutex_unlock(dbenv, gp->mutex))) {
- fprintf(stderr,
- "wakeup: global unlock: %s\n", db_strerror(err));
+ if ((err = dbenv->mutex_unlock(dbenv, gp->mutex)) != 0) {
+ fprintf(stderr, "%s: wakeup: global unlock: %s\n",
+ progname, db_strerror(err));
return ((void *)1);
}
- __os_sleep(dbenv, 0, rand() % 3);
+ __os_sleep(dbenv, 0, (u_long)rand() % 3);
}
return (NULL);
}
@@ -618,11 +652,11 @@ tm_env_init()
* reporting.
*/
if ((ret = db_env_create(&dbenv, 0)) != 0) {
- fprintf(stderr, "tm: %s\n", db_strerror(ret));
+ fprintf(stderr, "%s: %s\n", progname, db_strerror(ret));
return (1);
}
dbenv->set_errfile(dbenv, stderr);
- dbenv->set_errpfx(dbenv, "tm");
+ dbenv->set_errpfx(dbenv, progname);
/* Allocate enough mutexes. */
if ((ret = dbenv->mutex_set_increment(dbenv,
@@ -658,40 +692,6 @@ tm_env_close()
}
/*
- * tm_file_init --
- * Initialize the backing file.
- */
-void
-tm_file_init()
-{
- DB_FH *fhp;
- int err;
- size_t nwrite;
-
- /* Initialize the backing file. */
- if (verbose)
- printf("Create the backing file.\n");
-
- (void)unlink(MT_FILE);
-
- if ((err = __os_open(dbenv, MT_FILE,
- DB_OSO_CREATE | DB_OSO_TRUNC, 0666, &fhp)) == -1) {
- (void)fprintf(stderr,
- "%s: open: %s\n", MT_FILE, db_strerror(err));
- exit(EXIT_FAILURE);
- }
-
- if ((err = __os_seek(dbenv, fhp, 0, 0, len)) != 0 ||
- (err = __os_write(dbenv, fhp, &err, 1, &nwrite)) != 0 ||
- nwrite != 1) {
- (void)fprintf(stderr,
- "%s: seek/write: %s\n", MT_FILE, db_strerror(err));
- exit(EXIT_FAILURE);
- }
- (void)__os_closehandle(dbenv, fhp);
-}
-
-/*
* tm_mutex_init --
* Initialize the mutexes.
*/
@@ -699,14 +699,15 @@ void
tm_mutex_init()
{
TM *mp;
- int err, i;
+ u_int i;
+ int err;
if (verbose)
printf("Allocate the global mutex: ");
mp = (TM *)gm_addr;
if ((err = dbenv->mutex_alloc(dbenv, 0, &mp->mutex)) != 0) {
- fprintf(stderr,
- "DB_ENV->mutex_alloc (global): %s\n", db_strerror(err));
+ fprintf(stderr, "%s: DB_ENV->mutex_alloc (global): %s\n",
+ progname, db_strerror(err));
exit(EXIT_FAILURE);
}
if (verbose)
@@ -721,14 +722,14 @@ tm_mutex_init()
if ((err = dbenv->mutex_alloc(
dbenv, DB_MUTEX_SELF_BLOCK, &mp->mutex)) != 0) {
fprintf(stderr,
- "DB_ENV->mutex_alloc (per-thread %d): %s\n",
- i, db_strerror(err));
+ "%s: DB_ENV->mutex_alloc (per-thread %d): %s\n",
+ progname, i, db_strerror(err));
exit(EXIT_FAILURE);
}
if ((err = dbenv->mutex_lock(dbenv, mp->mutex)) != 0) {
fprintf(stderr,
- "DB_ENV->mutex_lock (per-thread %d): %s\n",
- i, db_strerror(err));
+ "%s: DB_ENV->mutex_lock (per-thread %d): %s\n",
+ progname, i, db_strerror(err));
exit(EXIT_FAILURE);
}
if (verbose)
@@ -743,8 +744,8 @@ tm_mutex_init()
mp = (TM *)(lm_addr + i * sizeof(TM));
if ((err = dbenv->mutex_alloc(dbenv, 0, &mp->mutex)) != 0) {
fprintf(stderr,
- "DB_ENV->mutex_alloc (per-lock: %d): %s\n",
- i, db_strerror(err));
+ "%s: DB_ENV->mutex_alloc (per-lock: %d): %s\n",
+ progname, i, db_strerror(err));
exit(EXIT_FAILURE);
}
if (verbose)
@@ -762,14 +763,15 @@ void
tm_mutex_destroy()
{
TM *gp, *mp;
- int err, i;
+ u_int i;
+ int err;
if (verbose)
printf("Destroy the global mutex.\n");
gp = (TM *)gm_addr;
if ((err = dbenv->mutex_free(dbenv, gp->mutex)) != 0) {
- fprintf(stderr,
- "DB_ENV->mutex_free (global): %s\n", db_strerror(err));
+ fprintf(stderr, "%s: DB_ENV->mutex_free (global): %s\n",
+ progname, db_strerror(err));
exit(EXIT_FAILURE);
}
@@ -779,8 +781,8 @@ tm_mutex_destroy()
mp = (TM *)(tm_addr + i * sizeof(TM));
if ((err = dbenv->mutex_free(dbenv, mp->mutex)) != 0) {
fprintf(stderr,
- "DB_ENV->mutex_free (per-thread %d): %s\n",
- i, db_strerror(err));
+ "%s: DB_ENV->mutex_free (per-thread %d): %s\n",
+ progname, i, db_strerror(err));
exit(EXIT_FAILURE);
}
}
@@ -791,13 +793,11 @@ tm_mutex_destroy()
mp = (TM *)(lm_addr + i * sizeof(TM));
if ((err = dbenv->mutex_free(dbenv, mp->mutex)) != 0) {
fprintf(stderr,
- "DB_ENV->mutex_free (per-lock: %d): %s\n",
- i, db_strerror(err));
+ "%s: DB_ENV->mutex_free (per-lock: %d): %s\n",
+ progname, i, db_strerror(err));
exit(EXIT_FAILURE);
}
}
-
- (void)unlink(MT_FILE);
}
/*
@@ -809,8 +809,8 @@ tm_mutex_stats()
{
#ifdef HAVE_STATISTICS
TM *mp;
- int i;
u_int32_t set_wait, set_nowait;
+ u_int i;
printf("Per-lock mutex statistics.\n");
for (i = 0; i < maxlocks; ++i) {
@@ -823,32 +823,64 @@ tm_mutex_stats()
}
/*
- * map_file --
- * Map in the backing file.
+ * data_on --
+ * Map in or allocate the backing data space.
*/
void
-map_file(gm_addrp, tm_addrp, lm_addrp, fhpp)
+data_on(gm_addrp, tm_addrp, lm_addrp, fhpp, init)
u_int8_t **gm_addrp, **tm_addrp, **lm_addrp;
DB_FH **fhpp;
+ int init;
{
- void *addr;
DB_FH *fhp;
+ size_t nwrite;
int err;
+ void *addr;
-#ifndef MAP_FAILED
-#define MAP_FAILED (void *)-1
-#endif
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif
- if ((err = __os_open(dbenv, MT_FILE, 0, 0, &fhp)) != 0) {
- fprintf(stderr, "%s: open %s\n", MT_FILE, db_strerror(err));
- exit(EXIT_FAILURE);
- }
+ fhp = NULL;
- if ((err = __os_mapfile(dbenv, MT_FILE, fhp, len, 0, &addr)) != 0) {
- fprintf(stderr, "%s: mmap: %s\n", MT_FILE, db_strerror(err));
- exit(EXIT_FAILURE);
+ /*
+ * In a single process, use heap memory.
+ */
+ if (nprocs == 1) {
+ if (init) {
+ if ((err =
+ __os_calloc(dbenv, (size_t)len, 1, &addr)) != 0)
+ exit(EXIT_FAILURE);
+ } else {
+ fprintf(stderr,
+ "%s: init should be set for single process call\n",
+ progname);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ if (init) {
+ if (verbose)
+ printf("Create the backing file.\n");
+
+ if ((err = __os_open(dbenv, MT_FILE, 0,
+ DB_OSO_CREATE | DB_OSO_TRUNC, 0666, &fhp)) == -1) {
+ fprintf(stderr, "%s: %s: open: %s\n",
+ progname, MT_FILE, db_strerror(err));
+ exit(EXIT_FAILURE);
+ }
+
+ if ((err = __os_seek(dbenv, fhp, 0, 0, len)) != 0 ||
+ (err =
+ __os_write(dbenv, fhp, &err, 1, &nwrite)) != 0 ||
+ nwrite != 1) {
+ fprintf(stderr, "%s: %s: seek/write: %s\n",
+ progname, MT_FILE, db_strerror(err));
+ exit(EXIT_FAILURE);
+ }
+ } else
+ if ((err =
+ __os_open(dbenv, MT_FILE, 0, 0, 0, &fhp)) != 0)
+ exit(EXIT_FAILURE);
+
+ if ((err =
+ __os_mapfile(dbenv, MT_FILE, fhp, len, 0, &addr)) != 0)
+ exit(EXIT_FAILURE);
}
*gm_addrp = (u_int8_t *)addr;
@@ -862,23 +894,21 @@ map_file(gm_addrp, tm_addrp, lm_addrp, fhpp)
}
/*
- * unmap_file --
- * Discard backing file map.
+ * data_off --
+ * Discard or de-allocate the backing data space.
*/
void
-unmap_file(addr, fhp)
+data_off(addr, fhp)
u_int8_t *addr;
DB_FH *fhp;
{
- int err;
-
- if ((err = __os_unmapfile(dbenv, addr, len)) != 0) {
- fprintf(stderr, "munmap: %s\n", db_strerror(err));
- exit(EXIT_FAILURE);
- }
- if ((err = __os_closehandle(dbenv, fhp)) != 0) {
- fprintf(stderr, "close: %s\n", db_strerror(err));
- exit(EXIT_FAILURE);
+ if (nprocs == 1)
+ __os_free(dbenv, addr);
+ else {
+ if (__os_unmapfile(dbenv, addr, len) != 0)
+ exit(EXIT_FAILURE);
+ if (__os_closehandle(dbenv, fhp) != 0)
+ exit(EXIT_FAILURE);
}
}
@@ -889,8 +919,8 @@ unmap_file(addr, fhp)
int
usage()
{
- (void)fprintf(stderr, "%s\n\t%s\n",
- "usage: tm [-v] [-l maxlocks]",
+ fprintf(stderr, "usage: %s %s\n\t%s\n", progname,
+ "[-v] [-l maxlocks]",
"[-n locks] [-p procs] [-T locker=ID|wakeup=ID] [-t threads]");
return (EXIT_FAILURE);
}
@@ -900,11 +930,12 @@ usage()
* Wait for an array of N procs.
*/
int
-os_wait(procs, nprocs)
+os_wait(procs, n)
os_pid_t *procs;
- int nprocs;
+ u_int n;
{
- int i, status;
+ u_int i;
+ int status;
#if defined(DB_WIN32)
DWORD ret;
#endif
@@ -913,29 +944,29 @@ os_wait(procs, nprocs)
#if defined(DB_WIN32)
do {
- ret = WaitForMultipleObjects(nprocs, procs, FALSE, INFINITE);
+ ret = WaitForMultipleObjects(n, procs, FALSE, INFINITE);
i = ret - WAIT_OBJECT_0;
- if (i < 0 || i >= nprocs)
+ if (i < 0 || i >= n)
return (__os_posix_err(__os_get_syserr()));
if ((GetExitCodeProcess(procs[i], &ret) == 0) || (ret != 0))
return (ret);
/* remove the process handle from the list */
- while (++i < nprocs)
+ while (++i < n)
procs[i - 1] = procs[i];
- } while (--nprocs);
+ } while (--n);
#elif !defined(HAVE_VXWORKS)
do {
- if ((i = wait(&status)) == -1)
+ if (wait(&status) == -1)
return (__os_posix_err(__os_get_syserr()));
if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) {
- for (i = 0; i < nprocs; i++)
- kill(procs[i], SIGKILL);
+ for (i = 0; i < n; i++)
+ (void)kill(procs[i], SIGKILL);
return (WEXITSTATUS(status));
}
- } while (--nprocs);
+ } while (--n);
#endif
return (0);
@@ -983,7 +1014,7 @@ os_spawn(path, argv)
COMPQUIET(status, 0);
#ifdef HAVE_VXWORKS
- fprintf(stderr, "ERROR: os_spawn not supported for VxWorks.\n");
+ fprintf(stderr, "%s: os_spawn not supported for VxWorks.\n", progname);
return (OS_BAD_PID);
#elif defined(HAVE_QNX)
/*
@@ -1003,7 +1034,7 @@ os_spawn(path, argv)
return (OS_BAD_PID);
return (pid);
} else {
- execv(path, argv);
+ (void)execv(path, argv);
exit(EXIT_FAILURE);
}
#endif
diff --git a/db/mutex/uts4_cc.s b/db/mutex/uts4_cc.s
index a8f2498ab..526ac3196 100644
--- a/db/mutex/uts4_cc.s
+++ b/db/mutex/uts4_cc.s
@@ -1,9 +1,8 @@
/ See the file LICENSE for redistribution information.
/
- / Copyright (c) 1997-2006
- / Oracle Corporation. All rights reserved.
+ / Copyright (c) 1997,2007 Oracle. All rights reserved.
/
- / $Id: uts4_cc.s,v 12.3 2006/08/24 14:46:16 bostic Exp $
+ / $Id: uts4_cc.s,v 12.5 2007/05/17 15:15:45 bostic Exp $
/
/ int uts_lock ( int *p, int i );
/ Update the lock word pointed to by p with the