00001
00002
00003
00004
00005
00006
00007 #include "config.h"
00008
00009 #ifndef lint
00010 static const char revid[] = "$Id: mp__alloc_8c-source.html,v 1.1 2008/06/08 10:20:39 sebdiaz Exp $";
00011 #endif
00012
00013 #ifndef NO_SYSTEM_INCLUDES
00014 #include <sys/types.h>
00015 #endif
00016
00017 #include "db_int.h"
00018 #include "db_shash.h"
00019 #include "mp.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028 int
00029 CDB___memp_alloc(dbmp, memreg, mfp, len, offsetp, retp)
00030 DB_MPOOL *dbmp;
00031 REGINFO *memreg;
00032 MPOOLFILE *mfp;
00033 size_t len;
00034 roff_t *offsetp;
00035 void *retp;
00036 {
00037 BH *bhp, *nbhp;
00038 MPOOL *c_mp;
00039 MPOOLFILE *bh_mfp;
00040 size_t total;
00041 int nomore, restart, ret, wrote;
00042 void *p;
00043
00044 c_mp = memreg->primary;
00045
00046
00047
00048
00049
00050
00051
00052
00053 if (mfp != NULL)
00054 len = (sizeof(BH) - sizeof(u_int8_t)) + mfp->stat.st_pagesize;
00055
00056 nomore = 0;
00057 alloc: if ((ret = CDB___db_shalloc(memreg->addr, len, MUTEX_ALIGN, &p)) == 0) {
00058 if (offsetp != NULL)
00059 *offsetp = R_OFFSET(memreg, p);
00060 *(void **)retp = p;
00061 return (0);
00062 }
00063 if (nomore) {
00064 CDB___db_err(dbmp->dbenv,
00065 "Unable to allocate %lu bytes from mpool shared region: %s\n",
00066 (u_long)len, CDB_db_strerror(ret));
00067 return (ret);
00068 }
00069
00070 retry:
00071 restart = total = 0;
00072 for (bhp =
00073 SH_TAILQ_FIRST(&c_mp->bhq, __bh); bhp != NULL; bhp = nbhp) {
00074 nbhp = SH_TAILQ_NEXT(bhp, q, __bh);
00075
00076
00077 if (bhp->ref != 0 || F_ISSET(bhp, BH_LOCKED))
00078 continue;
00079
00080
00081 bh_mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
00082
00083
00084 if (F_ISSET(bhp, BH_DIRTY)) {
00085 ++bhp->ref;
00086 if ((ret = CDB___memp_bhwrite(dbmp,
00087 bh_mfp, bhp, &restart, &wrote)) != 0)
00088 return (ret);
00089 --bhp->ref;
00090
00091
00092
00093
00094
00095 if (bhp->ref != 0)
00096 goto retry;
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 if (wrote)
00111 ++c_mp->stat.st_rw_evict;
00112 else {
00113 if (restart)
00114 goto retry;
00115 continue;
00116 }
00117 } else
00118 ++c_mp->stat.st_ro_evict;
00119
00120
00121
00122
00123
00124 if (mfp != NULL &&
00125 mfp->stat.st_pagesize == bh_mfp->stat.st_pagesize) {
00126 CDB___memp_bhfree(dbmp, bhp, 0);
00127
00128 if (offsetp != NULL)
00129 *offsetp = R_OFFSET(memreg, bhp);
00130 *(void **)retp = bhp;
00131 return (0);
00132 }
00133
00134
00135 total += CDB___db_shsizeof(bhp);
00136 CDB___memp_bhfree(dbmp, bhp, 1);
00137
00138
00139
00140
00141
00142
00143 if (total >= 3 * len)
00144 goto alloc;
00145
00146
00147 if (restart)
00148 goto retry;
00149 }
00150 nomore = 1;
00151 goto alloc;
00152 }