diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-02-17 17:25:57 +0000 |
---|---|---|
committer | <> | 2015-03-17 16:26:24 +0000 |
commit | 780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch) | |
tree | 598f8b9fa431b228d29897e798de4ac0c1d3d970 /src/mutex/mut_stat.c | |
parent | 7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff) | |
download | berkeleydb-master.tar.gz |
Diffstat (limited to 'src/mutex/mut_stat.c')
-rw-r--r-- | src/mutex/mut_stat.c | 119 |
1 files changed, 88 insertions, 31 deletions
diff --git a/src/mutex/mut_stat.c b/src/mutex/mut_stat.c index b64207fa..af622c7d 100644 --- a/src/mutex/mut_stat.c +++ b/src/mutex/mut_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -19,6 +19,17 @@ static int __mutex_print_stats __P((ENV *, u_int32_t)); static void __mutex_print_summary __P((ENV *)); static int __mutex_stat __P((ENV *, DB_MUTEX_STAT **, u_int32_t)); +static const FN MutexFlagNames[] = { + { DB_MUTEX_ALLOCATED, "alloc" }, + { DB_MUTEX_LOCKED, "locked" }, + { DB_MUTEX_LOGICAL_LOCK, "logical" }, + { DB_MUTEX_OWNER_DEAD, "ower-dead" }, + { DB_MUTEX_PROCESS_ONLY, "process-private" }, + { DB_MUTEX_SELF_BLOCK, "self-block" }, + { DB_MUTEX_SHARED, "shared" }, + { 0, NULL } +}; + /* * __mutex_stat_pp -- * ENV->mutex_stat pre/post processing. @@ -170,11 +181,12 @@ __mutex_print_summary(env) size = 0; if (F_ISSET(env, ENV_PRIVATE)) { - mutexp = (DB_MUTEX *)mtxmgr->mutex_array + 1; + mutexp = (DB_MUTEX *)((uintptr_t)mtxmgr->mutex_array + + mtxregion->mutex_size); chunk = NULL; size = __env_elem_size(env, ROFF_TO_P(mtxregion->mutex_off_alloc)); - size -= sizeof(*mutexp); + size -= mtxregion->mutex_size; } else mutexp = MUTEXP_SET(env, 1); for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i) { @@ -185,13 +197,15 @@ __mutex_print_summary(env) else counts[mutexp->alloc_id]++; - mutexp++; + mutexp = (DB_MUTEX *)((uintptr_t)mutexp + + mtxregion->mutex_size); if (F_ISSET(env, ENV_PRIVATE) && (size -= sizeof(*mutexp)) < sizeof(*mutexp)) { mutexp = __env_get_chunk(&mtxmgr->reginfo, &chunk, &size); + mutexp = ALIGNP_INC(mutexp, + mtxregion->stat.st_mutex_align); } - mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align); } __db_msg(env, "Mutex counts"); __db_msg(env, "%d\tUnallocated", counts[0]); @@ -252,14 +266,6 @@ __mutex_print_all(env, flags) ENV *env; u_int32_t flags; { - static const FN fn[] = { - { DB_MUTEX_ALLOCATED, "alloc" }, - { DB_MUTEX_LOCKED, "locked" }, - { DB_MUTEX_LOGICAL_LOCK, "logical" }, - { DB_MUTEX_PROCESS_ONLY, "process-private" }, - { DB_MUTEX_SELF_BLOCK, "self-block" }, - { 0, NULL } - }; DB_MSGBUF mb, *mbp; DB_MUTEX *mutexp; DB_MUTEXMGR *mtxmgr; @@ -294,37 +300,32 @@ __mutex_print_all(env, flags) __db_msg(env, "mutex\twait/nowait, pct wait, holder, flags"); size = 0; if (F_ISSET(env, ENV_PRIVATE)) { - mutexp = (DB_MUTEX *)mtxmgr->mutex_array + 1; + mutexp = (DB_MUTEX *)((uintptr_t)mtxmgr->mutex_array + + mtxregion->mutex_size); chunk = NULL; size = __env_elem_size(env, ROFF_TO_P(mtxregion->mutex_off_alloc)); - size -= sizeof(*mutexp); + size -= mtxregion->mutex_size; } else mutexp = MUTEXP_SET(env, 1); for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i) { if (F_ISSET(mutexp, DB_MUTEX_ALLOCATED)) { __db_msgadd(env, mbp, "%5lu\t", (u_long)i); - __mutex_print_debug_stats(env, mbp, F_ISSET(env, ENV_PRIVATE) ? (db_mutex_t)mutexp : i, flags); - - if (mutexp->alloc_id != 0) - __db_msgadd(env, mbp, - ", %s", __mutex_print_id(mutexp->alloc_id)); - - __db_prflags(env, mbp, mutexp->flags, fn, " (", ")"); - DB_MSGBUF_FLUSH(env, mbp); } - mutexp++; + mutexp = (DB_MUTEX *)((uintptr_t)mutexp + + mtxregion->mutex_size); if (F_ISSET(env, ENV_PRIVATE) && - (size -= sizeof(*mutexp)) < sizeof(*mutexp)) { + (size -= mtxregion->mutex_size) < mtxregion->mutex_size) { mutexp = __env_get_chunk(&mtxmgr->reginfo, &chunk, &size); + mutexp = ALIGNP_INC(mutexp, + mtxregion->stat.st_mutex_align); } - mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align); } return (0); @@ -332,8 +333,7 @@ __mutex_print_all(env, flags) /* * __mutex_print_debug_single -- - * Print mutex internal debugging statistics for a single mutex on a - * single output line. + * Print mutex internal debugging statistics for a single mutex. * * PUBLIC: void __mutex_print_debug_single * PUBLIC: __P((ENV *, const char *, db_mutex_t, u_int32_t)); @@ -359,8 +359,9 @@ __mutex_print_debug_single(env, tag, mutex, flags) /* * __mutex_print_debug_stats -- - * Print mutex internal debugging statistics, that is, the statistics - * in the [] square brackets. + * Print the mutex internal debugging statistics in square bracket,s on a + * followed by the allocation id and flags, on single line. When MUTEX_DIAG + * is on and the mutex is held, append the owner's stack trace. * * PUBLIC: void __mutex_print_debug_stats * PUBLIC: __P((ENV *, DB_MSGBUF *, db_mutex_t, u_int32_t)); @@ -380,6 +381,9 @@ __mutex_print_debug_stats(env, mbp, mutex, flags) !defined(HAVE_MUTEX_PTHREADS)) int sharecount; #endif +#ifdef MUTEX_DIAG + char timestr[CTIME_BUFLEN]; +#endif if (mutex == MUTEX_INVALID) { __db_msgadd(env, mbp, "[!Set]"); @@ -448,6 +452,22 @@ __mutex_print_debug_stats(env, mbp, mutex, flags) mutexp->hybrid_wait, mutexp->hybrid_wakeup); #endif + if (mutexp->alloc_id != 0) + __db_msgadd(env, + mbp, ", %s", __mutex_print_id(mutexp->alloc_id)); + + __db_prflags(env, mbp, mutexp->flags, MutexFlagNames, " (", ")"); +#ifdef MUTEX_DIAG + if (mutexp->alloc_id != MTX_LOGICAL_LOCK && + timespecisset(&mutexp->mutex_history.when)) { + __db_ctimespec(&mutexp->mutex_history.when, timestr); + __db_msgadd(env, mbp, "\nLocked %s", timestr); + if (mutexp->mutex_history.stacktext[0] != '\0') + __db_msgadd(env, mbp, "\n%.*s", + (int)sizeof(mutexp->mutex_history.stacktext) - 1, + mutexp->mutex_history.stacktext); + } +#endif if (LF_ISSET(DB_STAT_CLEAR)) __mutex_clear(env, mutex); } @@ -495,7 +515,8 @@ __mutex_print_id(alloc_id) case MTX_TXN_COMMIT: return ("txn commit"); case MTX_TXN_MVCC: return ("txn mvcc"); case MTX_TXN_REGION: return ("txn region"); - default: return ("unknown mutex type"); + case 0: return ("invalid 0 mutex type"); + default: return ("unknown non-zero mutex type"); /* NOTREACHED */ } } @@ -577,3 +598,39 @@ __mutex_stat_print_pp(dbenv, flags) return (__db_stat_not_built(dbenv->env)); } #endif + +/* + * __mutex_describe + * Fill in a buffer with the mutex #, alloc_id, and any other + * characteristics which are likely to be useful for diagnostics. The + * destination buffer must hold at least DB_MUTEX_DESCRIBE_STRLEN bytes. + * + * PUBLIC: char *__mutex_describe __P((ENV *, db_mutex_t, char *)); + */ +char * +__mutex_describe(env, mutex, dest) + ENV *env; + db_mutex_t mutex; + char *dest; +{ + DB_MUTEX *mutexp; + DB_MSGBUF mb, *mbp; + const char *type; + + DB_MSGBUF_INIT(&mb); + mbp = &mb; + mutexp = MUTEXP_SET(env, mutex); + type = F_ISSET(mutexp, DB_MUTEX_SHARED) ? "latch" : "mutex"; +#ifdef HAVE_STATISTICS + __db_msgadd(env, mbp, "%s %s id %ld ", + __mutex_print_id(mutexp->alloc_id), type, (long)mutex); + __db_prflags(env, mbp, mutexp->flags, MutexFlagNames, " (", ")"); +#else + __db_msgadd(env, mbp, "%s flags %x id %ld ", + type, mutexp->flags, (long)mutex); +#endif + (void)snprintf(dest, DB_MUTEX_DESCRIBE_STRLEN - 1, + "%.*s", (int)(mbp->cur - mbp->buf), mbp->buf); + dest[DB_MUTEX_DESCRIBE_STRLEN - 1] = '\0'; + return (dest); +} |