lock_stat.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:7k
- /*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998, 1999, 2000
- * Sleepycat Software. All rights reserved.
- */
- #include "db_config.h"
- #ifndef lint
- static const char revid[] = "$Id: lock_stat.c,v 11.4 2000/12/08 20:15:31 ubell Exp $";
- #endif /* not lint */
- #ifndef NO_SYSTEM_INCLUDES
- #include <sys/types.h>
- #include <ctype.h>
- #endif
- #ifdef HAVE_RPC
- #include "db_server.h"
- #endif
- #include "db_int.h"
- #include "db_shash.h"
- #include "lock.h"
- #ifdef HAVE_RPC
- #include "gen_client_ext.h"
- #include "rpc_client_ext.h"
- #endif
- static void __lock_dump_locker __P((DB_LOCKTAB *, DB_LOCKER *, FILE *));
- static void __lock_dump_object __P((DB_LOCKTAB *, DB_LOCKOBJ *, FILE *));
- static const char *
- __lock_dump_status __P((db_status_t));
- /*
- * lock_stat --
- * Return LOCK statistics.
- */
- int
- lock_stat(dbenv, statp, db_malloc)
- DB_ENV *dbenv;
- DB_LOCK_STAT **statp;
- void *(*db_malloc) __P((size_t));
- {
- DB_LOCKREGION *region;
- DB_LOCKTAB *lt;
- DB_LOCK_STAT *stats;
- int ret;
- #ifdef HAVE_RPC
- if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
- return (__dbcl_lock_stat(dbenv, statp, db_malloc));
- #endif
- PANIC_CHECK(dbenv);
- ENV_REQUIRES_CONFIG(dbenv, dbenv->lk_handle, DB_INIT_LOCK);
- *statp = NULL;
- lt = dbenv->lk_handle;
- if ((ret = __os_malloc(dbenv, sizeof(*stats), db_malloc, &stats)) != 0)
- return (ret);
- /* Copy out the global statistics. */
- R_LOCK(dbenv, <->reginfo);
- region = lt->reginfo.primary;
- stats->st_lastid = region->id;
- stats->st_maxlocks = region->maxlocks;
- stats->st_maxlockers = region->maxlockers;
- stats->st_maxobjects = region->maxobjects;
- stats->st_nmodes = region->nmodes;
- stats->st_nlockers = region->nlockers;
- stats->st_maxnlockers = region->maxnlockers;
- stats->st_nobjects = region->nobjects;
- stats->st_maxnobjects = region->maxnobjects;
- stats->st_nlocks = region->nlocks;
- stats->st_maxnlocks = region->maxnlocks;
- stats->st_nconflicts = region->nconflicts;
- stats->st_nrequests = region->nrequests;
- stats->st_nreleases = region->nreleases;
- stats->st_nnowaits = region->nnowaits;
- stats->st_ndeadlocks = region->ndeadlocks;
- stats->st_region_wait = lt->reginfo.rp->mutex.mutex_set_wait;
- stats->st_region_nowait = lt->reginfo.rp->mutex.mutex_set_nowait;
- stats->st_regsize = lt->reginfo.rp->size;
- R_UNLOCK(dbenv, <->reginfo);
- *statp = stats;
- return (0);
- }
- #define LOCK_DUMP_CONF 0x001 /* Conflict matrix. */
- #define LOCK_DUMP_FREE 0x002 /* Display lock free list. */
- #define LOCK_DUMP_LOCKERS 0x004 /* Display lockers. */
- #define LOCK_DUMP_MEM 0x008 /* Display region memory. */
- #define LOCK_DUMP_OBJECTS 0x010 /* Display objects. */
- #define LOCK_DUMP_ALL 0x01f /* Display all. */
- /*
- * __lock_dump_region --
- *
- * PUBLIC: void __lock_dump_region __P((DB_ENV *, char *, FILE *));
- */
- void
- __lock_dump_region(dbenv, area, fp)
- DB_ENV *dbenv;
- char *area;
- FILE *fp;
- {
- struct __db_lock *lp;
- DB_LOCKER *lip;
- DB_LOCKOBJ *op;
- DB_LOCKREGION *lrp;
- DB_LOCKTAB *lt;
- u_int32_t flags, i, j;
- int label;
- /* Make it easy to call from the debugger. */
- if (fp == NULL)
- fp = stderr;
- for (flags = 0; *area != ' '; ++area)
- switch (*area) {
- case 'A':
- LF_SET(LOCK_DUMP_ALL);
- break;
- case 'c':
- LF_SET(LOCK_DUMP_CONF);
- break;
- case 'f':
- LF_SET(LOCK_DUMP_FREE);
- break;
- case 'l':
- LF_SET(LOCK_DUMP_LOCKERS);
- break;
- case 'm':
- LF_SET(LOCK_DUMP_MEM);
- break;
- case 'o':
- LF_SET(LOCK_DUMP_OBJECTS);
- break;
- }
- lt = dbenv->lk_handle;
- lrp = lt->reginfo.primary;
- LOCKREGION(dbenv, lt);
- fprintf(fp, "%snLock region parametersn", DB_LINE);
- fprintf(fp, "%s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lun",
- "locker table size", (u_long)lrp->locker_t_size,
- "object table size", (u_long)lrp->object_t_size,
- "obj_off", (u_long)lrp->obj_off,
- "osynch_off", (u_long)lrp->osynch_off,
- "locker_off", (u_long)lrp->locker_off,
- "lsynch_off", (u_long)lrp->lsynch_off,
- "need_dd", (u_long)lrp->need_dd);
- if (LF_ISSET(LOCK_DUMP_CONF)) {
- fprintf(fp, "n%snConflict matrixn", DB_LINE);
- for (i = 0; i < lrp->nmodes; i++) {
- for (j = 0; j < lrp->nmodes; j++)
- fprintf(fp, "%lut",
- (u_long)lt->conflicts[i * lrp->nmodes + j]);
- fprintf(fp, "n");
- }
- }
- if (LF_ISSET(LOCK_DUMP_LOCKERS)) {
- fprintf(fp, "%snLocker hash bucketsn", DB_LINE);
- for (i = 0; i < lrp->locker_t_size; i++) {
- label = 1;
- for (lip =
- SH_TAILQ_FIRST(<->locker_tab[i], __db_locker);
- lip != NULL;
- lip = SH_TAILQ_NEXT(lip, links, __db_locker)) {
- if (label) {
- fprintf(fp, "Bucket %lu:n", (u_long)i);
- label = 0;
- }
- __lock_dump_locker(lt, lip, fp);
- }
- }
- }
- if (LF_ISSET(LOCK_DUMP_OBJECTS)) {
- fprintf(fp, "%snObject hash bucketsn", DB_LINE);
- for (i = 0; i < lrp->object_t_size; i++) {
- label = 1;
- for (op = SH_TAILQ_FIRST(<->obj_tab[i], __db_lockobj);
- op != NULL;
- op = SH_TAILQ_NEXT(op, links, __db_lockobj)) {
- if (label) {
- fprintf(fp, "Bucket %lu:n", (u_long)i);
- label = 0;
- }
- __lock_dump_object(lt, op, fp);
- }
- }
- }
- if (LF_ISSET(LOCK_DUMP_FREE)) {
- fprintf(fp, "%snLock free listn", DB_LINE);
- for (lp = SH_TAILQ_FIRST(&lrp->free_locks, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_NEXT(lp, links, __db_lock))
- fprintf(fp, "0x%lx: %lut%lut%st0x%lxn", (u_long)lp,
- (u_long)lp->holder, (u_long)lp->mode,
- __lock_dump_status(lp->status), (u_long)lp->obj);
- fprintf(fp, "%snObject free listn", DB_LINE);
- for (op = SH_TAILQ_FIRST(&lrp->free_objs, __db_lockobj);
- op != NULL;
- op = SH_TAILQ_NEXT(op, links, __db_lockobj))
- fprintf(fp, "0x%lxn", (u_long)op);
- fprintf(fp, "%snLocker free listn", DB_LINE);
- for (lip = SH_TAILQ_FIRST(&lrp->free_lockers, __db_locker);
- lip != NULL;
- lip = SH_TAILQ_NEXT(lip, links, __db_locker))
- fprintf(fp, "0x%lxn", (u_long)lip);
- }
- if (LF_ISSET(LOCK_DUMP_MEM))
- __db_shalloc_dump(lt->reginfo.addr, fp);
- UNLOCKREGION(dbenv, lt);
- }
- static void
- __lock_dump_locker(lt, lip, fp)
- DB_LOCKTAB *lt;
- DB_LOCKER *lip;
- FILE *fp;
- {
- struct __db_lock *lp;
- fprintf(fp, "L %lx [%ld]", (u_long)lip->id, (long)lip->dd_id);
- fprintf(fp, " %s ", F_ISSET(lip, DB_LOCKER_DELETED) ? "(D)" : " ");
- if ((lp = SH_LIST_FIRST(&lip->heldby, __db_lock)) == NULL)
- fprintf(fp, "n");
- else
- for (; lp != NULL;
- lp = SH_LIST_NEXT(lp, locker_links, __db_lock))
- __lock_printlock(lt, lp, 1);
- }
- static void
- __lock_dump_object(lt, op, fp)
- DB_LOCKTAB *lt;
- DB_LOCKOBJ *op;
- FILE *fp;
- {
- struct __db_lock *lp;
- u_int32_t j;
- u_int8_t *ptr;
- u_int ch;
- ptr = SH_DBT_PTR(&op->lockobj);
- for (j = 0; j < op->lockobj.size; ptr++, j++) {
- ch = *ptr;
- fprintf(fp, isprint(ch) ? "%c" : "\%o", ch);
- }
- fprintf(fp, "n");
- fprintf(fp, "H:");
- for (lp =
- SH_TAILQ_FIRST(&op->holders, __db_lock);
- lp != NULL;
- lp = SH_TAILQ_NEXT(lp, links, __db_lock))
- __lock_printlock(lt, lp, 1);
- lp = SH_TAILQ_FIRST(&op->waiters, __db_lock);
- if (lp != NULL) {
- fprintf(fp, "nW:");
- for (; lp != NULL; lp = SH_TAILQ_NEXT(lp, links, __db_lock))
- __lock_printlock(lt, lp, 1);
- }
- }
- static const char *
- __lock_dump_status(status)
- db_status_t status;
- {
- switch (status) {
- case DB_LSTAT_ABORTED:
- return ("aborted");
- case DB_LSTAT_ERR:
- return ("err");
- case DB_LSTAT_FREE:
- return ("free");
- case DB_LSTAT_HELD:
- return ("held");
- case DB_LSTAT_NOGRANT:
- return ("nogrant");
- case DB_LSTAT_PENDING:
- return ("pending");
- case DB_LSTAT_WAITING:
- return ("waiting");
- }
- return ("unknown status");
- }