xref: /NextBSD/contrib/ntp/lib/isc/mem_api.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
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 
34 static isc_mutex_t createlock;
35 static isc_once_t once = ISC_ONCE_INIT;
36 static isc_memcreatefunc_t mem_createfunc = NULL;
37 
38 static void
initialize(void)39 initialize(void) {
40 	RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
41 }
42 
43 isc_result_t
isc_mem_register(isc_memcreatefunc_t createfunc)44 isc_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 
59 isc_result_t
isc_mem_create(size_t init_max_size,size_t target_size,isc_mem_t ** mctxp)60 isc_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 
74 isc_result_t
isc_mem_create2(size_t init_max_size,size_t target_size,isc_mem_t ** mctxp,unsigned int flags)75 isc_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 
90 void
isc_mem_attach(isc_mem_t * source,isc_mem_t ** targetp)91 isc_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 
100 void
isc_mem_detach(isc_mem_t ** mctxp)101 isc_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 
109 void
isc_mem_destroy(isc_mem_t ** mctxp)110 isc_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 
118 void *
isc__mem_get(isc_mem_t * mctx,size_t size FLARG)119 isc__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 
125 void
isc__mem_put(isc_mem_t * mctx,void * ptr,size_t size FLARG)126 isc__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 
132 void
isc__mem_putanddetach(isc_mem_t ** mctxp,void * ptr,size_t size FLARG)133 isc__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 
144 void *
isc__mem_allocate(isc_mem_t * mctx,size_t size FLARG)145 isc__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 
151 void *
isc__mem_reallocate(isc_mem_t * mctx,void * ptr,size_t size FLARG)152 isc__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 
158 char *
isc__mem_strdup(isc_mem_t * mctx,const char * s FLARG)159 isc__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 
165 void
isc__mem_free(isc_mem_t * mctx,void * ptr FLARG)166 isc__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 
172 void
isc_mem_setdestroycheck(isc_mem_t * mctx,isc_boolean_t flag)173 isc_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 
179 void
isc_mem_setwater(isc_mem_t * ctx,isc_mem_water_t water,void * water_arg,size_t hiwater,size_t lowater)180 isc_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 
188 void
isc_mem_waterack(isc_mem_t * ctx,int flag)189 isc_mem_waterack(isc_mem_t *ctx, int flag) {
190 	REQUIRE(ISCAPI_MCTX_VALID(ctx));
191 
192 	ctx->methods->waterack(ctx, flag);
193 }
194 
195 size_t
isc_mem_inuse(isc_mem_t * mctx)196 isc_mem_inuse(isc_mem_t *mctx) {
197 	REQUIRE(ISCAPI_MCTX_VALID(mctx));
198 
199 	return (mctx->methods->inuse(mctx));
200 }
201 
202 isc_boolean_t
isc_mem_isovermem(isc_mem_t * mctx)203 isc_mem_isovermem(isc_mem_t *mctx) {
204 	REQUIRE(ISCAPI_MCTX_VALID(mctx));
205 
206 	return (mctx->methods->isovermem(mctx));
207 }
208 
209 void
isc_mem_setname(isc_mem_t * mctx,const char * name,void * tag)210 isc_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 
219 const char *
isc_mem_getname(isc_mem_t * mctx)220 isc_mem_getname(isc_mem_t *mctx) {
221 	REQUIRE(ISCAPI_MCTX_VALID(mctx));
222 
223 	return ("");
224 }
225 
226 void *
isc_mem_gettag(isc_mem_t * mctx)227 isc_mem_gettag(isc_mem_t *mctx) {
228 	REQUIRE(ISCAPI_MCTX_VALID(mctx));
229 
230 	return (NULL);
231 }
232 
233 isc_result_t
isc_mempool_create(isc_mem_t * mctx,size_t size,isc_mempool_t ** mpctxp)234 isc_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 
240 void
isc_mempool_destroy(isc_mempool_t ** mpctxp)241 isc_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 
249 void *
isc__mempool_get(isc_mempool_t * mpctx FLARG)250 isc__mempool_get(isc_mempool_t *mpctx FLARG) {
251 	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
252 
253 	return (mpctx->methods->get(mpctx FLARG_PASS));
254 }
255 
256 void
isc__mempool_put(isc_mempool_t * mpctx,void * mem FLARG)257 isc__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 
263 unsigned int
isc_mempool_getallocated(isc_mempool_t * mpctx)264 isc_mempool_getallocated(isc_mempool_t *mpctx) {
265 	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
266 
267 	return (mpctx->methods->getallocated(mpctx));
268 }
269 
270 void
isc_mempool_setmaxalloc(isc_mempool_t * mpctx,unsigned int limit)271 isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
272 	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
273 
274 	mpctx->methods->setmaxalloc(mpctx, limit);
275 }
276 
277 void
isc_mempool_setfreemax(isc_mempool_t * mpctx,unsigned int limit)278 isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
279 	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
280 
281 	mpctx->methods->setfreemax(mpctx, limit);
282 }
283 
284 void
isc_mempool_setname(isc_mempool_t * mpctx,const char * name)285 isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
286 	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
287 
288 	mpctx->methods->setname(mpctx, name);
289 }
290 
291 void
isc_mempool_associatelock(isc_mempool_t * mpctx,isc_mutex_t * lock)292 isc_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 
298 void
isc_mempool_setfillcount(isc_mempool_t * mpctx,unsigned int limit)299 isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
300 	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
301 
302 	mpctx->methods->setfillcount(mpctx, limit);
303 }
304