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