summaryrefslogtreecommitdiff
path: root/db/lock/lock_region.c
diff options
context:
space:
mode:
Diffstat (limited to 'db/lock/lock_region.c')
-rw-r--r--db/lock/lock_region.c172
1 files changed, 56 insertions, 116 deletions
diff --git a/db/lock/lock_region.c b/db/lock/lock_region.c
index b03dc74f1..c3a1b401d 100644
--- a/db/lock/lock_region.c
+++ b/db/lock/lock_region.c
@@ -1,32 +1,21 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1996-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: lock_region.c,v 11.82 2004/10/15 16:59:42 bostic Exp $
+ * $Id: lock_region.c,v 12.11 2006/08/24 14:46:11 bostic Exp $
*/
#include "db_config.h"
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <string.h>
-#endif
-
#include "db_int.h"
-#include "dbinc/db_shash.h"
#include "dbinc/lock.h"
static int __lock_region_init __P((DB_ENV *, DB_LOCKTAB *));
static size_t
__lock_region_size __P((DB_ENV *));
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
-static size_t __lock_region_maint __P((DB_ENV *));
-#endif
-
/*
* The conflict arrays are set up such that the row is the lock you are
* holding and the column is the lock that is desired.
@@ -73,7 +62,9 @@ __lock_open(dbenv)
DB_LOCKREGION *region;
DB_LOCKTAB *lt;
size_t size;
- int ret;
+ int region_locked, ret;
+
+ region_locked = 0;
/* Create the lock table structure. */
if ((ret = __os_calloc(dbenv, 1, sizeof(DB_LOCKTAB), &lt)) != 0)
@@ -100,6 +91,16 @@ __lock_open(dbenv)
region = lt->reginfo.primary =
R_ADDR(&lt->reginfo, lt->reginfo.rp->primary);
+ /* Set remaining pointers into region. */
+ lt->conflicts = R_ADDR(&lt->reginfo, region->conf_off);
+ lt->obj_tab = R_ADDR(&lt->reginfo, region->obj_off);
+ lt->locker_tab = R_ADDR(&lt->reginfo, region->locker_off);
+
+ dbenv->lk_handle = lt;
+
+ LOCK_SYSTEM_LOCK(dbenv);
+ region_locked = 1;
+
if (dbenv->lk_detect != DB_LOCK_NORUN) {
/*
* Check for incompatible automatic deadlock detection requests.
@@ -113,7 +114,7 @@ __lock_open(dbenv)
if (region->detect != DB_LOCK_NORUN &&
dbenv->lk_detect != DB_LOCK_DEFAULT &&
region->detect != dbenv->lk_detect) {
- __db_err(dbenv,
+ __db_errx(dbenv,
"lock_open: incompatible deadlock detector mode");
ret = EINVAL;
goto err;
@@ -131,22 +132,18 @@ __lock_open(dbenv)
if (dbenv->tx_timeout != 0)
region->tx_timeout = dbenv->tx_timeout;
- /* Set remaining pointers into region. */
- lt->conflicts = R_ADDR(&lt->reginfo, region->conf_off);
- lt->obj_tab = R_ADDR(&lt->reginfo, region->obj_off);
- lt->locker_tab = R_ADDR(&lt->reginfo, region->locker_off);
+ LOCK_SYSTEM_UNLOCK(dbenv);
+ region_locked = 0;
- R_UNLOCK(dbenv, &lt->reginfo);
-
- dbenv->lk_handle = lt;
return (0);
-err: if (lt->reginfo.addr != NULL) {
- if (F_ISSET(&lt->reginfo, REGION_CREATE))
- ret = __db_panic(dbenv, ret);
- R_UNLOCK(dbenv, &lt->reginfo);
+err: dbenv->lk_handle = NULL;
+ if (lt->reginfo.addr != NULL) {
+ if (region_locked)
+ LOCK_SYSTEM_UNLOCK(dbenv);
(void)__db_r_detach(dbenv, &lt->reginfo, 0);
}
+
__os_free(dbenv, lt);
return (ret);
}
@@ -165,9 +162,6 @@ __lock_region_init(dbenv, lt)
DB_LOCKER *lidp;
DB_LOCKOBJ *op;
DB_LOCKREGION *region;
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
- size_t maint_size;
-#endif
u_int32_t i;
u_int8_t *addr;
int lk_modes, ret;
@@ -179,6 +173,10 @@ __lock_region_init(dbenv, lt)
region = lt->reginfo.primary;
memset(region, 0, sizeof(*region));
+ if ((ret = __mutex_alloc(
+ dbenv, MTX_LOCK_REGION, 0, &region->mtx_region)) != 0)
+ return (ret);
+
/* Select a conflict matrix if none specified. */
if (dbenv->lk_modes == 0)
if (CDB_LOCKING(dbenv)) {
@@ -229,33 +227,15 @@ __lock_region_init(dbenv, lt)
__db_hashinit(addr, region->locker_t_size);
region->locker_off = R_OFFSET(&lt->reginfo, addr);
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
- maint_size = __lock_region_maint(dbenv);
- /* Allocate room for the locker maintenance info and initialize it. */
- if ((ret = __db_shalloc(&lt->reginfo,
- sizeof(REGMAINT) + maint_size, 0, &addr)) != 0)
- goto mem_err;
- __db_maintinit(&lt->reginfo, addr, maint_size);
- region->maint_off = R_OFFSET(&lt->reginfo, addr);
-#endif
-
- /*
- * Initialize locks onto a free list. Initialize and lock the mutex
- * so that when we need to block, all we need do is try to acquire
- * the mutex.
- */
+ /* Initialize locks onto a free list. */
SH_TAILQ_INIT(&region->free_locks);
for (i = 0; i < region->stat.st_maxlocks; ++i) {
if ((ret = __db_shalloc(&lt->reginfo,
- sizeof(struct __db_lock), MUTEX_ALIGN, &lp)) != 0)
+ sizeof(struct __db_lock), 0, &lp)) != 0)
goto mem_err;
- lp->status = DB_LSTAT_FREE;
+ lp->mtx_lock = MUTEX_INVALID;
lp->gen = 0;
- if ((ret = __db_mutex_setup(dbenv, &lt->reginfo, &lp->mutex,
- MUTEX_LOGICAL_LOCK | MUTEX_NO_RLOCK | MUTEX_SELF_BLOCK))
- != 0)
- return (ret);
- MUTEX_LOCK(dbenv, &lp->mutex);
+ lp->status = DB_LSTAT_FREE;
SH_TAILQ_INSERT_HEAD(&region->free_locks, lp, links, __db_lock);
}
@@ -276,7 +256,7 @@ __lock_region_init(dbenv, lt)
for (i = 0; i < region->stat.st_maxlockers; ++i) {
if ((ret = __db_shalloc(&lt->reginfo,
sizeof(DB_LOCKER), 0, &lidp)) != 0) {
-mem_err: __db_err(dbenv,
+mem_err: __db_errx(dbenv,
"Unable to allocate memory for the lock table");
return (ret);
}
@@ -316,14 +296,13 @@ __lock_dbenv_refresh(dbenv)
*/
if (F_ISSET(dbenv, DB_ENV_PRIVATE)) {
/* Discard the conflict matrix. */
- __db_shalloc_free(reginfo, R_ADDR(&lt->reginfo, lr->conf_off));
+ __db_shalloc_free(reginfo, R_ADDR(reginfo, lr->conf_off));
/* Discard the object hash table. */
- __db_shalloc_free(reginfo, R_ADDR(&lt->reginfo, lr->obj_off));
+ __db_shalloc_free(reginfo, R_ADDR(reginfo, lr->obj_off));
/* Discard the locker hash table. */
- __db_shalloc_free(
- reginfo, R_ADDR(&lt->reginfo, lr->locker_off));
+ __db_shalloc_free(reginfo, R_ADDR(reginfo, lr->locker_off));
/* Discard locks. */
while ((lp =
@@ -360,6 +339,19 @@ __lock_dbenv_refresh(dbenv)
}
/*
+ * __lock_region_mutex_count --
+ * Return the number of mutexes the lock region will need.
+ *
+ * PUBLIC: u_int32_t __lock_region_mutex_count __P((DB_ENV *));
+ */
+u_int32_t
+__lock_region_mutex_count(dbenv)
+ DB_ENV *dbenv;
+{
+ return (dbenv->lk_max);
+}
+
+/*
* __lock_region_size --
* Return the region size.
*/
@@ -377,20 +369,16 @@ __lock_region_size(dbenv)
retval += __db_shalloc_size(sizeof(DB_LOCKREGION), 0);
retval += __db_shalloc_size(
(size_t)(dbenv->lk_modes * dbenv->lk_modes), 0);
- retval += __db_shalloc_size(__db_tablesize
- (dbenv->lk_max_lockers) * (sizeof(DB_HASHTAB)), 0);
- retval += __db_shalloc_size(__db_tablesize
- (dbenv->lk_max_objects) * (sizeof(DB_HASHTAB)), 0);
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
+ retval += __db_shalloc_size(
+ __db_tablesize(dbenv->lk_max_objects) * (sizeof(DB_HASHTAB)), 0);
+ retval += __db_shalloc_size(
+ __db_tablesize(dbenv->lk_max_lockers) * (sizeof(DB_HASHTAB)), 0);
retval +=
- __db_shalloc_size(sizeof(REGMAINT) + __lock_region_maint(dbenv), 0);
-#endif
- retval += __db_shalloc_size
- (sizeof(struct __db_lock), MUTEX_ALIGN) * dbenv->lk_max;
+ __db_shalloc_size(sizeof(struct __db_lock), 0) * dbenv->lk_max;
retval +=
- __db_shalloc_size(sizeof(DB_LOCKOBJ), 1) * dbenv->lk_max_objects;
+ __db_shalloc_size(sizeof(DB_LOCKOBJ), 0) * dbenv->lk_max_objects;
retval +=
- __db_shalloc_size(sizeof(DB_LOCKER), 1) * dbenv->lk_max_lockers;
+ __db_shalloc_size(sizeof(DB_LOCKER), 0) * dbenv->lk_max_lockers;
/*
* Include 16 bytes of string space per lock. DB doesn't use it
@@ -403,51 +391,3 @@ __lock_region_size(dbenv)
return (retval);
}
-
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
-/*
- * __lock_region_maint --
- * Return the amount of space needed for region maintenance info.
- */
-static size_t
-__lock_region_maint(dbenv)
- DB_ENV *dbenv;
-{
- size_t s;
-
- s = sizeof(DB_MUTEX *) * dbenv->lk_max;
- return (s);
-}
-#endif
-
-/*
- * __lock_region_destroy
- * Destroy any region maintenance info.
- *
- * PUBLIC: void __lock_region_destroy __P((DB_ENV *, REGINFO *));
- */
-void
-__lock_region_destroy(dbenv, infop)
- DB_ENV *dbenv;
- REGINFO *infop;
-{
- /*
- * This routine is called in two cases: when discarding the mutexes
- * from a previous Berkeley DB run, during recovery, and two, when
- * discarding the mutexes as we shut down the database environment.
- * In the latter case, we also need to discard shared memory segments,
- * this is the last time we use them, and the last region-specific
- * call we make.
- */
-#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
- DB_LOCKREGION *lt;
-
- lt = R_ADDR(infop, infop->rp->primary);
-
- __db_shlocks_destroy(infop, R_ADDR(infop, lt->maint_off));
- if (infop->primary != NULL && F_ISSET(dbenv, DB_ENV_PRIVATE))
- __db_shalloc_free(infop, R_ADDR(infop, lt->maint_off));
-#endif
- if (infop->primary != NULL && F_ISSET(dbenv, DB_ENV_PRIVATE))
- __db_shalloc_free(infop, infop->primary);
-}