lock_stat.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: lock_stat.c,v 11.4 2000/12/08 20:15:31 ubell Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <ctype.h>
  14. #endif
  15. #ifdef HAVE_RPC
  16. #include "db_server.h"
  17. #endif
  18. #include "db_int.h"
  19. #include "db_shash.h"
  20. #include "lock.h"
  21. #ifdef HAVE_RPC
  22. #include "gen_client_ext.h"
  23. #include "rpc_client_ext.h"
  24. #endif
  25. static void __lock_dump_locker __P((DB_LOCKTAB *, DB_LOCKER *, FILE *));
  26. static void __lock_dump_object __P((DB_LOCKTAB *, DB_LOCKOBJ *, FILE *));
  27. static const char *
  28.     __lock_dump_status __P((db_status_t));
  29. /*
  30.  * lock_stat --
  31.  * Return LOCK statistics.
  32.  */
  33. int
  34. lock_stat(dbenv, statp, db_malloc)
  35. DB_ENV *dbenv;
  36. DB_LOCK_STAT **statp;
  37. void *(*db_malloc) __P((size_t));
  38. {
  39. DB_LOCKREGION *region;
  40. DB_LOCKTAB *lt;
  41. DB_LOCK_STAT *stats;
  42. int ret;
  43. #ifdef HAVE_RPC
  44. if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
  45. return (__dbcl_lock_stat(dbenv, statp, db_malloc));
  46. #endif
  47. PANIC_CHECK(dbenv);
  48. ENV_REQUIRES_CONFIG(dbenv, dbenv->lk_handle, DB_INIT_LOCK);
  49. *statp = NULL;
  50. lt = dbenv->lk_handle;
  51. if ((ret = __os_malloc(dbenv, sizeof(*stats), db_malloc, &stats)) != 0)
  52. return (ret);
  53. /* Copy out the global statistics. */
  54. R_LOCK(dbenv, &lt->reginfo);
  55. region = lt->reginfo.primary;
  56. stats->st_lastid = region->id;
  57. stats->st_maxlocks = region->maxlocks;
  58. stats->st_maxlockers = region->maxlockers;
  59. stats->st_maxobjects = region->maxobjects;
  60. stats->st_nmodes = region->nmodes;
  61. stats->st_nlockers = region->nlockers;
  62. stats->st_maxnlockers = region->maxnlockers;
  63. stats->st_nobjects = region->nobjects;
  64. stats->st_maxnobjects = region->maxnobjects;
  65. stats->st_nlocks = region->nlocks;
  66. stats->st_maxnlocks = region->maxnlocks;
  67. stats->st_nconflicts = region->nconflicts;
  68. stats->st_nrequests = region->nrequests;
  69. stats->st_nreleases = region->nreleases;
  70. stats->st_nnowaits = region->nnowaits;
  71. stats->st_ndeadlocks = region->ndeadlocks;
  72. stats->st_region_wait = lt->reginfo.rp->mutex.mutex_set_wait;
  73. stats->st_region_nowait = lt->reginfo.rp->mutex.mutex_set_nowait;
  74. stats->st_regsize = lt->reginfo.rp->size;
  75. R_UNLOCK(dbenv, &lt->reginfo);
  76. *statp = stats;
  77. return (0);
  78. }
  79. #define LOCK_DUMP_CONF 0x001 /* Conflict matrix. */
  80. #define LOCK_DUMP_FREE 0x002 /* Display lock free list. */
  81. #define LOCK_DUMP_LOCKERS 0x004 /* Display lockers. */
  82. #define LOCK_DUMP_MEM 0x008 /* Display region memory. */
  83. #define LOCK_DUMP_OBJECTS 0x010 /* Display objects. */
  84. #define LOCK_DUMP_ALL 0x01f /* Display all. */
  85. /*
  86.  * __lock_dump_region --
  87.  *
  88.  * PUBLIC: void __lock_dump_region __P((DB_ENV *, char *, FILE *));
  89.  */
  90. void
  91. __lock_dump_region(dbenv, area, fp)
  92. DB_ENV *dbenv;
  93. char *area;
  94. FILE *fp;
  95. {
  96. struct __db_lock *lp;
  97. DB_LOCKER *lip;
  98. DB_LOCKOBJ *op;
  99. DB_LOCKREGION *lrp;
  100. DB_LOCKTAB *lt;
  101. u_int32_t flags, i, j;
  102. int label;
  103. /* Make it easy to call from the debugger. */
  104. if (fp == NULL)
  105. fp = stderr;
  106. for (flags = 0; *area != ''; ++area)
  107. switch (*area) {
  108. case 'A':
  109. LF_SET(LOCK_DUMP_ALL);
  110. break;
  111. case 'c':
  112. LF_SET(LOCK_DUMP_CONF);
  113. break;
  114. case 'f':
  115. LF_SET(LOCK_DUMP_FREE);
  116. break;
  117. case 'l':
  118. LF_SET(LOCK_DUMP_LOCKERS);
  119. break;
  120. case 'm':
  121. LF_SET(LOCK_DUMP_MEM);
  122. break;
  123. case 'o':
  124. LF_SET(LOCK_DUMP_OBJECTS);
  125. break;
  126. }
  127. lt = dbenv->lk_handle;
  128. lrp = lt->reginfo.primary;
  129. LOCKREGION(dbenv, lt);
  130. fprintf(fp, "%snLock region parametersn", DB_LINE);
  131. fprintf(fp, "%s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lu, %s: %lun",
  132.     "locker table size", (u_long)lrp->locker_t_size,
  133.     "object table size", (u_long)lrp->object_t_size,
  134.     "obj_off", (u_long)lrp->obj_off,
  135.     "osynch_off", (u_long)lrp->osynch_off,
  136.     "locker_off", (u_long)lrp->locker_off,
  137.     "lsynch_off", (u_long)lrp->lsynch_off,
  138.     "need_dd", (u_long)lrp->need_dd);
  139. if (LF_ISSET(LOCK_DUMP_CONF)) {
  140. fprintf(fp, "n%snConflict matrixn", DB_LINE);
  141. for (i = 0; i < lrp->nmodes; i++) {
  142. for (j = 0; j < lrp->nmodes; j++)
  143. fprintf(fp, "%lut",
  144.     (u_long)lt->conflicts[i * lrp->nmodes + j]);
  145. fprintf(fp, "n");
  146. }
  147. }
  148. if (LF_ISSET(LOCK_DUMP_LOCKERS)) {
  149. fprintf(fp, "%snLocker hash bucketsn", DB_LINE);
  150. for (i = 0; i < lrp->locker_t_size; i++) {
  151. label = 1;
  152. for (lip =
  153.     SH_TAILQ_FIRST(&lt->locker_tab[i], __db_locker);
  154.     lip != NULL;
  155.     lip = SH_TAILQ_NEXT(lip, links, __db_locker)) {
  156. if (label) {
  157. fprintf(fp, "Bucket %lu:n", (u_long)i);
  158. label = 0;
  159. }
  160. __lock_dump_locker(lt, lip, fp);
  161. }
  162. }
  163. }
  164. if (LF_ISSET(LOCK_DUMP_OBJECTS)) {
  165. fprintf(fp, "%snObject hash bucketsn", DB_LINE);
  166. for (i = 0; i < lrp->object_t_size; i++) {
  167. label = 1;
  168. for (op = SH_TAILQ_FIRST(&lt->obj_tab[i], __db_lockobj);
  169.     op != NULL;
  170.     op = SH_TAILQ_NEXT(op, links, __db_lockobj)) {
  171. if (label) {
  172. fprintf(fp, "Bucket %lu:n", (u_long)i);
  173. label = 0;
  174. }
  175. __lock_dump_object(lt, op, fp);
  176. }
  177. }
  178. }
  179. if (LF_ISSET(LOCK_DUMP_FREE)) {
  180. fprintf(fp, "%snLock free listn", DB_LINE);
  181. for (lp = SH_TAILQ_FIRST(&lrp->free_locks, __db_lock);
  182.     lp != NULL;
  183.     lp = SH_TAILQ_NEXT(lp, links, __db_lock))
  184. fprintf(fp, "0x%lx: %lut%lut%st0x%lxn", (u_long)lp,
  185.     (u_long)lp->holder, (u_long)lp->mode,
  186.     __lock_dump_status(lp->status), (u_long)lp->obj);
  187. fprintf(fp, "%snObject free listn", DB_LINE);
  188. for (op = SH_TAILQ_FIRST(&lrp->free_objs, __db_lockobj);
  189.     op != NULL;
  190.     op = SH_TAILQ_NEXT(op, links, __db_lockobj))
  191. fprintf(fp, "0x%lxn", (u_long)op);
  192. fprintf(fp, "%snLocker free listn", DB_LINE);
  193. for (lip = SH_TAILQ_FIRST(&lrp->free_lockers, __db_locker);
  194.     lip != NULL;
  195.     lip = SH_TAILQ_NEXT(lip, links, __db_locker))
  196. fprintf(fp, "0x%lxn", (u_long)lip);
  197. }
  198. if (LF_ISSET(LOCK_DUMP_MEM))
  199. __db_shalloc_dump(lt->reginfo.addr, fp);
  200. UNLOCKREGION(dbenv, lt);
  201. }
  202. static void
  203. __lock_dump_locker(lt, lip, fp)
  204. DB_LOCKTAB *lt;
  205. DB_LOCKER *lip;
  206. FILE *fp;
  207. {
  208. struct __db_lock *lp;
  209. fprintf(fp, "L %lx [%ld]", (u_long)lip->id, (long)lip->dd_id);
  210. fprintf(fp, " %s ", F_ISSET(lip, DB_LOCKER_DELETED) ? "(D)" : "   ");
  211. if ((lp = SH_LIST_FIRST(&lip->heldby, __db_lock)) == NULL)
  212. fprintf(fp, "n");
  213. else
  214. for (; lp != NULL;
  215.     lp = SH_LIST_NEXT(lp, locker_links, __db_lock))
  216. __lock_printlock(lt, lp, 1);
  217. }
  218. static void
  219. __lock_dump_object(lt, op, fp)
  220. DB_LOCKTAB *lt;
  221. DB_LOCKOBJ *op;
  222. FILE *fp;
  223. {
  224. struct __db_lock *lp;
  225. u_int32_t j;
  226. u_int8_t *ptr;
  227. u_int ch;
  228. ptr = SH_DBT_PTR(&op->lockobj);
  229. for (j = 0; j < op->lockobj.size; ptr++, j++) {
  230. ch = *ptr;
  231. fprintf(fp, isprint(ch) ? "%c" : "\%o", ch);
  232. }
  233. fprintf(fp, "n");
  234. fprintf(fp, "H:");
  235. for (lp =
  236.     SH_TAILQ_FIRST(&op->holders, __db_lock);
  237.     lp != NULL;
  238.     lp = SH_TAILQ_NEXT(lp, links, __db_lock))
  239. __lock_printlock(lt, lp, 1);
  240. lp = SH_TAILQ_FIRST(&op->waiters, __db_lock);
  241. if (lp != NULL) {
  242. fprintf(fp, "nW:");
  243. for (; lp != NULL; lp = SH_TAILQ_NEXT(lp, links, __db_lock))
  244. __lock_printlock(lt, lp, 1);
  245. }
  246. }
  247. static const char *
  248. __lock_dump_status(status)
  249. db_status_t status;
  250. {
  251. switch (status) {
  252. case DB_LSTAT_ABORTED:
  253. return ("aborted");
  254. case DB_LSTAT_ERR:
  255. return ("err");
  256. case DB_LSTAT_FREE:
  257. return ("free");
  258. case DB_LSTAT_HELD:
  259. return ("held");
  260. case DB_LSTAT_NOGRANT:
  261. return ("nogrant");
  262. case DB_LSTAT_PENDING:
  263. return ("pending");
  264. case DB_LSTAT_WAITING:
  265. return ("waiting");
  266. }
  267. return ("unknown status");
  268. }