00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014
00015 #include <stdio.h>
00016 #include <string.h>
00017 #endif
00018
00019 #include "db_int.h"
00020 #include "dbinc/db_page.h"
00021 #include "dbinc/db_shash.h"
00022 #include "dbinc/db_am.h"
00023 #include "dbinc/log.h"
00024 #include "dbinc/mp.h"
00025
00026 #ifdef HAVE_STATISTICS
00027 static void __memp_print_bh
00028 __P((DB_ENV *, DB_MPOOL *, BH *, roff_t *, u_int32_t));
00029 static int __memp_print_all __P((DB_ENV *, u_int32_t));
00030 static int __memp_print_stats __P((DB_ENV *, u_int32_t));
00031 static int __memp_print_hash __P((DB_ENV *,
00032 DB_MPOOL *, REGINFO *, roff_t *, u_int32_t));
00033 static int __memp_stat __P((DB_ENV *,
00034 DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t));
00035 static void __memp_stat_wait __P((
00036 DB_ENV *, REGINFO *, MPOOL *, DB_MPOOL_STAT *, u_int32_t));
00037
00038
00039
00040
00041
00042
00043
00044
00045 int
00046 __memp_stat_pp(dbenv, gspp, fspp, flags)
00047 DB_ENV *dbenv;
00048 DB_MPOOL_STAT **gspp;
00049 DB_MPOOL_FSTAT ***fspp;
00050 u_int32_t flags;
00051 {
00052 DB_THREAD_INFO *ip;
00053 int ret;
00054
00055 PANIC_CHECK(dbenv);
00056 ENV_REQUIRES_CONFIG(dbenv,
00057 dbenv->mp_handle, "DB_ENV->memp_stat", DB_INIT_MPOOL);
00058
00059 if ((ret = __db_fchk(dbenv,
00060 "DB_ENV->memp_stat", flags, DB_STAT_CLEAR)) != 0)
00061 return (ret);
00062
00063 ENV_ENTER(dbenv, ip);
00064 REPLICATION_WRAP(dbenv, (__memp_stat(dbenv, gspp, fspp, flags)), ret);
00065 ENV_LEAVE(dbenv, ip);
00066 return (ret);
00067 }
00068
00069
00070
00071
00072
00073 static int
00074 __memp_stat(dbenv, gspp, fspp, flags)
00075 DB_ENV *dbenv;
00076 DB_MPOOL_STAT **gspp;
00077 DB_MPOOL_FSTAT ***fspp;
00078 u_int32_t flags;
00079 {
00080 DB_MPOOL *dbmp;
00081 DB_MPOOL_FSTAT **tfsp, *tstruct;
00082 DB_MPOOL_STAT *sp;
00083 MPOOL *c_mp, *mp;
00084 MPOOLFILE *mfp;
00085 size_t len, nlen;
00086 u_int32_t i, pagesize, st_bytes, st_gbytes, st_hash_buckets, st_pages;
00087 u_int32_t tmp_wait, tmp_nowait;
00088 int ret;
00089 char *name, *tname;
00090
00091 dbmp = dbenv->mp_handle;
00092 mp = dbmp->reginfo[0].primary;
00093
00094
00095 if (gspp != NULL) {
00096 *gspp = NULL;
00097
00098 if ((ret = __os_umalloc(dbenv, sizeof(**gspp), gspp)) != 0)
00099 return (ret);
00100 memset(*gspp, 0, sizeof(**gspp));
00101 sp = *gspp;
00102
00103
00104
00105
00106
00107
00108 c_mp = dbmp->reginfo[0].primary;
00109 sp->st_gbytes = c_mp->stat.st_gbytes;
00110 sp->st_bytes = c_mp->stat.st_bytes;
00111 sp->st_ncache = dbmp->nreg;
00112 sp->st_regsize = dbmp->reginfo[0].rp->size;
00113
00114 MPOOL_SYSTEM_LOCK(dbenv);
00115 sp->st_mmapsize = mp->mp_mmapsize;
00116 sp->st_maxopenfd = mp->mp_maxopenfd;
00117 sp->st_maxwrite = mp->mp_maxwrite;
00118 sp->st_maxwrite_sleep = mp->mp_maxwrite_sleep;
00119 MPOOL_SYSTEM_UNLOCK(dbenv);
00120
00121
00122 for (i = 0; i < mp->nreg; ++i) {
00123 c_mp = dbmp->reginfo[i].primary;
00124
00125 sp->st_map += c_mp->stat.st_map;
00126 sp->st_cache_hit += c_mp->stat.st_cache_hit;
00127 sp->st_cache_miss += c_mp->stat.st_cache_miss;
00128 sp->st_page_create += c_mp->stat.st_page_create;
00129 sp->st_page_in += c_mp->stat.st_page_in;
00130 sp->st_page_out += c_mp->stat.st_page_out;
00131 sp->st_ro_evict += c_mp->stat.st_ro_evict;
00132 sp->st_rw_evict += c_mp->stat.st_rw_evict;
00133 sp->st_page_trickle += c_mp->stat.st_page_trickle;
00134 sp->st_pages += c_mp->stat.st_pages;
00135
00136
00137
00138
00139 __memp_stat_hash(
00140 &dbmp->reginfo[i], c_mp, &sp->st_page_dirty);
00141 sp->st_page_clean = sp->st_pages - sp->st_page_dirty;
00142 sp->st_hash_buckets += c_mp->stat.st_hash_buckets;
00143 sp->st_hash_searches += c_mp->stat.st_hash_searches;
00144 sp->st_hash_longest += c_mp->stat.st_hash_longest;
00145 sp->st_hash_examined += c_mp->stat.st_hash_examined;
00146
00147
00148
00149
00150 __memp_stat_wait(
00151 dbenv, &dbmp->reginfo[i], c_mp, sp, flags);
00152 __mutex_set_wait_info(dbenv,
00153 c_mp->mtx_region, &tmp_wait, &tmp_nowait);
00154 sp->st_region_nowait += tmp_nowait;
00155 sp->st_region_wait += tmp_wait;
00156 sp->st_alloc += c_mp->stat.st_alloc;
00157 sp->st_alloc_buckets += c_mp->stat.st_alloc_buckets;
00158 if (sp->st_alloc_max_buckets <
00159 c_mp->stat.st_alloc_max_buckets)
00160 sp->st_alloc_max_buckets =
00161 c_mp->stat.st_alloc_max_buckets;
00162 sp->st_alloc_pages += c_mp->stat.st_alloc_pages;
00163 if (sp->st_alloc_max_pages <
00164 c_mp->stat.st_alloc_max_pages)
00165 sp->st_alloc_max_pages =
00166 c_mp->stat.st_alloc_max_pages;
00167
00168 if (LF_ISSET(DB_STAT_CLEAR)) {
00169 __mutex_clear(dbenv, c_mp->mtx_region);
00170
00171 MPOOL_SYSTEM_LOCK(dbenv);
00172 st_bytes = c_mp->stat.st_bytes;
00173 st_gbytes = c_mp->stat.st_gbytes;
00174 st_hash_buckets = c_mp->stat.st_hash_buckets;
00175 st_pages = c_mp->stat.st_pages;
00176 memset(&c_mp->stat, 0, sizeof(c_mp->stat));
00177 c_mp->stat.st_bytes = st_bytes;
00178 c_mp->stat.st_gbytes = st_gbytes;
00179 c_mp->stat.st_hash_buckets = st_hash_buckets;
00180 c_mp->stat.st_pages = st_pages;
00181 MPOOL_SYSTEM_UNLOCK(dbenv);
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 MPOOL_SYSTEM_LOCK(dbenv);
00194 for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile);
00195 mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
00196 sp->st_map += mfp->stat.st_map;
00197 sp->st_cache_hit += mfp->stat.st_cache_hit;
00198 sp->st_cache_miss += mfp->stat.st_cache_miss;
00199 sp->st_page_create += mfp->stat.st_page_create;
00200 sp->st_page_in += mfp->stat.st_page_in;
00201 sp->st_page_out += mfp->stat.st_page_out;
00202 if (fspp == NULL && LF_ISSET(DB_STAT_CLEAR)) {
00203 pagesize = mfp->stat.st_pagesize;
00204 memset(&mfp->stat, 0, sizeof(mfp->stat));
00205 mfp->stat.st_pagesize = pagesize;
00206 }
00207 }
00208 MPOOL_SYSTEM_UNLOCK(dbenv);
00209 }
00210
00211
00212 if (fspp != NULL) {
00213 *fspp = NULL;
00214
00215
00216 MPOOL_SYSTEM_LOCK(dbenv);
00217 for (i = 0, len = 0,
00218 mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile);
00219 mfp != NULL;
00220 ++i, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile))
00221 len += sizeof(DB_MPOOL_FSTAT *) +
00222 sizeof(DB_MPOOL_FSTAT) +
00223 strlen(__memp_fns(dbmp, mfp)) + 1;
00224 len += sizeof(DB_MPOOL_FSTAT *);
00225 MPOOL_SYSTEM_UNLOCK(dbenv);
00226
00227 if (i == 0)
00228 return (0);
00229
00230
00231 if ((ret = __os_umalloc(dbenv, len, fspp)) != 0)
00232 return (ret);
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 tfsp = *fspp;
00245 tstruct = (DB_MPOOL_FSTAT *)(tfsp + i + 1);
00246 tname = (char *)(tstruct + i);
00247
00248
00249
00250
00251
00252 MPOOL_SYSTEM_LOCK(dbenv);
00253 for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile);
00254 mfp != NULL && i-- > 0;
00255 ++tfsp, ++tstruct, tname += nlen,
00256 mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
00257 name = __memp_fns(dbmp, mfp);
00258 nlen = strlen(name) + 1;
00259 *tfsp = tstruct;
00260 *tstruct = mfp->stat;
00261 if (LF_ISSET(DB_STAT_CLEAR)) {
00262 pagesize = mfp->stat.st_pagesize;
00263 memset(&mfp->stat, 0, sizeof(mfp->stat));
00264 mfp->stat.st_pagesize = pagesize;
00265 }
00266 tstruct->file_name = tname;
00267 memcpy(tname, name, nlen);
00268 }
00269 MPOOL_SYSTEM_UNLOCK(dbenv);
00270
00271 *tfsp = NULL;
00272 }
00273 return (0);
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 int
00283 __memp_stat_print_pp(dbenv, flags)
00284 DB_ENV *dbenv;
00285 u_int32_t flags;
00286 {
00287 DB_THREAD_INFO *ip;
00288 int ret;
00289
00290 PANIC_CHECK(dbenv);
00291 ENV_REQUIRES_CONFIG(dbenv,
00292 dbenv->mp_handle, "DB_ENV->memp_stat_print", DB_INIT_MPOOL);
00293
00294 #define DB_STAT_MEMP_FLAGS \
00295 (DB_STAT_ALL | DB_STAT_CLEAR | DB_STAT_MEMP_HASH)
00296 if ((ret = __db_fchk(dbenv,
00297 "DB_ENV->memp_stat_print", flags, DB_STAT_MEMP_FLAGS)) != 0)
00298 return (ret);
00299
00300 ENV_ENTER(dbenv, ip);
00301 REPLICATION_WRAP(dbenv, (__memp_stat_print(dbenv, flags)), ret);
00302 ENV_LEAVE(dbenv, ip);
00303 return (ret);
00304 }
00305
00306 #define FMAP_ENTRIES 200
00307
00308
00309
00310
00311
00312
00313
00314 int
00315 __memp_stat_print(dbenv, flags)
00316 DB_ENV *dbenv;
00317 u_int32_t flags;
00318 {
00319 u_int32_t orig_flags;
00320 int ret;
00321
00322 orig_flags = flags;
00323 LF_CLR(DB_STAT_CLEAR);
00324 if (flags == 0 || LF_ISSET(DB_STAT_ALL)) {
00325 ret = __memp_print_stats(dbenv, orig_flags);
00326 if (flags == 0 || ret != 0)
00327 return (ret);
00328 }
00329
00330 if (LF_ISSET(DB_STAT_ALL | DB_STAT_MEMP_HASH) &&
00331 (ret = __memp_print_all(dbenv, orig_flags)) != 0)
00332 return (ret);
00333
00334 return (0);
00335 }
00336
00337
00338
00339
00340
00341 static int
00342 __memp_print_stats(dbenv, flags)
00343 DB_ENV *dbenv;
00344 u_int32_t flags;
00345 {
00346 DB_MPOOL_FSTAT **fsp, **tfsp;
00347 DB_MPOOL_STAT *gsp;
00348 int ret;
00349
00350 if ((ret = __memp_stat(dbenv, &gsp, &fsp, flags)) != 0)
00351 return (ret);
00352
00353 if (LF_ISSET(DB_STAT_ALL))
00354 __db_msg(dbenv, "Default cache region information:");
00355 __db_dlbytes(dbenv, "Total cache size",
00356 (u_long)gsp->st_gbytes, (u_long)0, (u_long)gsp->st_bytes);
00357 __db_dl(dbenv, "Number of caches", (u_long)gsp->st_ncache);
00358 __db_dlbytes(dbenv, "Pool individual cache size",
00359 (u_long)0, (u_long)0, (u_long)gsp->st_regsize);
00360 __db_dlbytes(dbenv, "Maximum memory-mapped file size",
00361 (u_long)0, (u_long)0, (u_long)gsp->st_mmapsize);
00362 STAT_LONG("Maximum open file descriptors", gsp->st_maxopenfd);
00363 STAT_LONG("Maximum sequential buffer writes", gsp->st_maxwrite);
00364 STAT_LONG("Sleep after writing maximum sequential buffers",
00365 gsp->st_maxwrite_sleep);
00366 __db_dl(dbenv,
00367 "Requested pages mapped into the process' address space",
00368 (u_long)gsp->st_map);
00369 __db_dl_pct(dbenv, "Requested pages found in the cache",
00370 (u_long)gsp->st_cache_hit, DB_PCT(
00371 gsp->st_cache_hit, gsp->st_cache_hit + gsp->st_cache_miss), NULL);
00372 __db_dl(dbenv, "Requested pages not found in the cache",
00373 (u_long)gsp->st_cache_miss);
00374 __db_dl(dbenv,
00375 "Pages created in the cache", (u_long)gsp->st_page_create);
00376 __db_dl(dbenv, "Pages read into the cache", (u_long)gsp->st_page_in);
00377 __db_dl(dbenv, "Pages written from the cache to the backing file",
00378 (u_long)gsp->st_page_out);
00379 __db_dl(dbenv, "Clean pages forced from the cache",
00380 (u_long)gsp->st_ro_evict);
00381 __db_dl(dbenv, "Dirty pages forced from the cache",
00382 (u_long)gsp->st_rw_evict);
00383 __db_dl(dbenv, "Dirty pages written by trickle-sync thread",
00384 (u_long)gsp->st_page_trickle);
00385 __db_dl(dbenv, "Current total page count",
00386 (u_long)gsp->st_pages);
00387 __db_dl(dbenv, "Current clean page count",
00388 (u_long)gsp->st_page_clean);
00389 __db_dl(dbenv, "Current dirty page count",
00390 (u_long)gsp->st_page_dirty);
00391 __db_dl(dbenv, "Number of hash buckets used for page location",
00392 (u_long)gsp->st_hash_buckets);
00393 __db_dl(dbenv,
00394 "Total number of times hash chains searched for a page",
00395 (u_long)gsp->st_hash_searches);
00396 __db_dl(dbenv, "The longest hash chain searched for a page",
00397 (u_long)gsp->st_hash_longest);
00398 __db_dl(dbenv,
00399 "Total number of hash chain entries checked for page",
00400 (u_long)gsp->st_hash_examined);
00401 __db_dl_pct(dbenv,
00402 "The number of hash bucket locks that required waiting",
00403 (u_long)gsp->st_hash_wait, DB_PCT(
00404 gsp->st_hash_wait, gsp->st_hash_wait + gsp->st_hash_nowait), NULL);
00405 __db_dl(dbenv,
00406 "The maximum number of times any hash bucket lock was waited for",
00407 (u_long)gsp->st_hash_max_wait);
00408 __db_dl_pct(dbenv,
00409 "The number of region locks that required waiting",
00410 (u_long)gsp->st_region_wait, DB_PCT(gsp->st_region_wait,
00411 gsp->st_region_wait + gsp->st_region_nowait), NULL);
00412 __db_dl(dbenv, "The number of page allocations", (u_long)gsp->st_alloc);
00413 __db_dl(dbenv,
00414 "The number of hash buckets examined during allocations",
00415 (u_long)gsp->st_alloc_buckets);
00416 __db_dl(dbenv,
00417 "The maximum number of hash buckets examined for an allocation",
00418 (u_long)gsp->st_alloc_max_buckets);
00419 __db_dl(dbenv, "The number of pages examined during allocations",
00420 (u_long)gsp->st_alloc_pages);
00421 __db_dl(dbenv, "The max number of pages examined for an allocation",
00422 (u_long)gsp->st_alloc_max_pages);
00423
00424 for (tfsp = fsp; fsp != NULL && *tfsp != NULL; ++tfsp) {
00425 if (LF_ISSET(DB_STAT_ALL))
00426 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00427 __db_msg(dbenv, "Pool File: %s", (*tfsp)->file_name);
00428 __db_dl(dbenv, "Page size", (u_long)(*tfsp)->st_pagesize);
00429 __db_dl(dbenv,
00430 "Requested pages mapped into the process' address space",
00431 (u_long)(*tfsp)->st_map);
00432 __db_dl_pct(dbenv, "Requested pages found in the cache",
00433 (u_long)(*tfsp)->st_cache_hit, DB_PCT((*tfsp)->st_cache_hit,
00434 (*tfsp)->st_cache_hit + (*tfsp)->st_cache_miss), NULL);
00435 __db_dl(dbenv, "Requested pages not found in the cache",
00436 (u_long)(*tfsp)->st_cache_miss);
00437 __db_dl(dbenv, "Pages created in the cache",
00438 (u_long)(*tfsp)->st_page_create);
00439 __db_dl(dbenv, "Pages read into the cache",
00440 (u_long)(*tfsp)->st_page_in);
00441 __db_dl(dbenv,
00442 "Pages written from the cache to the backing file",
00443 (u_long)(*tfsp)->st_page_out);
00444 }
00445
00446 __os_ufree(dbenv, fsp);
00447 __os_ufree(dbenv, gsp);
00448 return (0);
00449 }
00450
00451
00452
00453
00454
00455 static int
00456 __memp_print_all(dbenv, flags)
00457 DB_ENV *dbenv;
00458 u_int32_t flags;
00459 {
00460 static const FN fn[] = {
00461 { MP_CAN_MMAP, "MP_CAN_MMAP" },
00462 { MP_DIRECT, "MP_DIRECT" },
00463 { MP_EXTENT, "MP_EXTENT" },
00464 { MP_FAKE_DEADFILE, "deadfile" },
00465 { MP_FAKE_FILEWRITTEN, "file written" },
00466 { MP_FAKE_NB, "no backing file" },
00467 { MP_FAKE_UOC, "unlink on close" },
00468 { MP_NOT_DURABLE, "not durable" },
00469 { MP_TEMP, "MP_TEMP" },
00470 { 0, NULL }
00471 };
00472 static const FN cfn[] = {
00473 { DB_MPOOL_NOFILE, "DB_MPOOL_NOFILE" },
00474 { DB_MPOOL_UNLINK, "DB_MPOOL_UNLINK" },
00475 { 0, NULL }
00476 };
00477 DB_MPOOL *dbmp;
00478 DB_MPOOLFILE *dbmfp;
00479 MPOOL *mp;
00480 MPOOLFILE *mfp;
00481 roff_t fmap[FMAP_ENTRIES + 1];
00482 u_int32_t i, mfp_flags;
00483 int cnt, ret;
00484
00485 dbmp = dbenv->mp_handle;
00486 mp = dbmp->reginfo[0].primary;
00487 ret = 0;
00488
00489 MPOOL_SYSTEM_LOCK(dbenv);
00490
00491 __db_print_reginfo(dbenv, dbmp->reginfo, "Mpool");
00492 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00493
00494 __db_msg(dbenv, "MPOOL structure:");
00495 __mutex_print_debug_single(
00496 dbenv, "MPOOL region mutex", mp->mtx_region, flags);
00497 STAT_LSN("Maximum checkpoint LSN", &mp->lsn);
00498 STAT_ULONG("Hash table entries", mp->htab_buckets);
00499 STAT_ULONG("Hash table last-checked", mp->last_checked);
00500 STAT_ULONG("Hash table LRU count", mp->lru_count);
00501 STAT_ULONG("Put counter", mp->put_counter);
00502
00503 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00504 __db_msg(dbenv, "DB_MPOOL handle information:");
00505 __mutex_print_debug_single(
00506 dbenv, "DB_MPOOL handle mutex", dbmp->mutex, flags);
00507 STAT_ULONG("Underlying cache regions", dbmp->nreg);
00508
00509 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00510 __db_msg(dbenv, "DB_MPOOLFILE structures:");
00511 for (cnt = 0, dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
00512 dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q), ++cnt) {
00513 __db_msg(dbenv, "File #%d: %s: per-process, %s",
00514 cnt + 1, __memp_fn(dbmfp),
00515 F_ISSET(dbmfp, MP_READONLY) ? "readonly" : "read/write");
00516 STAT_ULONG("Reference count", dbmfp->ref);
00517 STAT_ULONG("Pinned block reference count", dbmfp->ref);
00518 STAT_ULONG("Clear length", dbmfp->clear_len);
00519 __db_print_fileid(dbenv, dbmfp->fileid, "\tID");
00520 STAT_ULONG("File type", dbmfp->ftype);
00521 STAT_ULONG("LSN offset", dbmfp->lsn_offset);
00522 STAT_ULONG("Max gbytes", dbmfp->gbytes);
00523 STAT_ULONG("Max bytes", dbmfp->bytes);
00524 STAT_ULONG("Cache priority", dbmfp->priority);
00525 STAT_POINTER("mmap address", dbmfp->addr);
00526 STAT_ULONG("mmap length", dbmfp->len);
00527 __db_prflags(dbenv, NULL, dbmfp->flags, cfn, NULL, "\tFlags");
00528 __db_print_fh(dbenv, "File handle", dbmfp->fhp, flags);
00529 }
00530
00531 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00532 __db_msg(dbenv, "MPOOLFILE structures:");
00533 for (cnt = 0, mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile);
00534 mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile), ++cnt) {
00535 __db_msg(dbenv, "File #%d: %s", cnt + 1, __memp_fns(dbmp, mfp));
00536 __mutex_print_debug_single(dbenv, "Mutex", mfp->mutex, flags);
00537
00538 MUTEX_LOCK(dbenv, mfp->mutex);
00539 STAT_ULONG("Reference count", mfp->mpf_cnt);
00540 STAT_ULONG("Block count", mfp->block_cnt);
00541 STAT_ULONG("Last page number", mfp->last_pgno);
00542 STAT_ULONG("Original last page number", mfp->orig_last_pgno);
00543 STAT_ULONG("Maximum page number", mfp->maxpgno);
00544 STAT_LONG("Type", mfp->ftype);
00545 STAT_LONG("Priority", mfp->priority);
00546 STAT_LONG("Page's LSN offset", mfp->lsn_off);
00547 STAT_LONG("Page's clear length", mfp->clear_len);
00548
00549 __db_print_fileid(dbenv,
00550 R_ADDR(dbmp->reginfo, mfp->fileid_off), "\tID");
00551
00552 mfp_flags = 0;
00553 if (mfp->deadfile)
00554 FLD_SET(mfp_flags, MP_FAKE_DEADFILE);
00555 if (mfp->file_written)
00556 FLD_SET(mfp_flags, MP_FAKE_FILEWRITTEN);
00557 if (mfp->no_backing_file)
00558 FLD_SET(mfp_flags, MP_FAKE_NB);
00559 if (mfp->unlink_on_close)
00560 FLD_SET(mfp_flags, MP_FAKE_UOC);
00561 __db_prflags(dbenv, NULL, mfp_flags, fn, NULL, "\tFlags");
00562
00563 if (cnt < FMAP_ENTRIES)
00564 fmap[cnt] = R_OFFSET(dbmp->reginfo, mfp);
00565 MUTEX_UNLOCK(dbenv, mfp->mutex);
00566 }
00567 MPOOL_SYSTEM_UNLOCK(dbenv);
00568
00569 if (cnt < FMAP_ENTRIES)
00570 fmap[cnt] = INVALID_ROFF;
00571 else
00572 fmap[FMAP_ENTRIES] = INVALID_ROFF;
00573
00574
00575 for (i = 0; i < mp->nreg; ++i) {
00576 __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
00577 __db_msg(dbenv, "Cache #%d:", i + 1);
00578 if ((ret = __memp_print_hash(
00579 dbenv, dbmp, &dbmp->reginfo[i], fmap, flags)) != 0)
00580 break;
00581 }
00582
00583 return (ret);
00584 }
00585
00586
00587
00588
00589
00590 static int
00591 __memp_print_hash(dbenv, dbmp, reginfo, fmap, flags)
00592 DB_ENV *dbenv;
00593 DB_MPOOL *dbmp;
00594 REGINFO *reginfo;
00595 roff_t *fmap;
00596 u_int32_t flags;
00597 {
00598 BH *bhp;
00599 DB_MPOOL_HASH *hp;
00600 DB_MSGBUF mb;
00601 MPOOL *c_mp;
00602 u_int32_t bucket;
00603
00604 c_mp = reginfo->primary;
00605 DB_MSGBUF_INIT(&mb);
00606
00607
00608 __db_msg(dbenv,
00609 "BH hash table (%lu hash slots)", (u_long)c_mp->htab_buckets);
00610 __db_msg(dbenv, "bucket #: priority, [mutex]");
00611 __db_msg(dbenv,
00612 "\tpageno, file, ref, LSN, [mutex], address, priority, flags");
00613
00614 for (hp = R_ADDR(reginfo, c_mp->htab),
00615 bucket = 0; bucket < c_mp->htab_buckets; ++hp, ++bucket) {
00616 MUTEX_LOCK(dbenv, hp->mtx_hash);
00617 if ((bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh)) != NULL) {
00618 __db_msgadd(dbenv, &mb, "bucket %lu: %lu, ",
00619 (u_long)bucket, (u_long)hp->hash_priority);
00620 __mutex_print_debug_stats(
00621 dbenv, &mb, hp->mtx_hash, flags);
00622 DB_MSGBUF_FLUSH(dbenv, &mb);
00623 }
00624 for (; bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh))
00625 __memp_print_bh(dbenv, dbmp, bhp, fmap, flags);
00626
00627 MUTEX_UNLOCK(dbenv, hp->mtx_hash);
00628 }
00629
00630 return (0);
00631 }
00632
00633
00634
00635
00636
00637 static void
00638 __memp_print_bh(dbenv, dbmp, bhp, fmap, flags)
00639 DB_ENV *dbenv;
00640 DB_MPOOL *dbmp;
00641 BH *bhp;
00642 roff_t *fmap;
00643 u_int32_t flags;
00644 {
00645 static const FN fn[] = {
00646 { BH_CALLPGIN, "callpgin" },
00647 { BH_DIRTY, "dirty" },
00648 { BH_DIRTY_CREATE, "created" },
00649 { BH_DISCARD, "discard" },
00650 { BH_LOCKED, "locked" },
00651 { BH_TRASH, "trash" },
00652 { 0, NULL }
00653 };
00654 DB_MSGBUF mb;
00655 int i;
00656
00657 DB_MSGBUF_INIT(&mb);
00658
00659 for (i = 0; i < FMAP_ENTRIES; ++i)
00660 if (fmap[i] == INVALID_ROFF || fmap[i] == bhp->mf_offset)
00661 break;
00662
00663 if (fmap[i] == INVALID_ROFF)
00664 __db_msgadd(dbenv, &mb, "\t%5lu, %lu, ",
00665 (u_long)bhp->pgno, (u_long)bhp->mf_offset);
00666 else
00667 __db_msgadd(
00668 dbenv, &mb, "\t%5lu, #%d, ", (u_long)bhp->pgno, i + 1);
00669
00670 __db_msgadd(dbenv, &mb, "%2lu, %lu/%lu, ", (u_long)bhp->ref,
00671 (u_long)LSN(bhp->buf).file, (u_long)LSN(bhp->buf).offset);
00672 __mutex_print_debug_stats(dbenv, &mb, bhp->mtx_bh, flags);
00673 __db_msgadd(dbenv, &mb, ", %#08lx, %lu",
00674 (u_long)R_OFFSET(dbmp->reginfo, bhp), (u_long)bhp->priority);
00675 __db_prflags(dbenv, &mb, bhp->flags, fn, " (", ")");
00676 DB_MSGBUF_FLUSH(dbenv, &mb);
00677 }
00678
00679
00680
00681
00682
00683 static void
00684 __memp_stat_wait(dbenv, reginfo, mp, mstat, flags)
00685 DB_ENV *dbenv;
00686 REGINFO *reginfo;
00687 MPOOL *mp;
00688 DB_MPOOL_STAT *mstat;
00689 u_int32_t flags;
00690 {
00691 DB_MPOOL_HASH *hp;
00692 u_int32_t i, tmp_nowait, tmp_wait;
00693
00694 mstat->st_hash_max_wait = 0;
00695 hp = R_ADDR(reginfo, mp->htab);
00696 for (i = 0; i < mp->htab_buckets; i++, hp++) {
00697 __mutex_set_wait_info(
00698 dbenv, hp->mtx_hash, &tmp_wait, &tmp_nowait);
00699 mstat->st_hash_nowait += tmp_nowait;
00700 mstat->st_hash_wait += tmp_wait;
00701 if (tmp_wait > mstat->st_hash_max_wait)
00702 mstat->st_hash_max_wait = tmp_wait;
00703
00704 if (LF_ISSET(DB_STAT_CLEAR))
00705 __mutex_clear(dbenv, hp->mtx_hash);
00706 }
00707 }
00708
00709 #else
00710
00711 int
00712 __memp_stat_pp(dbenv, gspp, fspp, flags)
00713 DB_ENV *dbenv;
00714 DB_MPOOL_STAT **gspp;
00715 DB_MPOOL_FSTAT ***fspp;
00716 u_int32_t flags;
00717 {
00718 COMPQUIET(gspp, NULL);
00719 COMPQUIET(fspp, NULL);
00720 COMPQUIET(flags, 0);
00721
00722 return (__db_stat_not_built(dbenv));
00723 }
00724
00725 int
00726 __memp_stat_print_pp(dbenv, flags)
00727 DB_ENV *dbenv;
00728 u_int32_t flags;
00729 {
00730 COMPQUIET(flags, 0);
00731
00732 return (__db_stat_not_built(dbenv));
00733 }
00734 #endif
00735
00736
00737
00738
00739
00740
00741
00742 void
00743 __memp_stat_hash(reginfo, mp, dirtyp)
00744 REGINFO *reginfo;
00745 MPOOL *mp;
00746 u_int32_t *dirtyp;
00747 {
00748 DB_MPOOL_HASH *hp;
00749 u_int32_t dirty, i;
00750
00751 hp = R_ADDR(reginfo, mp->htab);
00752 for (i = 0, dirty = 0; i < mp->htab_buckets; i++, hp++)
00753 dirty += hp->hash_page_dirty;
00754 *dirtyp = dirty;
00755 }