diff options
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/db/mp_trickle.c')
-rw-r--r-- | debian/htdig/htdig-3.2.0b6/db/mp_trickle.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/db/mp_trickle.c b/debian/htdig/htdig-3.2.0b6/db/mp_trickle.c new file mode 100644 index 00000000..61e45f1f --- /dev/null +++ b/debian/htdig/htdig-3.2.0b6/db/mp_trickle.c @@ -0,0 +1,136 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997, 1998, 1999 + * Sleepycat Software. All rights reserved. + */ +#include "db_config.h" + +#ifndef lint +static const char sccsid[] = "@(#)mp_trickle.c 11.3 (Sleepycat) 9/16/99"; +#endif /* not lint */ + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <stdlib.h> +#endif + +#include "db_int.h" +#include "db_shash.h" +#include "mp.h" + +static int CDB___memp_trick __P((DB_ENV *, int, int, int *)); + +/* + * CDB_memp_trickle -- + * Keep a specified percentage of the buffers clean. + */ +int +CDB_memp_trickle(dbenv, pct, nwrotep) + DB_ENV *dbenv; + int pct, *nwrotep; +{ + DB_MPOOL *dbmp; + MPOOL *mp; + u_int32_t i; + int ret; + + PANIC_CHECK(dbenv); + ENV_REQUIRES_CONFIG(dbenv, dbenv->mp_handle, DB_INIT_MPOOL); + + dbmp = dbenv->mp_handle; + mp = dbmp->reginfo.primary; + + if (nwrotep != NULL) + *nwrotep = 0; + + if (pct < 1 || pct > 100) + return (EINVAL); + + R_LOCK(dbenv, &dbmp->reginfo); + + /* Loop through the caches... */ + for (ret = 0, i = 0; i < mp->nc_reg; ++i) + if ((ret = CDB___memp_trick(dbenv, i, pct, nwrotep)) != 0) + break; + + R_UNLOCK(dbenv, &dbmp->reginfo); + return (ret); +} + +/* + * CDB___memp_trick -- + * Trickle a single cache. + */ +static int +CDB___memp_trick(dbenv, ncache, pct, nwrotep) + DB_ENV *dbenv; + int ncache, pct, *nwrotep; +{ + BH *bhp; + DB_MPOOL *dbmp; + MCACHE *mc; + MPOOLFILE *mfp; + db_pgno_t pgno; + u_long total; + int ret, wrote; + + dbmp = dbenv->mp_handle; + mc = dbmp->c_reginfo[ncache].primary; + + /* + * If there are sufficient clean buffers, or no buffers or no dirty + * buffers, we're done. + * + * XXX + * Using st_page_clean and st_page_dirty is our only choice at the + * moment, but it's not as correct as we might like in the presence + * of pools with more than one buffer size, as a free 512-byte buffer + * isn't the same as a free 8K buffer. + */ +loop: total = mc->stat.st_page_clean + mc->stat.st_page_dirty; + if (total == 0 || mc->stat.st_page_dirty == 0 || + (mc->stat.st_page_clean * 100) / total >= (u_long)pct) + return (0); + + /* Loop until we write a buffer. */ + for (bhp = SH_TAILQ_FIRST(&mc->bhq, __bh); + bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh)) { + if (bhp->ref != 0 || + !F_ISSET(bhp, BH_DIRTY) || F_ISSET(bhp, BH_LOCKED)) + continue; + + mfp = R_ADDR(&dbmp->reginfo, bhp->mf_offset); + + /* + * We can't write to temporary files -- see the comment in + * mp_bh.c:CDB___memp_bhwrite(). + */ + if (F_ISSET(mfp, MP_TEMP)) + continue; + + pgno = bhp->pgno; + if ((ret = CDB___memp_bhwrite(dbmp, mfp, bhp, NULL, &wrote)) != 0) + return (ret); + + /* + * Any process syncing the shared memory buffer pool had better + * be able to write to any underlying file. Be understanding, + * but firm, on this point. + */ + if (!wrote) { + CDB___db_err(dbenv, "%s: unable to flush page: %lu", + CDB___memp_fns(dbmp, mfp), (u_long)pgno); + return (EPERM); + } + + ++mc->stat.st_page_trickle; + if (nwrotep != NULL) + ++*nwrotep; + goto loop; + } + + return (0); +} |