1/* 2 * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17/* $Id: mem_api.c,v 1.8 2010/08/12 21:30:26 jinmei Exp $ */ 18 19#include <config.h> 20 21#include <isc/magic.h> 22#include <isc/mem.h> 23#include <isc/once.h> 24#include <isc/util.h> 25 26#if ISC_MEM_TRACKLINES 27#define FLARG_PASS , file, line 28#define FLARG , const char *file, unsigned int line 29#else 30#define FLARG_PASS 31#define FLARG 32#endif 33 34static isc_mutex_t createlock; 35static isc_once_t once = ISC_ONCE_INIT; 36static isc_memcreatefunc_t mem_createfunc = NULL; 37 38static void 39initialize(void) { 40 RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); 41} 42 43isc_result_t 44isc_mem_register(isc_memcreatefunc_t createfunc) { 45 isc_result_t result = ISC_R_SUCCESS; 46 47 RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); 48 49 LOCK(&createlock); 50 if (mem_createfunc == NULL) 51 mem_createfunc = createfunc; 52 else 53 result = ISC_R_EXISTS; 54 UNLOCK(&createlock); 55 56 return (result); 57} 58 59isc_result_t 60isc_mem_create(size_t init_max_size, size_t target_size, isc_mem_t **mctxp) { 61 isc_result_t result; 62 63 LOCK(&createlock); 64 65 REQUIRE(mem_createfunc != NULL); 66 result = (*mem_createfunc)(init_max_size, target_size, mctxp, 67 ISC_MEMFLAG_DEFAULT); 68 69 UNLOCK(&createlock); 70 71 return (result); 72} 73 74isc_result_t 75isc_mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **mctxp, 76 unsigned int flags) 77{ 78 isc_result_t result; 79 80 LOCK(&createlock); 81 82 REQUIRE(mem_createfunc != NULL); 83 result = (*mem_createfunc)(init_max_size, target_size, mctxp, flags); 84 85 UNLOCK(&createlock); 86 87 return (result); 88} 89 90void 91isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) { 92 REQUIRE(ISCAPI_MCTX_VALID(source)); 93 REQUIRE(targetp != NULL && *targetp == NULL); 94 95 source->methods->attach(source, targetp); 96 97 ENSURE(*targetp == source); 98} 99 100void 101isc_mem_detach(isc_mem_t **mctxp) { 102 REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp)); 103 104 (*mctxp)->methods->detach(mctxp); 105 106 ENSURE(*mctxp == NULL); 107} 108 109void 110isc_mem_destroy(isc_mem_t **mctxp) { 111 REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp)); 112 113 (*mctxp)->methods->destroy(mctxp); 114 115 ENSURE(*mctxp == NULL); 116} 117 118void * 119isc__mem_get(isc_mem_t *mctx, size_t size FLARG) { 120 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 121 122 return (mctx->methods->memget(mctx, size FLARG_PASS)); 123} 124 125void 126isc__mem_put(isc_mem_t *mctx, void *ptr, size_t size FLARG) { 127 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 128 129 mctx->methods->memput(mctx, ptr, size FLARG_PASS); 130} 131 132void 133isc__mem_putanddetach(isc_mem_t **mctxp, void *ptr, size_t size FLARG) { 134 REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp)); 135 136 (*mctxp)->methods->memputanddetach(mctxp, ptr, size FLARG_PASS); 137 138 /* 139 * XXX: We cannot always ensure *mctxp == NULL here 140 * (see lib/isc/mem.c). 141 */ 142} 143 144void * 145isc__mem_allocate(isc_mem_t *mctx, size_t size FLARG) { 146 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 147 148 return (mctx->methods->memallocate(mctx, size FLARG_PASS)); 149} 150 151void * 152isc__mem_reallocate(isc_mem_t *mctx, void *ptr, size_t size FLARG) { 153 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 154 155 return (mctx->methods->memreallocate(mctx, ptr, size FLARG_PASS)); 156} 157 158char * 159isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) { 160 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 161 162 return (mctx->methods->memstrdup(mctx, s FLARG_PASS)); 163} 164 165void 166isc__mem_free(isc_mem_t *mctx, void *ptr FLARG) { 167 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 168 169 mctx->methods->memfree(mctx, ptr FLARG_PASS); 170} 171 172void 173isc_mem_setdestroycheck(isc_mem_t *mctx, isc_boolean_t flag) { 174 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 175 176 mctx->methods->setdestroycheck(mctx, flag); 177} 178 179void 180isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg, 181 size_t hiwater, size_t lowater) 182{ 183 REQUIRE(ISCAPI_MCTX_VALID(ctx)); 184 185 ctx->methods->setwater(ctx, water, water_arg, hiwater, lowater); 186} 187 188void 189isc_mem_waterack(isc_mem_t *ctx, int flag) { 190 REQUIRE(ISCAPI_MCTX_VALID(ctx)); 191 192 ctx->methods->waterack(ctx, flag); 193} 194 195size_t 196isc_mem_inuse(isc_mem_t *mctx) { 197 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 198 199 return (mctx->methods->inuse(mctx)); 200} 201 202isc_boolean_t 203isc_mem_isovermem(isc_mem_t *mctx) { 204 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 205 206 return (mctx->methods->isovermem(mctx)); 207} 208 209void 210isc_mem_setname(isc_mem_t *mctx, const char *name, void *tag) { 211 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 212 213 UNUSED(name); 214 UNUSED(tag); 215 216 return; 217} 218 219const char * 220isc_mem_getname(isc_mem_t *mctx) { 221 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 222 223 return (""); 224} 225 226void * 227isc_mem_gettag(isc_mem_t *mctx) { 228 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 229 230 return (NULL); 231} 232 233isc_result_t 234isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) { 235 REQUIRE(ISCAPI_MCTX_VALID(mctx)); 236 237 return (mctx->methods->mpcreate(mctx, size, mpctxp)); 238} 239 240void 241isc_mempool_destroy(isc_mempool_t **mpctxp) { 242 REQUIRE(mpctxp != NULL && ISCAPI_MPOOL_VALID(*mpctxp)); 243 244 (*mpctxp)->methods->destroy(mpctxp); 245 246 ENSURE(*mpctxp == NULL); 247} 248 249void * 250isc__mempool_get(isc_mempool_t *mpctx FLARG) { 251 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 252 253 return (mpctx->methods->get(mpctx FLARG_PASS)); 254} 255 256void 257isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) { 258 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 259 260 mpctx->methods->put(mpctx, mem FLARG_PASS); 261} 262 263unsigned int 264isc_mempool_getallocated(isc_mempool_t *mpctx) { 265 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 266 267 return (mpctx->methods->getallocated(mpctx)); 268} 269 270void 271isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) { 272 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 273 274 mpctx->methods->setmaxalloc(mpctx, limit); 275} 276 277void 278isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) { 279 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 280 281 mpctx->methods->setfreemax(mpctx, limit); 282} 283 284void 285isc_mempool_setname(isc_mempool_t *mpctx, const char *name) { 286 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 287 288 mpctx->methods->setname(mpctx, name); 289} 290 291void 292isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) { 293 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 294 295 mpctx->methods->associatelock(mpctx, lock); 296} 297 298void 299isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) { 300 REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); 301 302 mpctx->methods->setfillcount(mpctx, limit); 303} 304