mp_pr.c
Upload User: qinhanled
Upload Date: 2021-01-17
Package Size: 1452k
Code Size: 8k
Development Platform:

Unix_Linux

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "config.h"
  8. #ifndef lint
  9. static const char sccsid[] = "@(#)mp_pr.c 10.18 (Sleepycat) 11/1/97";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <errno.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <unistd.h>
  18. #endif
  19. #include "db_int.h"
  20. #include "shqueue.h"
  21. #include "db_shash.h"
  22. #include "mp.h"
  23. void __memp_debug __P((DB_MPOOL *, FILE *, int));
  24. static void __memp_pbh __P((FILE *, DB_MPOOL *, BH *, int));
  25. static void __memp_pdbmf __P((FILE *, DB_MPOOLFILE *, int));
  26. static void __memp_pmf __P((FILE *, MPOOLFILE *, int));
  27. static void __memp_pmp __P((FILE *, DB_MPOOL *, MPOOL *, int));
  28. /*
  29.  * memp_stat --
  30.  * Display MPOOL statistics.
  31.  */
  32. int
  33. memp_stat(dbmp, gspp, fspp, db_malloc)
  34. DB_MPOOL *dbmp;
  35. DB_MPOOL_STAT **gspp;
  36. DB_MPOOL_FSTAT ***fspp;
  37. void *(*db_malloc) __P((size_t));
  38. {
  39. DB_MPOOL_FSTAT **tfsp;
  40. MPOOLFILE *mfp;
  41. size_t len, nlen;
  42. char *name;
  43. /* Allocate space for the global statistics. */
  44. if (gspp != NULL) {
  45. *gspp = NULL;
  46. if ((*gspp = db_malloc == NULL ?
  47.     (DB_MPOOL_STAT *)__db_malloc(sizeof(**gspp)) :
  48.     (DB_MPOOL_STAT *)db_malloc(sizeof(**gspp))) == NULL)
  49. return (ENOMEM);
  50. LOCKREGION(dbmp);
  51. /* Copy out the global statistics. */
  52. **gspp = dbmp->mp->stat;
  53. (*gspp)->st_hash_buckets = dbmp->mp->htab_buckets;
  54. (*gspp)->st_region_wait =
  55.     dbmp->mp->rlayout.lock.mutex_set_wait;
  56. (*gspp)->st_region_nowait =
  57.     dbmp->mp->rlayout.lock.mutex_set_nowait;
  58. UNLOCKREGION(dbmp);
  59. }
  60. if (fspp != NULL) {
  61. *fspp = NULL;
  62. LOCKREGION(dbmp);
  63. /* Count the MPOOLFILE structures. */
  64. for (len = 0,
  65.     mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
  66.     mfp != NULL;
  67.     ++len, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile));
  68. UNLOCKREGION(dbmp);
  69. if (len == 0)
  70. return (0);
  71. /* Allocate space for the pointers. */
  72. len = (len + 1) * sizeof(DB_MPOOL_FSTAT *);
  73. if ((*fspp = db_malloc == NULL ?
  74.     (DB_MPOOL_FSTAT **)__db_malloc(len) :
  75.     (DB_MPOOL_FSTAT **)db_malloc(len)) == NULL)
  76. return (ENOMEM);
  77. LOCKREGION(dbmp);
  78. /* Build each individual entry. */
  79. for (tfsp = *fspp,
  80.     mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
  81.     mfp != NULL;
  82.     ++tfsp, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
  83. name = R_ADDR(dbmp, mfp->path_off);
  84. nlen = strlen(name);
  85. len = sizeof(DB_MPOOL_FSTAT) + nlen + 1;
  86. if ((*tfsp = db_malloc == NULL ?
  87.     (DB_MPOOL_FSTAT *)__db_malloc(len) :
  88.     (DB_MPOOL_FSTAT *)db_malloc(len)) == NULL)
  89. return (ENOMEM);
  90. **tfsp = mfp->stat;
  91. (*tfsp)->file_name = (char *)
  92.     (u_int8_t *)*tfsp + sizeof(DB_MPOOL_FSTAT);
  93. memcpy((*tfsp)->file_name, name, nlen + 1);
  94. }
  95. *tfsp = NULL;
  96. UNLOCKREGION(dbmp);
  97. }
  98. return (0);
  99. }
  100. /*
  101.  * __memp_debug --
  102.  * Display MPOOL structures.
  103.  *
  104.  * PUBLIC: void __memp_debug __P((DB_MPOOL *, FILE *, int));
  105.  */
  106. void
  107. __memp_debug(dbmp, fp, data)
  108. DB_MPOOL *dbmp;
  109. FILE *fp;
  110. int data;
  111. {
  112. DB_MPOOLFILE *dbmfp;
  113. u_long cnt;
  114. /* Make it easy to call from the debugger. */
  115. if (fp == NULL)
  116. fp = stderr;
  117. /* Welcome message. */
  118. (void)fprintf(fp, "%snMpool per-process (%lu) statisticsn",
  119.     DB_LINE, (u_long)getpid());
  120. if (data)
  121. (void)fprintf(fp, "    fd: %d; addr %lx; maddr %lxn",
  122.     dbmp->fd, (u_long)dbmp->addr, (u_long)dbmp->maddr);
  123. /* Display the DB_MPOOLFILE structures. */
  124. for (cnt = 0, dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
  125.     dbmfp != NULL; ++cnt, dbmfp = TAILQ_NEXT(dbmfp, q));
  126. (void)fprintf(fp, "%lu process-local filesn", cnt);
  127. for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
  128.     dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q)) {
  129. (void)fprintf(fp, "%sn", dbmfp->path);
  130. __memp_pdbmf(fp, dbmfp, data);
  131. }
  132. /* Switch to global statistics. */
  133. (void)fprintf(fp, "n%snMpool statisticsn", DB_LINE);
  134. /* Display the MPOOL structure. */
  135. __memp_pmp(fp, dbmp, dbmp->mp, data);
  136. /* Flush in case we're debugging. */
  137. (void)fflush(fp);
  138. }
  139. /*
  140.  * __memp_pdbmf --
  141.  * Display a DB_MPOOLFILE structure.
  142.  */
  143. static void
  144. __memp_pdbmf(fp, dbmfp, data)
  145. FILE *fp;
  146. DB_MPOOLFILE *dbmfp;
  147. int data;
  148. {
  149. if (!data)
  150. return;
  151. (void)fprintf(fp, "    fd: %d; %sn",
  152.     dbmfp->fd, F_ISSET(dbmfp, MP_READONLY) ? "readonly" : "read/write");
  153. }
  154. /*
  155.  * __memp_pmp --
  156.  * Display the MPOOL structure.
  157.  */
  158. static void
  159. __memp_pmp(fp, dbmp, mp, data)
  160. FILE *fp;
  161. DB_MPOOL *dbmp;
  162. MPOOL *mp;
  163. int data;
  164. {
  165. BH *bhp;
  166. MPOOLFILE *mfp;
  167. DB_HASHTAB *htabp;
  168. size_t bucket;
  169. int cnt;
  170. const char *sep;
  171. (void)fprintf(fp, "references: %lu; cachesize: %lun",
  172.     (u_long)mp->rlayout.refcnt, (u_long)mp->stat.st_cachesize);
  173. (void)fprintf(fp,
  174.     "    %lu pages createdn", (u_long)mp->stat.st_page_create);
  175. (void)fprintf(fp,
  176.     "    %lu mmap pages returnedn", (u_long)mp->stat.st_map);
  177. (void)fprintf(fp, "    %lu I/O's (%lu read, %lu written)n",
  178.     (u_long)mp->stat.st_page_in + mp->stat.st_page_out,
  179.     (u_long)mp->stat.st_page_in, (u_long)mp->stat.st_page_out);
  180. if (mp->stat.st_cache_hit + mp->stat.st_cache_miss != 0)
  181. (void)fprintf(fp,
  182.     "    %.0f%% cache hit rate (%lu hit, %lu miss)n",
  183.     ((double)mp->stat.st_cache_hit /
  184.     (mp->stat.st_cache_hit + mp->stat.st_cache_miss)) * 100,
  185.     (u_long)mp->stat.st_cache_hit,
  186.     (u_long)mp->stat.st_cache_miss);
  187. /* Display the MPOOLFILE structures. */
  188. for (cnt = 0, mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
  189.     mfp != NULL; ++cnt, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile));
  190. (void)fprintf(fp, "%d total filesn", cnt);
  191. for (cnt = 1, mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
  192.     mfp != NULL; ++cnt, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
  193. (void)fprintf(fp, "file %dn", cnt);
  194. __memp_pmf(fp, mfp, data);
  195. }
  196. if (!data)
  197. return;
  198. /* Display the hash table list of BH's. */
  199. (void)fprintf(fp, "%snHASH table of BH's (%lu buckets):n",
  200.     DB_LINE, (u_long)mp->htab_buckets);
  201. (void)fprintf(fp,
  202.     "longest chain searched %lun", (u_long)mp->stat.st_hash_longest);
  203. (void)fprintf(fp, "average chain searched %lu (total/calls: %lu/%lu)n",
  204.     (u_long)mp->stat.st_hash_examined /
  205.     (mp->stat.st_hash_searches ? mp->stat.st_hash_searches : 1),
  206.     (u_long)mp->stat.st_hash_examined,
  207.     (u_long)mp->stat.st_hash_searches);
  208. for (htabp = dbmp->htab,
  209.     bucket = 0; bucket < mp->htab_buckets; ++htabp, ++bucket) {
  210. if (SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh) != NULL)
  211. (void)fprintf(fp, "%lu:n", (u_long)bucket);
  212. for (bhp = SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh);
  213.     bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh))
  214. __memp_pbh(fp, dbmp, bhp, data);
  215. }
  216. /* Display the LRU list of BH's. */
  217. (void)fprintf(fp, "LRU list of BH's (pgno/offset):");
  218. for (sep = "n    ", bhp = SH_TAILQ_FIRST(&dbmp->mp->bhq, __bh);
  219.     bhp != NULL; sep = ", ", bhp = SH_TAILQ_NEXT(bhp, q, __bh))
  220. (void)fprintf(fp, "%s%lu/%lu", sep,
  221.     (u_long)bhp->pgno, (u_long)R_OFFSET(dbmp, bhp));
  222. (void)fprintf(fp, "n");
  223. }
  224. /*
  225.  * __memp_pmf --
  226.  * Display an MPOOLFILE structure.
  227.  */
  228. static void
  229. __memp_pmf(fp, mfp, data)
  230. FILE *fp;
  231. MPOOLFILE *mfp;
  232. int data;
  233. {
  234. (void)fprintf(fp, "    %lu pages createdn",
  235.     (u_long)mfp->stat.st_page_create);
  236. (void)fprintf(fp, "    %lu I/O's (%lu read, %lu written)n",
  237.     (u_long)mfp->stat.st_page_in + mfp->stat.st_page_out,
  238.     (u_long)mfp->stat.st_page_in, (u_long)mfp->stat.st_page_out);
  239. if (mfp->stat.st_cache_hit + mfp->stat.st_cache_miss != 0)
  240. (void)fprintf(fp,
  241.     "    %.0f%% cache hit rate (%lu hit, %lu miss)n",
  242.     ((double)mfp->stat.st_cache_hit /
  243.     (mfp->stat.st_cache_hit + mfp->stat.st_cache_miss)) * 100,
  244.     (u_long)mfp->stat.st_cache_hit,
  245.     (u_long)mfp->stat.st_cache_miss);
  246. if (!data)
  247. return;
  248. (void)fprintf(fp, "    %d references; %s; pagesize: %lun", mfp->ref,
  249.     mfp->can_mmap ? "mmap" : "read/write",
  250.     (u_long)mfp->stat.st_pagesize);
  251. }
  252. /*
  253.  * __memp_pbh --
  254.  * Display a BH structure.
  255.  */
  256. static void
  257. __memp_pbh(fp, dbmp, bhp, data)
  258. FILE *fp;
  259. DB_MPOOL *dbmp;
  260. BH *bhp;
  261. int data;
  262. {
  263. const char *sep;
  264. if (!data)
  265. return;
  266. (void)fprintf(fp, "    BH @ %lu (mf: %lu): page %lu; ref %lu",
  267.     (u_long)R_OFFSET(dbmp, bhp),
  268.     (u_long)bhp->mf_offset, (u_long)bhp->pgno, (u_long)bhp->ref);
  269. sep = "; ";
  270. if (F_ISSET(bhp, BH_DIRTY)) {
  271. (void)fprintf(fp, "%sdirty", sep);
  272. sep = ", ";
  273. }
  274. if (F_ISSET(bhp, BH_WRITE)) {
  275. (void)fprintf(fp, "%schk_write", sep);
  276. sep = ", ";
  277. }
  278. (void)fprintf(fp, "n");
  279. }