00001
00002
00003
00004
00005
00006
00007 #include "config.h"
00008
00009 #ifndef lint
00010 static const char revid[] = "$Id: mp__trickle_8c-source.html,v 1.1 2008/06/08 10:20:54 sebdiaz Exp $";
00011 #endif
00012
00013 #ifndef NO_SYSTEM_INCLUDES
00014 #include <sys/types.h>
00015
00016 #include <errno.h>
00017 #include <stdlib.h>
00018 #endif
00019
00020 #ifdef HAVE_RPC
00021 #include "db_server.h"
00022 #endif
00023
00024 #include "db_int.h"
00025 #include "db_shash.h"
00026 #include "mp.h"
00027
00028 #ifdef HAVE_RPC
00029 #include "gen_client_ext.h"
00030 #include "rpc_client_ext.h"
00031 #endif
00032
00033 static int __memp_trick __P((DB_ENV *, int, int, int *));
00034
00035
00036
00037
00038
00039 int
00040 CDB_memp_trickle(dbenv, pct, nwrotep)
00041 DB_ENV *dbenv;
00042 int pct, *nwrotep;
00043 {
00044 DB_MPOOL *dbmp;
00045 MPOOL *mp;
00046 u_int32_t i;
00047 int ret;
00048
00049 #ifdef HAVE_RPC
00050 if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
00051 return (__dbcl_memp_trickle(dbenv, pct, nwrotep));
00052 #endif
00053
00054 PANIC_CHECK(dbenv);
00055 ENV_REQUIRES_CONFIG(dbenv, dbenv->mp_handle, DB_INIT_MPOOL);
00056
00057 dbmp = dbenv->mp_handle;
00058 mp = dbmp->reginfo[0].primary;
00059
00060 if (nwrotep != NULL)
00061 *nwrotep = 0;
00062
00063 if (pct < 1 || pct > 100)
00064 return (EINVAL);
00065
00066 R_LOCK(dbenv, dbmp->reginfo);
00067
00068
00069 for (ret = 0, i = 0; i < mp->nreg; ++i)
00070 if ((ret = __memp_trick(dbenv, i, pct, nwrotep)) != 0)
00071 break;
00072
00073 R_UNLOCK(dbenv, dbmp->reginfo);
00074 return (ret);
00075 }
00076
00077
00078
00079
00080
00081 static int
00082 __memp_trick(dbenv, ncache, pct, nwrotep)
00083 DB_ENV *dbenv;
00084 int ncache, pct, *nwrotep;
00085 {
00086 BH *bhp;
00087 DB_MPOOL *dbmp;
00088 MPOOL *c_mp;
00089 MPOOLFILE *mfp;
00090 db_pgno_t pgno;
00091 u_long total;
00092 int ret, wrote;
00093
00094 dbmp = dbenv->mp_handle;
00095 c_mp = dbmp->reginfo[ncache].primary;
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 loop: total = c_mp->stat.st_page_clean + c_mp->stat.st_page_dirty;
00108 if (total == 0 || c_mp->stat.st_page_dirty == 0 ||
00109 (c_mp->stat.st_page_clean * 100) / total >= (u_long)pct)
00110 return (0);
00111
00112
00113 for (bhp = SH_TAILQ_FIRST(&c_mp->bhq, __bh);
00114 bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh)) {
00115 if (bhp->ref != 0 ||
00116 !F_ISSET(bhp, BH_DIRTY) || F_ISSET(bhp, BH_LOCKED))
00117 continue;
00118
00119 mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
00120
00121
00122
00123
00124
00125 if (F_ISSET(mfp, MP_TEMP))
00126 continue;
00127
00128 pgno = bhp->pgno;
00129 if ((ret = CDB___memp_bhwrite(dbmp, mfp, bhp, NULL, &wrote)) != 0)
00130 return (ret);
00131
00132
00133
00134
00135
00136
00137 if (!wrote) {
00138 CDB___db_err(dbenv, "%s: unable to flush page: %lu",
00139 CDB___memp_fns(dbmp, mfp), (u_long)pgno);
00140 return (EPERM);
00141 }
00142
00143 ++c_mp->stat.st_page_trickle;
00144 if (nwrotep != NULL)
00145 ++*nwrotep;
00146 goto loop;
00147 }
00148
00149 return (0);
00150 }