mp_trickle.c

Go to the documentation of this file.
00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00005  *      Sleepycat Software.  All rights reserved.
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 /* not lint */
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  * CDB_memp_trickle --
00037  *      Keep a specified percentage of the buffers clean.
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         /* Loop through the caches... */
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  * __memp_trick --
00079  *      Trickle a single cache.
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          * If there are sufficient clean buffers, or no buffers or no dirty
00099          * buffers, we're done.
00100          *
00101          * XXX
00102          * Using st_page_clean and st_page_dirty is our only choice at the
00103          * moment, but it's not as correct as we might like in the presence
00104          * of pools with more than one buffer size, as a free 512-byte buffer
00105          * isn't the same as a free 8K buffer.
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         /* Loop until we write a buffer. */
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                  * We can't write to temporary files -- see the comment in
00123                  * mp_bh.c:CDB___memp_bhwrite().
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                  * Any process syncing the shared memory buffer pool had better
00134                  * be able to write to any underlying file.  Be understanding,
00135                  * but firm, on this point.
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 }

Generated on Sun Jun 8 10:56:38 2008 for GNUmifluz by  doxygen 1.5.5