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

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: mp_trickle.c,v 11.12 2000/11/30 00:58:41 ubell Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <stdlib.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 "mp.h"
  21. #ifdef HAVE_RPC
  22. #include "gen_client_ext.h"
  23. #include "rpc_client_ext.h"
  24. #endif
  25. static int __memp_trick __P((DB_ENV *, int, int, int *));
  26. /*
  27.  * memp_trickle --
  28.  * Keep a specified percentage of the buffers clean.
  29.  */
  30. int
  31. memp_trickle(dbenv, pct, nwrotep)
  32. DB_ENV *dbenv;
  33. int pct, *nwrotep;
  34. {
  35. DB_MPOOL *dbmp;
  36. MPOOL *mp;
  37. u_int32_t i;
  38. int ret;
  39. #ifdef HAVE_RPC
  40. if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
  41. return (__dbcl_memp_trickle(dbenv, pct, nwrotep));
  42. #endif
  43. PANIC_CHECK(dbenv);
  44. ENV_REQUIRES_CONFIG(dbenv, dbenv->mp_handle, DB_INIT_MPOOL);
  45. dbmp = dbenv->mp_handle;
  46. mp = dbmp->reginfo[0].primary;
  47. if (nwrotep != NULL)
  48. *nwrotep = 0;
  49. if (pct < 1 || pct > 100)
  50. return (EINVAL);
  51. R_LOCK(dbenv, dbmp->reginfo);
  52. /* Loop through the caches... */
  53. for (ret = 0, i = 0; i < mp->nreg; ++i)
  54. if ((ret = __memp_trick(dbenv, i, pct, nwrotep)) != 0)
  55. break;
  56. R_UNLOCK(dbenv, dbmp->reginfo);
  57. return (ret);
  58. }
  59. /*
  60.  * __memp_trick --
  61.  * Trickle a single cache.
  62.  */
  63. static int
  64. __memp_trick(dbenv, ncache, pct, nwrotep)
  65. DB_ENV *dbenv;
  66. int ncache, pct, *nwrotep;
  67. {
  68. BH *bhp;
  69. DB_MPOOL *dbmp;
  70. MPOOL *c_mp;
  71. MPOOLFILE *mfp;
  72. db_pgno_t pgno;
  73. u_long total;
  74. int ret, wrote;
  75. dbmp = dbenv->mp_handle;
  76. c_mp = dbmp->reginfo[ncache].primary;
  77. /*
  78.  * If there are sufficient clean buffers, or no buffers or no dirty
  79.  * buffers, we're done.
  80.  *
  81.  * XXX
  82.  * Using st_page_clean and st_page_dirty is our only choice at the
  83.  * moment, but it's not as correct as we might like in the presence
  84.  * of pools with more than one buffer size, as a free 512-byte buffer
  85.  * isn't the same as a free 8K buffer.
  86.  */
  87. loop: total = c_mp->stat.st_page_clean + c_mp->stat.st_page_dirty;
  88. if (total == 0 || c_mp->stat.st_page_dirty == 0 ||
  89.     (c_mp->stat.st_page_clean * 100) / total >= (u_long)pct)
  90. return (0);
  91. /* Loop until we write a buffer. */
  92. for (bhp = SH_TAILQ_FIRST(&c_mp->bhq, __bh);
  93.     bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh)) {
  94. if (bhp->ref != 0 ||
  95.     !F_ISSET(bhp, BH_DIRTY) || F_ISSET(bhp, BH_LOCKED))
  96. continue;
  97. mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
  98. /*
  99.  * We can't write to temporary files -- see the comment in
  100.  * mp_bh.c:__memp_bhwrite().
  101.  */
  102. if (F_ISSET(mfp, MP_TEMP))
  103. continue;
  104. pgno = bhp->pgno;
  105. if ((ret = __memp_bhwrite(dbmp, mfp, bhp, NULL, &wrote)) != 0)
  106. return (ret);
  107. /*
  108.  * Any process syncing the shared memory buffer pool had better
  109.  * be able to write to any underlying file.  Be understanding,
  110.  * but firm, on this point.
  111.  */
  112. if (!wrote) {
  113. __db_err(dbenv, "%s: unable to flush page: %lu",
  114.     __memp_fns(dbmp, mfp), (u_long)pgno);
  115. return (EPERM);
  116. }
  117. ++c_mp->stat.st_page_trickle;
  118. if (nwrotep != NULL)
  119. ++*nwrotep;
  120. goto loop;
  121. }
  122. return (0);
  123. }