00001
00002
00003
00004
00005
00006
00007 #include "config.h"
00008
00009 #ifndef lint
00010 static const char revid[] = "$Id: mp__region_8c-source.html,v 1.1 2008/06/08 10:20:49 sebdiaz Exp $";
00011 #endif
00012
00013 #ifndef NO_SYSTEM_INCLUDES
00014 #include <sys/types.h>
00015
00016 #include <errno.h>
00017 #include <string.h>
00018 #endif
00019
00020 #include "db_int.h"
00021 #include "db_shash.h"
00022 #include "mp.h"
00023
00024 static int __mpool_init __P((DB_ENV *, DB_MPOOL *, int, int));
00025
00026
00027
00028
00029
00030
00031
00032 int
00033 CDB___memp_open(dbenv)
00034 DB_ENV *dbenv;
00035 {
00036 DB_MPOOL *dbmp;
00037 MPOOL *mp;
00038 REGINFO reginfo;
00039 roff_t reg_size, *regids;
00040 u_int32_t i;
00041 int htab_buckets, ret;
00042
00043
00044 reg_size = dbenv->mp_gbytes / dbenv->mp_ncache;
00045 reg_size += (dbenv->mp_gbytes % dbenv->mp_ncache) / dbenv->mp_ncache;
00046 reg_size += dbenv->mp_bytes / dbenv->mp_ncache;
00047
00048
00049
00050
00051
00052
00053
00054
00055 htab_buckets = CDB___db_tablesize((reg_size / (1 * 1024)) / 10);
00056
00057
00058 if ((ret = CDB___os_calloc(dbenv, 1, sizeof(*dbmp), &dbmp)) != 0)
00059 return (ret);
00060 LIST_INIT(&dbmp->dbregq);
00061 TAILQ_INIT(&dbmp->dbmfq);
00062 dbmp->dbenv = dbenv;
00063
00064
00065 reginfo.id = REG_ID_MPOOL;
00066 reginfo.mode = dbenv->db_mode;
00067 if (F_ISSET(dbenv, DB_ENV_CREATE))
00068 F_SET(®info, REGION_CREATE_OK);
00069 if ((ret = CDB___db_r_attach(dbenv, ®info, reg_size)) != 0)
00070 goto err;
00071
00072
00073
00074
00075
00076 if (F_ISSET(®info, REGION_CREATE)) {
00077
00078
00079
00080
00081
00082 dbmp->nreg = dbenv->mp_ncache;
00083 if ((ret = CDB___os_calloc(dbenv,
00084 dbmp->nreg, sizeof(REGINFO), &dbmp->reginfo)) != 0)
00085 goto err;
00086 for (i = 0; i < dbmp->nreg; ++i)
00087 dbmp->reginfo[i].id = REG_ID_INVALID;
00088 dbmp->reginfo[0] = reginfo;
00089
00090
00091 if ((ret = __mpool_init(dbenv, dbmp, 0, htab_buckets)) != 0)
00092 goto err;
00093
00094
00095
00096
00097
00098 mp = R_ADDR(dbmp->reginfo, dbmp->reginfo[0].rp->primary);
00099 regids = R_ADDR(dbmp->reginfo, mp->regids);
00100 for (i = 1; i < dbmp->nreg; ++i) {
00101 dbmp->reginfo[i].id = REG_ID_INVALID;
00102 dbmp->reginfo[i].mode = dbenv->db_mode;
00103 F_SET(&dbmp->reginfo[i], REGION_CREATE_OK);
00104 if ((ret = CDB___db_r_attach(
00105 dbenv, &dbmp->reginfo[i], reg_size)) != 0)
00106 goto err;
00107 if ((ret =
00108 __mpool_init(dbenv, dbmp, i, htab_buckets)) != 0)
00109 goto err;
00110 R_UNLOCK(dbenv, &dbmp->reginfo[i]);
00111
00112 regids[i] = dbmp->reginfo[i].id;
00113 }
00114 } else {
00115
00116
00117
00118
00119
00120
00121 mp = R_ADDR(®info, reginfo.rp->primary);
00122 dbmp->nreg = mp->nreg;
00123 if ((ret = CDB___os_calloc(dbenv,
00124 dbmp->nreg, sizeof(REGINFO), &dbmp->reginfo)) != 0)
00125 goto err;
00126 for (i = 0; i < dbmp->nreg; ++i)
00127 dbmp->reginfo[i].id = REG_ID_INVALID;
00128 dbmp->reginfo[0] = reginfo;
00129
00130
00131 regids = R_ADDR(dbmp->reginfo, mp->regids);
00132 for (i = 1; i < dbmp->nreg; ++i) {
00133 dbmp->reginfo[i].id = regids[i];
00134 dbmp->reginfo[i].mode = 0;
00135 if ((ret = CDB___db_r_attach(
00136 dbenv, &dbmp->reginfo[i], 0)) != 0)
00137 goto err;
00138 R_UNLOCK(dbenv, &dbmp->reginfo[i]);
00139 }
00140 }
00141
00142
00143 for (i = 0; i < dbmp->nreg; ++i)
00144 dbmp->reginfo[i].primary =
00145 R_ADDR(&dbmp->reginfo[i], dbmp->reginfo[i].rp->primary);
00146
00147 R_UNLOCK(dbenv, dbmp->reginfo);
00148
00149
00150 if (F_ISSET(dbenv, DB_ENV_THREAD)) {
00151 if ((ret = CDB___db_mutex_alloc(
00152 dbenv, dbmp->reginfo, &dbmp->mutexp)) != 0) {
00153 goto err;
00154 }
00155 if ((ret =
00156 __db_mutex_init(dbenv, dbmp->mutexp, 0, MUTEX_THREAD)) != 0)
00157 goto err;
00158 }
00159
00160 dbenv->mp_handle = dbmp;
00161 return (0);
00162
00163 err: if (dbmp->reginfo[0].addr != NULL) {
00164 if (F_ISSET(dbmp->reginfo, REGION_CREATE))
00165 for (i = 0; i < dbmp->nreg; ++i)
00166 if (dbmp->reginfo[i].id != REG_ID_INVALID)
00167 F_SET(dbmp->reginfo[i].rp, REG_DEAD);
00168
00169 R_UNLOCK(dbenv, dbmp->reginfo);
00170
00171 for (i = 0; i < dbmp->nreg; ++i)
00172 if (dbmp->reginfo[i].id != REG_ID_INVALID)
00173 (void)CDB___db_r_detach(
00174 dbenv, &dbmp->reginfo[i], 0);
00175 CDB___os_free(dbmp->reginfo,
00176 dbmp->nreg * sizeof(*dbmp->reginfo));
00177 }
00178 CDB___os_free(dbmp, sizeof(*dbmp));
00179 return (ret);
00180 }
00181
00182
00183
00184
00185
00186 static int
00187 __mpool_init(dbenv, dbmp, reginfo_off, htab_buckets)
00188 DB_ENV *dbenv;
00189 DB_MPOOL *dbmp;
00190 int reginfo_off, htab_buckets;
00191 {
00192 DB_HASHTAB *htab;
00193 MPOOL *mp;
00194 REGINFO *reginfo;
00195 int ret;
00196 void *p;
00197
00198 mp = NULL;
00199
00200 reginfo = &dbmp->reginfo[reginfo_off];
00201 if ((ret = CDB___db_shalloc(reginfo->addr,
00202 sizeof(MPOOL), MUTEX_ALIGN, ®info->primary)) != 0)
00203 goto mem_err;
00204 reginfo->rp->primary = R_OFFSET(reginfo, reginfo->primary);
00205 mp = reginfo->primary;
00206 memset(mp, 0, sizeof(*mp));
00207
00208 if (reginfo_off == 0) {
00209 SH_TAILQ_INIT(&mp->mpfq);
00210
00211 if ((ret = __db_mutex_init(dbenv, &mp->sync_mutex,
00212 R_OFFSET(dbmp->reginfo,
00213 &mp->sync_mutex) + DB_FCNTL_OFF_MPOOL, 0)) != 0)
00214 goto err;
00215
00216 ZERO_LSN(mp->lsn);
00217 mp->lsn_cnt = 0;
00218
00219 mp->nreg = dbmp->nreg;
00220 if ((ret = CDB___db_shalloc(dbmp->reginfo[0].addr,
00221 dbmp->nreg * sizeof(int), 0, &p)) != 0)
00222 goto mem_err;
00223 mp->regids = R_OFFSET(dbmp->reginfo, p);
00224 }
00225
00226 SH_TAILQ_INIT(&mp->bhq);
00227
00228
00229 if ((ret = CDB___db_shalloc(reginfo->addr,
00230 htab_buckets * sizeof(DB_HASHTAB), 0, &htab)) != 0)
00231 goto mem_err;
00232 CDB___db_hashinit(htab, htab_buckets);
00233 mp->htab = R_OFFSET(reginfo, htab);
00234 mp->htab_buckets = htab_buckets;
00235
00236 return (0);
00237
00238 mem_err:CDB___db_err(dbenv, "Unable to allocate memory for mpool region");
00239 err: if (reginfo->primary != NULL)
00240 CDB___db_shalloc_free(reginfo->addr, reginfo->primary);
00241 return (ret);
00242 }
00243
00244
00245
00246
00247
00248
00249
00250 int
00251 CDB___memp_close(dbenv)
00252 DB_ENV *dbenv;
00253 {
00254 DB_MPOOL *dbmp;
00255 DB_MPOOLFILE *dbmfp;
00256 DB_MPREG *mpreg;
00257 u_int32_t i;
00258 int ret, t_ret;
00259
00260 ret = 0;
00261 dbmp = dbenv->mp_handle;
00262
00263
00264 while ((mpreg = LIST_FIRST(&dbmp->dbregq)) != NULL) {
00265 LIST_REMOVE(mpreg, q);
00266 CDB___os_free(mpreg, sizeof(DB_MPREG));
00267 }
00268
00269
00270 while ((dbmfp = TAILQ_FIRST(&dbmp->dbmfq)) != NULL) {
00271 if ((t_ret = CDB_memp_fclose(dbmfp)) != 0 && ret == 0)
00272 ret = t_ret;
00273 }
00274
00275
00276 if (dbmp->mutexp != NULL)
00277 CDB___db_mutex_free(dbenv, dbmp->reginfo, dbmp->mutexp);
00278
00279
00280 for (i = 0; i < dbmp->nreg; ++i)
00281 if ((t_ret = CDB___db_r_detach(
00282 dbenv, &dbmp->reginfo[i], 0)) != 0 && ret == 0)
00283 ret = t_ret;
00284
00285 CDB___os_free(dbmp->reginfo, dbmp->nreg * sizeof(*dbmp->reginfo));
00286 CDB___os_free(dbmp, sizeof(*dbmp));
00287
00288 dbenv->mp_handle = NULL;
00289 return (ret);
00290 }