00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: lock__region_8c-source.html,v 1.1 2008/06/08 10:20:00 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <ctype.h>
00018 #include <errno.h>
00019 #include <string.h>
00020 #endif
00021
00022 #ifdef HAVE_RPC
00023 #include "db_server.h"
00024 #endif
00025
00026 #include "db_int.h"
00027 #include "db_shash.h"
00028 #include "lock.h"
00029
00030 #ifdef HAVE_RPC
00031 #include "gen_client_ext.h"
00032 #include "rpc_client_ext.h"
00033 #endif
00034 #undef __lock_init
00035
00036 static void __lock_dump_locker (DB_LOCKTAB *, DB_LOCKER *, FILE *);
00037 static void __lock_dump_object (DB_LOCKTAB *, DB_LOCKOBJ *, FILE *);
00038 static const char *
00039 __lock_dump_status __P((db_status_t));
00040
00041 static int __lock_init __P((DB_ENV *, DB_LOCKTAB *));
00042 static size_t
00043 __lock_region_size __P((DB_ENV *));
00044 static int __lock_set_lk_conflicts __P((DB_ENV *, u_int8_t *, int));
00045 static int __lock_set_lk_detect __P((DB_ENV *, u_int32_t));
00046 static int __lock_set_lk_max __P((DB_ENV *, u_int32_t));
00047
00048
00049
00050
00051
00052
00053 static u_int8_t const db_cdb_conflicts[] = {
00054
00055 0, 0, 0, 0,
00056 0, 0, 1, 0,
00057 0, 1, 1, 1,
00058 0, 0, 1, 1
00059 };
00060
00061
00062
00063
00064
00065
00066
00067 void
00068 CDB___lock_dbenv_create(dbenv)
00069 DB_ENV *dbenv;
00070 {
00071 dbenv->lk_max = DB_LOCK_DEFAULT_N;
00072
00073 dbenv->set_lk_conflicts = __lock_set_lk_conflicts;
00074 dbenv->set_lk_detect = __lock_set_lk_detect;
00075 dbenv->set_lk_max = __lock_set_lk_max;
00076
00077 #ifdef HAVE_RPC
00078
00079
00080
00081
00082 if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) {
00083 dbenv->set_lk_conflicts = __dbcl_set_lk_conflict;
00084 dbenv->set_lk_detect = __dbcl_set_lk_detect;
00085 dbenv->set_lk_max = __dbcl_set_lk_max;
00086 }
00087 #endif
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 void
00097 CDB___lock_dbenv_close(dbenv)
00098 DB_ENV *dbenv;
00099 {
00100 if (!F_ISSET(dbenv, DB_ENV_USER_ALLOC) && dbenv->lk_conflicts != NULL) {
00101 CDB___os_free(dbenv->lk_conflicts,
00102 dbenv->lk_modes * dbenv->lk_modes);
00103 dbenv->lk_conflicts = NULL;
00104 }
00105 }
00106
00107
00108
00109
00110
00111 static int
00112 __lock_set_lk_conflicts(dbenv, lk_conflicts, lk_modes)
00113 DB_ENV *dbenv;
00114 u_int8_t *lk_conflicts;
00115 int lk_modes;
00116 {
00117 int ret;
00118
00119 ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_lk_conflicts");
00120
00121 if (dbenv->lk_conflicts != NULL) {
00122 CDB___os_free(dbenv->lk_conflicts,
00123 dbenv->lk_modes * dbenv->lk_modes);
00124 dbenv->lk_conflicts = NULL;
00125 }
00126 if ((ret = CDB___os_malloc(dbenv,
00127 lk_modes * lk_modes, NULL, &dbenv->lk_conflicts)) != 0)
00128 return (ret);
00129 memcpy(dbenv->lk_conflicts, lk_conflicts, lk_modes * lk_modes);
00130 dbenv->lk_modes = lk_modes;
00131
00132 return (0);
00133 }
00134
00135
00136
00137
00138
00139 static int
00140 __lock_set_lk_detect(dbenv, lk_detect)
00141 DB_ENV *dbenv;
00142 u_int32_t lk_detect;
00143 {
00144 ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_lk_detect");
00145
00146 switch (lk_detect) {
00147 case DB_LOCK_DEFAULT:
00148 case DB_LOCK_OLDEST:
00149 case DB_LOCK_RANDOM:
00150 case DB_LOCK_YOUNGEST:
00151 break;
00152 default:
00153 return (EINVAL);
00154 }
00155 dbenv->lk_detect = lk_detect;
00156 return (0);
00157 }
00158
00159
00160
00161
00162
00163 static int
00164 __lock_set_lk_max(dbenv, lk_max)
00165 DB_ENV *dbenv;
00166 u_int32_t lk_max;
00167 {
00168 ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_lk_max");
00169
00170 dbenv->lk_max = lk_max;
00171 return (0);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 int
00181 CDB___lock_open(dbenv)
00182 DB_ENV *dbenv;
00183 {
00184 DB_LOCKREGION *region;
00185 DB_LOCKTAB *lt;
00186 size_t size;
00187 int ret;
00188
00189
00190 if ((ret = CDB___os_calloc(dbenv, 1, sizeof(DB_LOCKTAB), <)) != 0)
00191 return (ret);
00192 lt->dbenv = dbenv;
00193
00194
00195 lt->reginfo.id = REG_ID_LOCK;
00196 lt->reginfo.mode = dbenv->db_mode;
00197 if (F_ISSET(dbenv, DB_ENV_CREATE))
00198 F_SET(<->reginfo, REGION_CREATE_OK);
00199 size = __lock_region_size(dbenv);
00200 if ((ret = CDB___db_r_attach(dbenv, <->reginfo, size)) != 0)
00201 goto err;
00202
00203
00204 if (F_ISSET(<->reginfo, REGION_CREATE))
00205 if ((ret = __lock_init(dbenv, lt)) != 0)
00206 goto err;
00207
00208
00209 region = lt->reginfo.primary =
00210 R_ADDR(<->reginfo, lt->reginfo.rp->primary);
00211
00212
00213 if (dbenv->lk_detect != DB_LOCK_NORUN) {
00214 if (region->detect != DB_LOCK_NORUN &&
00215 dbenv->lk_detect != DB_LOCK_DEFAULT &&
00216 region->detect != dbenv->lk_detect) {
00217 CDB___db_err(dbenv,
00218 "lock_open: incompatible deadlock detector mode");
00219 ret = EINVAL;
00220 goto err;
00221 }
00222
00223
00224
00225
00226
00227
00228 if (region->detect == DB_LOCK_NORUN)
00229 region->detect = dbenv->lk_detect;
00230 }
00231
00232
00233 lt->conflicts = (u_int8_t *)R_ADDR(<->reginfo, region->conf_off);
00234 lt->obj_tab = (DB_HASHTAB *)R_ADDR(<->reginfo, region->obj_off);
00235 lt->locker_tab = (DB_HASHTAB *)R_ADDR(<->reginfo, region->locker_off);
00236
00237 R_UNLOCK(dbenv, <->reginfo);
00238
00239 dbenv->lk_handle = lt;
00240 return (0);
00241
00242 err: if (lt->reginfo.addr != NULL) {
00243 if (F_ISSET(<->reginfo, REGION_CREATE))
00244 F_SET(lt->reginfo.rp, REG_DEAD);
00245 R_UNLOCK(dbenv, <->reginfo);
00246 (void)CDB___db_r_detach(dbenv, <->reginfo, 0);
00247 }
00248 CDB___os_free(lt, sizeof(*lt));
00249 return (ret);
00250 };
00251
00252
00253
00254
00255
00256 static int
00257 __lock_init(dbenv, lt)
00258 DB_ENV *dbenv;
00259 DB_LOCKTAB *lt;
00260 {
00261 const u_int8_t *lk_conflicts;
00262 struct __db_lock *lp;
00263 DB_LOCKER *lidp;
00264 DB_LOCKOBJ *op;
00265 DB_LOCKREGION *region;
00266 u_int32_t i, lk_modes, nelements;
00267 u_int8_t *addr;
00268 int ret;
00269
00270 if ((ret = CDB___db_shalloc(lt->reginfo.addr,
00271 sizeof(DB_LOCKREGION), 0, <->reginfo.primary)) != 0)
00272 goto mem_err;
00273 lt->reginfo.rp->primary = R_OFFSET(<->reginfo, lt->reginfo.primary);
00274 region = lt->reginfo.primary;
00275 memset(region, 0, sizeof(*region));
00276
00277
00278 if (dbenv->lk_modes == 0)
00279 if (LOCKING(dbenv)) {
00280 lk_modes = DB_LOCK_RW_N + 1;
00281 lk_conflicts = db_cdb_conflicts;
00282 } else {
00283 lk_modes = DB_LOCK_RW_N;
00284 lk_conflicts = CDB_db_rw_conflicts;
00285 }
00286 else {
00287 lk_modes = dbenv->lk_modes;
00288 lk_conflicts = dbenv->lk_conflicts;
00289 }
00290
00291 region->id = 0;
00292 region->need_dd = 0;
00293 region->detect = DB_LOCK_NORUN;
00294 region->maxlocks = dbenv->lk_max;
00295 region->table_size = CDB___db_tablesize(dbenv->lk_max);
00296 region->nmodes = lk_modes;
00297 region->nlockers = 0;
00298 region->maxnlockers = 0;
00299 region->nconflicts = 0;
00300 region->nrequests = 0;
00301 region->nreleases = 0;
00302 region->ndeadlocks = 0;
00303
00304 nelements = region->table_size;
00305
00306
00307 if ((ret =
00308 CDB___db_shalloc(lt->reginfo.addr, lk_modes * lk_modes, 0, &addr)) != 0)
00309 goto mem_err;
00310 memcpy(addr, lk_conflicts, lk_modes * lk_modes);
00311 region->conf_off = R_OFFSET(<->reginfo, addr);
00312
00313
00314 if ((ret = CDB___db_shalloc(lt->reginfo.addr,
00315 nelements * sizeof(DB_HASHTAB), 0, &addr)) != 0)
00316 goto mem_err;
00317 CDB___db_hashinit(addr, nelements);
00318 region->obj_off = R_OFFSET(<->reginfo, addr);
00319
00320
00321 if ((ret = CDB___db_shalloc(lt->reginfo.addr,
00322 nelements * sizeof(DB_HASHTAB), 0, &addr)) != 0)
00323 goto mem_err;
00324 CDB___db_hashinit(addr, nelements);
00325 region->locker_off = R_OFFSET(<->reginfo, addr);
00326
00327
00328
00329
00330
00331
00332 SH_TAILQ_INIT(®ion->free_locks);
00333 for (i = 0; i < region->maxlocks; ++i) {
00334 if ((ret = CDB___db_shalloc(lt->reginfo.addr,
00335 sizeof(struct __db_lock), MUTEX_ALIGN, &lp)) != 0)
00336 goto mem_err;
00337 lp->status = DB_LSTAT_FREE;
00338 if ((ret = __db_mutex_init(dbenv, &lp->mutex,
00339 R_OFFSET(<->reginfo, &lp->mutex) + DB_FCNTL_OFF_LOCK,
00340 MUTEX_SELF_BLOCK)) != 0)
00341 return (ret);
00342 MUTEX_LOCK(&lp->mutex, lt->dbenv->lockfhp);
00343 SH_TAILQ_INSERT_HEAD(®ion->free_locks, lp, links, __db_lock);
00344 }
00345
00346
00347 SH_TAILQ_INIT(®ion->dd_objs);
00348 SH_TAILQ_INIT(®ion->free_objs);
00349 for (i = 0; i < region->maxlocks; ++i) {
00350 if ((ret = CDB___db_shalloc(lt->reginfo.addr,
00351 sizeof(DB_LOCKOBJ), 0, &op)) != 0)
00352 goto mem_err;
00353 SH_TAILQ_INSERT_HEAD(
00354 ®ion->free_objs, op, links, __db_lockobj);
00355 }
00356
00357
00358 SH_TAILQ_INIT(®ion->free_lockers);
00359 for (i = 0; i < region->maxlocks; ++i) {
00360 if ((ret = CDB___db_shalloc(lt->reginfo.addr,
00361 sizeof(DB_LOCKER), 0, &lidp)) != 0) {
00362 mem_err: CDB___db_err(dbenv, "Unable to allocate memory for the lock table");
00363 return (ret);
00364 }
00365 SH_TAILQ_INSERT_HEAD(
00366 ®ion->free_lockers, lidp, links, __db_locker);
00367 }
00368
00369 return (0);
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 int
00379 CDB___lock_close(dbenv)
00380 DB_ENV *dbenv;
00381 {
00382 DB_LOCKTAB *lt;
00383 int ret;
00384
00385 lt = dbenv->lk_handle;
00386
00387
00388 ret = CDB___db_r_detach(dbenv, <->reginfo, 0);
00389
00390 CDB___os_free(lt, sizeof(*lt));
00391
00392 dbenv->lk_handle = NULL;
00393 return (ret);
00394 }
00395
00396
00397
00398
00399
00400 int
00401 CDB_lock_stat(dbenv, statp, db_malloc)
00402 DB_ENV *dbenv;
00403 DB_LOCK_STAT **statp;
00404 void *(*db_malloc) __P((size_t));
00405 {
00406 DB_LOCKREGION *region;
00407 DB_LOCKTAB *lt;
00408 DB_LOCK_STAT *stats;
00409 int ret;
00410
00411 #ifdef HAVE_RPC
00412 if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
00413 return (__dbcl_lock_stat(dbenv, statp, db_malloc));
00414 #endif
00415
00416 PANIC_CHECK(dbenv);
00417 ENV_REQUIRES_CONFIG(dbenv, dbenv->lk_handle, DB_INIT_LOCK);
00418
00419 *statp = NULL;
00420
00421 lt = dbenv->lk_handle;
00422
00423 if ((ret = CDB___os_malloc(dbenv, sizeof(*stats), db_malloc, &stats)) != 0)
00424 return (ret);
00425
00426
00427 R_LOCK(dbenv, <->reginfo);
00428
00429 region = lt->reginfo.primary;
00430 stats->st_lastid = region->id;
00431 stats->st_maxlocks = region->maxlocks;
00432 stats->st_nmodes = region->nmodes;
00433 stats->st_nlockers = region->nlockers;
00434 stats->st_maxnlockers = region->maxnlockers;
00435 stats->st_nconflicts = region->nconflicts;
00436 stats->st_nrequests = region->nrequests;
00437 stats->st_nreleases = region->nreleases;
00438 stats->st_nnowaits = region->nnowaits;
00439 stats->st_ndeadlocks = region->ndeadlocks;
00440
00441 stats->st_region_wait = lt->reginfo.rp->mutex.mutex_set_wait;
00442 stats->st_region_nowait = lt->reginfo.rp->mutex.mutex_set_nowait;
00443 stats->st_regsize = lt->reginfo.rp->size;
00444
00445 R_UNLOCK(dbenv, <->reginfo);
00446
00447 *statp = stats;
00448 return (0);
00449 }
00450
00451 #define LOCK_DUMP_CONF 0x001
00452 #define LOCK_DUMP_FREE 0x002
00453 #define LOCK_DUMP_LOCKERS 0x004
00454 #define LOCK_DUMP_MEM 0x008
00455 #define LOCK_DUMP_OBJECTS 0x010
00456 #define LOCK_DUMP_ALL 0x01f
00457
00458
00459
00460
00461
00462
00463 void
00464 CDB___lock_dump_region(dbenv, area, fp)
00465 DB_ENV *dbenv;
00466 char *area;
00467 FILE *fp;
00468 {
00469 struct __db_lock *lp;
00470 DB_LOCKER *lip;
00471 DB_LOCKOBJ *op;
00472 DB_LOCKREGION *lrp;
00473 DB_LOCKTAB *lt;
00474 u_int32_t flags, i, j;
00475 int label;
00476
00477
00478 if (fp == NULL)
00479 fp = stderr;
00480
00481 for (flags = 0; *area != '\0'; ++area)
00482 switch (*area) {
00483 case 'A':
00484 LF_SET(LOCK_DUMP_ALL);
00485 break;
00486 case 'c':
00487 LF_SET(LOCK_DUMP_CONF);
00488 break;
00489 case 'f':
00490 LF_SET(LOCK_DUMP_FREE);
00491 break;
00492 case 'l':
00493 LF_SET(LOCK_DUMP_LOCKERS);
00494 break;
00495 case 'm':
00496 LF_SET(LOCK_DUMP_MEM);
00497 break;
00498 case 'o':
00499 LF_SET(LOCK_DUMP_OBJECTS);
00500 break;
00501 }
00502
00503 lt = dbenv->lk_handle;
00504 lrp = lt->reginfo.primary;
00505 LOCKREGION(dbenv, lt);
00506
00507 fprintf(fp, "%s\nLock region parameters\n", DB_LINE);
00508 fprintf(fp, "%s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lu\n",
00509 "table size", (u_long)lrp->table_size,
00510 "obj_off", (u_long)lrp->obj_off,
00511 "osynch_off", (u_long)lrp->osynch_off,
00512 "locker_off", (u_long)lrp->locker_off,
00513 "lsynch_off", (u_long)lrp->lsynch_off,
00514 "need_dd", (u_long)lrp->need_dd);
00515
00516 if (LF_ISSET(LOCK_DUMP_CONF)) {
00517 fprintf(fp, "\n%s\nConflict matrix\n", DB_LINE);
00518 for (i = 0; i < lrp->nmodes; i++) {
00519 for (j = 0; j < lrp->nmodes; j++)
00520 fprintf(fp, "%lu\t",
00521 (u_long)lt->conflicts[i * lrp->nmodes + j]);
00522 fprintf(fp, "\n");
00523 }
00524 }
00525
00526 if (LF_ISSET(LOCK_DUMP_LOCKERS)) {
00527 fprintf(fp, "%s\nLocker hash buckets\n", DB_LINE);
00528 for (i = 0; i < lrp->table_size; i++) {
00529 label = 1;
00530 for (lip =
00531 SH_TAILQ_FIRST(<->locker_tab[i], __db_locker);
00532 lip != NULL;
00533 lip = SH_TAILQ_NEXT(lip, links, __db_locker)) {
00534 if (label) {
00535 fprintf(fp, "Bucket %lu:\n", (u_long)i);
00536 label = 0;
00537 }
00538 __lock_dump_locker(lt, lip, fp);
00539 }
00540 }
00541 }
00542
00543 if (LF_ISSET(LOCK_DUMP_OBJECTS)) {
00544 fprintf(fp, "%s\nObject hash buckets\n", DB_LINE);
00545 for (i = 0; i < lrp->table_size; i++) {
00546 label = 1;
00547 for (op = SH_TAILQ_FIRST(<->obj_tab[i], __db_lockobj);
00548 op != NULL;
00549 op = SH_TAILQ_NEXT(op, links, __db_lockobj)) {
00550 if (label) {
00551 fprintf(fp, "Bucket %lu:\n", (u_long)i);
00552 label = 0;
00553 }
00554 __lock_dump_object(lt, op, fp);
00555 }
00556 }
00557 }
00558
00559 if (LF_ISSET(LOCK_DUMP_FREE)) {
00560 fprintf(fp, "%s\nLock free list\n", DB_LINE);
00561 for (lp = SH_TAILQ_FIRST(&lrp->free_locks, __db_lock);
00562 lp != NULL;
00563 lp = SH_TAILQ_NEXT(lp, links, __db_lock))
00564 fprintf(fp, "0x%lx: %lu\t%lu\t%s\t0x%lx\n", (u_long)lp,
00565 (u_long)lp->holder, (u_long)lp->mode,
00566 __lock_dump_status(lp->status), (u_long)lp->obj);
00567
00568 fprintf(fp, "%s\nObject free list\n", DB_LINE);
00569 for (op = SH_TAILQ_FIRST(&lrp->free_objs, __db_lockobj);
00570 op != NULL;
00571 op = SH_TAILQ_NEXT(op, links, __db_lockobj))
00572 fprintf(fp, "0x%lx\n", (u_long)op);
00573
00574 fprintf(fp, "%s\nLocker free list\n", DB_LINE);
00575 for (lip = SH_TAILQ_FIRST(&lrp->free_lockers, __db_locker);
00576 lip != NULL;
00577 lip = SH_TAILQ_NEXT(lip, links, __db_locker))
00578 fprintf(fp, "0x%lx\n", (u_long)lip);
00579 }
00580
00581 if (LF_ISSET(LOCK_DUMP_MEM))
00582 CDB___db_shalloc_dump(lt->reginfo.addr, fp);
00583
00584 UNLOCKREGION(dbenv, lt);
00585 }
00586
00587 static void
00588 __lock_dump_locker(lt, lip, fp)
00589 DB_LOCKTAB *lt;
00590 DB_LOCKER *lip;
00591 FILE *fp;
00592 {
00593 struct __db_lock *lp;
00594
00595 fprintf(fp, "L %lx [%ld]", (u_long)lip->id, (long)lip->dd_id);
00596 fprintf(fp, " %s ", F_ISSET(lip, DB_LOCKER_DELETED) ? "(D)" : " ");
00597
00598 if ((lp = SH_LIST_FIRST(&lip->heldby, __db_lock)) == NULL)
00599 fprintf(fp, "\n");
00600 else
00601 for (; lp != NULL;
00602 lp = SH_LIST_NEXT(lp, locker_links, __db_lock))
00603 CDB___lock_printlock(lt, lp, 1);
00604 }
00605
00606 static void
00607 __lock_dump_object(lt, op, fp)
00608 DB_LOCKTAB *lt;
00609 DB_LOCKOBJ *op;
00610 FILE *fp;
00611 {
00612 struct __db_lock *lp;
00613 u_int32_t j;
00614 u_int8_t *ptr;
00615 u_int ch;
00616
00617 ptr = SH_DBT_PTR(&op->lockobj);
00618 for (j = 0; j < op->lockobj.size; ptr++, j++) {
00619 ch = *ptr;
00620 fprintf(fp, isprint(ch) ? "%c" : "\\%o", ch);
00621 }
00622 fprintf(fp, "\n");
00623
00624 fprintf(fp, "H:");
00625 for (lp =
00626 SH_TAILQ_FIRST(&op->holders, __db_lock);
00627 lp != NULL;
00628 lp = SH_TAILQ_NEXT(lp, links, __db_lock))
00629 CDB___lock_printlock(lt, lp, 1);
00630 lp = SH_TAILQ_FIRST(&op->waiters, __db_lock);
00631 if (lp != NULL) {
00632 fprintf(fp, "\nW:");
00633 for (; lp != NULL; lp = SH_TAILQ_NEXT(lp, links, __db_lock))
00634 CDB___lock_printlock(lt, lp, 1);
00635 }
00636 }
00637
00638 static const char *
00639 __lock_dump_status(status)
00640 db_status_t status;
00641 {
00642 switch (status) {
00643 case DB_LSTAT_ABORTED:
00644 return ("aborted");
00645 case DB_LSTAT_ERR:
00646 return ("err");
00647 case DB_LSTAT_FREE:
00648 return ("free");
00649 case DB_LSTAT_HELD:
00650 return ("held");
00651 case DB_LSTAT_NOGRANT:
00652 return ("nogrant");
00653 case DB_LSTAT_PENDING:
00654 return ("pending");
00655 case DB_LSTAT_WAITING:
00656 return ("waiting");
00657 }
00658 return ("unknown status");
00659 }
00660
00661
00662
00663
00664
00665 static size_t
00666 __lock_region_size(dbenv)
00667 DB_ENV *dbenv;
00668 {
00669 size_t retval;
00670 u_int32_t i, nelements, nlocks;
00671 int gb;
00672
00673 gb = 0;
00674 #ifdef DIAGNOSTIC
00675
00676
00677
00678
00679
00680 gb = 1;
00681 #endif
00682
00683 nlocks = dbenv->lk_max;
00684 nelements = CDB___db_tablesize(dbenv->lk_max);
00685
00686
00687
00688
00689
00690 retval = 0;
00691 retval += ALIGN(sizeof(DB_LOCKREGION) + gb, 1);
00692 retval += ALIGN(dbenv->lk_modes * dbenv->lk_modes + gb, 1);
00693 retval += ALIGN(nelements * (sizeof(DB_HASHTAB) + gb), 1);
00694 retval += ALIGN(nelements * (sizeof(DB_HASHTAB) + gb), 1);
00695 for (i = 0; i < nlocks; ++i)
00696 retval +=
00697 ALIGN(sizeof(struct __db_lock) + gb , MUTEX_ALIGN);
00698 for (i = 0; i < nlocks; ++i)
00699 retval += ALIGN(sizeof(DB_LOCKOBJ) + gb , 1);
00700 for (i = 0; i < nlocks; ++i)
00701 retval += ALIGN(sizeof(DB_LOCKER) + gb , 1);
00702
00703
00704
00705
00706
00707 retval += nlocks * (2 * sizeof(ssize_t) + sizeof(size_t));
00708
00709
00710
00711
00712
00713 retval += ALIGN(nlocks * 16, sizeof(size_t));
00714
00715
00716 retval += 16 * 1024;
00717
00718 return (retval);
00719 }