1290001Sglebius/*
2290001Sglebius * Copyright (C) 2009, 2010  Internet Systems Consortium, Inc. ("ISC")
3290001Sglebius *
4290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any
5290001Sglebius * purpose with or without fee is hereby granted, provided that the above
6290001Sglebius * copyright notice and this permission notice appear in all copies.
7290001Sglebius *
8290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10290001Sglebius * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14290001Sglebius * PERFORMANCE OF THIS SOFTWARE.
15290001Sglebius */
16290001Sglebius
17290001Sglebius/* $Id: mem_api.c,v 1.8 2010/08/12 21:30:26 jinmei Exp $ */
18290001Sglebius
19290001Sglebius#include <config.h>
20290001Sglebius
21290001Sglebius#include <isc/magic.h>
22290001Sglebius#include <isc/mem.h>
23290001Sglebius#include <isc/once.h>
24290001Sglebius#include <isc/util.h>
25290001Sglebius
26290001Sglebius#if ISC_MEM_TRACKLINES
27290001Sglebius#define FLARG_PASS	, file, line
28290001Sglebius#define FLARG		, const char *file, unsigned int line
29290001Sglebius#else
30290001Sglebius#define FLARG_PASS
31290001Sglebius#define FLARG
32290001Sglebius#endif
33290001Sglebius
34290001Sglebiusstatic isc_mutex_t createlock;
35290001Sglebiusstatic isc_once_t once = ISC_ONCE_INIT;
36290001Sglebiusstatic isc_memcreatefunc_t mem_createfunc = NULL;
37290001Sglebius
38290001Sglebiusstatic void
39290001Sglebiusinitialize(void) {
40290001Sglebius	RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
41290001Sglebius}
42290001Sglebius
43290001Sglebiusisc_result_t
44290001Sglebiusisc_mem_register(isc_memcreatefunc_t createfunc) {
45290001Sglebius	isc_result_t result = ISC_R_SUCCESS;
46290001Sglebius
47290001Sglebius	RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
48290001Sglebius
49290001Sglebius	LOCK(&createlock);
50290001Sglebius	if (mem_createfunc == NULL)
51290001Sglebius		mem_createfunc = createfunc;
52290001Sglebius	else
53290001Sglebius		result = ISC_R_EXISTS;
54290001Sglebius	UNLOCK(&createlock);
55290001Sglebius
56290001Sglebius	return (result);
57290001Sglebius}
58290001Sglebius
59290001Sglebiusisc_result_t
60290001Sglebiusisc_mem_create(size_t init_max_size, size_t target_size, isc_mem_t **mctxp) {
61290001Sglebius	isc_result_t result;
62290001Sglebius
63290001Sglebius	LOCK(&createlock);
64290001Sglebius
65290001Sglebius	REQUIRE(mem_createfunc != NULL);
66290001Sglebius	result = (*mem_createfunc)(init_max_size, target_size, mctxp,
67290001Sglebius				   ISC_MEMFLAG_DEFAULT);
68290001Sglebius
69290001Sglebius	UNLOCK(&createlock);
70290001Sglebius
71290001Sglebius	return (result);
72290001Sglebius}
73290001Sglebius
74290001Sglebiusisc_result_t
75290001Sglebiusisc_mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **mctxp,
76290001Sglebius		unsigned int flags)
77290001Sglebius{
78290001Sglebius	isc_result_t result;
79290001Sglebius
80290001Sglebius	LOCK(&createlock);
81290001Sglebius
82290001Sglebius	REQUIRE(mem_createfunc != NULL);
83290001Sglebius	result = (*mem_createfunc)(init_max_size, target_size, mctxp, flags);
84290001Sglebius
85290001Sglebius	UNLOCK(&createlock);
86290001Sglebius
87290001Sglebius	return (result);
88290001Sglebius}
89290001Sglebius
90290001Sglebiusvoid
91290001Sglebiusisc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
92290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(source));
93290001Sglebius	REQUIRE(targetp != NULL && *targetp == NULL);
94290001Sglebius
95290001Sglebius	source->methods->attach(source, targetp);
96290001Sglebius
97290001Sglebius	ENSURE(*targetp == source);
98290001Sglebius}
99290001Sglebius
100290001Sglebiusvoid
101290001Sglebiusisc_mem_detach(isc_mem_t **mctxp) {
102290001Sglebius	REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
103290001Sglebius
104290001Sglebius	(*mctxp)->methods->detach(mctxp);
105290001Sglebius
106290001Sglebius	ENSURE(*mctxp == NULL);
107290001Sglebius}
108290001Sglebius
109290001Sglebiusvoid
110290001Sglebiusisc_mem_destroy(isc_mem_t **mctxp) {
111290001Sglebius	REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
112290001Sglebius
113290001Sglebius	(*mctxp)->methods->destroy(mctxp);
114290001Sglebius
115290001Sglebius	ENSURE(*mctxp == NULL);
116290001Sglebius}
117290001Sglebius
118290001Sglebiusvoid *
119290001Sglebiusisc__mem_get(isc_mem_t *mctx, size_t size FLARG) {
120290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
121290001Sglebius
122290001Sglebius	return (mctx->methods->memget(mctx, size FLARG_PASS));
123290001Sglebius}
124290001Sglebius
125290001Sglebiusvoid
126290001Sglebiusisc__mem_put(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
127290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
128290001Sglebius
129290001Sglebius	mctx->methods->memput(mctx, ptr, size FLARG_PASS);
130290001Sglebius}
131290001Sglebius
132290001Sglebiusvoid
133290001Sglebiusisc__mem_putanddetach(isc_mem_t **mctxp, void *ptr, size_t size FLARG) {
134290001Sglebius	REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
135290001Sglebius
136290001Sglebius	(*mctxp)->methods->memputanddetach(mctxp, ptr, size FLARG_PASS);
137290001Sglebius
138290001Sglebius	/*
139290001Sglebius	 * XXX: We cannot always ensure *mctxp == NULL here
140290001Sglebius	 * (see lib/isc/mem.c).
141290001Sglebius	 */
142290001Sglebius}
143290001Sglebius
144290001Sglebiusvoid *
145290001Sglebiusisc__mem_allocate(isc_mem_t *mctx, size_t size FLARG) {
146290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
147290001Sglebius
148290001Sglebius	return (mctx->methods->memallocate(mctx, size FLARG_PASS));
149290001Sglebius}
150290001Sglebius
151290001Sglebiusvoid *
152290001Sglebiusisc__mem_reallocate(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
153290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
154290001Sglebius
155290001Sglebius	return (mctx->methods->memreallocate(mctx, ptr, size FLARG_PASS));
156290001Sglebius}
157290001Sglebius
158290001Sglebiuschar *
159290001Sglebiusisc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
160290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
161290001Sglebius
162290001Sglebius	return (mctx->methods->memstrdup(mctx, s FLARG_PASS));
163290001Sglebius}
164290001Sglebius
165290001Sglebiusvoid
166290001Sglebiusisc__mem_free(isc_mem_t *mctx, void *ptr FLARG) {
167290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
168290001Sglebius
169290001Sglebius	mctx->methods->memfree(mctx, ptr FLARG_PASS);
170290001Sglebius}
171290001Sglebius
172290001Sglebiusvoid
173290001Sglebiusisc_mem_setdestroycheck(isc_mem_t *mctx, isc_boolean_t flag) {
174290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
175290001Sglebius
176290001Sglebius	mctx->methods->setdestroycheck(mctx, flag);
177290001Sglebius}
178290001Sglebius
179290001Sglebiusvoid
180290001Sglebiusisc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
181290001Sglebius		 size_t hiwater, size_t lowater)
182290001Sglebius{
183290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(ctx));
184290001Sglebius
185290001Sglebius	ctx->methods->setwater(ctx, water, water_arg, hiwater, lowater);
186290001Sglebius}
187290001Sglebius
188290001Sglebiusvoid
189290001Sglebiusisc_mem_waterack(isc_mem_t *ctx, int flag) {
190290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(ctx));
191290001Sglebius
192290001Sglebius	ctx->methods->waterack(ctx, flag);
193290001Sglebius}
194290001Sglebius
195290001Sglebiussize_t
196290001Sglebiusisc_mem_inuse(isc_mem_t *mctx) {
197290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
198290001Sglebius
199290001Sglebius	return (mctx->methods->inuse(mctx));
200290001Sglebius}
201290001Sglebius
202290001Sglebiusisc_boolean_t
203290001Sglebiusisc_mem_isovermem(isc_mem_t *mctx) {
204290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
205290001Sglebius
206290001Sglebius	return (mctx->methods->isovermem(mctx));
207290001Sglebius}
208290001Sglebius
209290001Sglebiusvoid
210290001Sglebiusisc_mem_setname(isc_mem_t *mctx, const char *name, void *tag) {
211290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
212290001Sglebius
213290001Sglebius	UNUSED(name);
214290001Sglebius	UNUSED(tag);
215290001Sglebius
216290001Sglebius	return;
217290001Sglebius}
218290001Sglebius
219290001Sglebiusconst char *
220290001Sglebiusisc_mem_getname(isc_mem_t *mctx) {
221290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
222290001Sglebius
223290001Sglebius	return ("");
224290001Sglebius}
225290001Sglebius
226290001Sglebiusvoid *
227290001Sglebiusisc_mem_gettag(isc_mem_t *mctx) {
228290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
229290001Sglebius
230290001Sglebius	return (NULL);
231290001Sglebius}
232290001Sglebius
233290001Sglebiusisc_result_t
234290001Sglebiusisc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
235290001Sglebius	REQUIRE(ISCAPI_MCTX_VALID(mctx));
236290001Sglebius
237290001Sglebius	return (mctx->methods->mpcreate(mctx, size, mpctxp));
238290001Sglebius}
239290001Sglebius
240290001Sglebiusvoid
241290001Sglebiusisc_mempool_destroy(isc_mempool_t **mpctxp) {
242290001Sglebius	REQUIRE(mpctxp != NULL && ISCAPI_MPOOL_VALID(*mpctxp));
243290001Sglebius
244290001Sglebius	(*mpctxp)->methods->destroy(mpctxp);
245290001Sglebius
246290001Sglebius	ENSURE(*mpctxp == NULL);
247290001Sglebius}
248290001Sglebius
249290001Sglebiusvoid *
250290001Sglebiusisc__mempool_get(isc_mempool_t *mpctx FLARG) {
251290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
252290001Sglebius
253290001Sglebius	return (mpctx->methods->get(mpctx FLARG_PASS));
254290001Sglebius}
255290001Sglebius
256290001Sglebiusvoid
257290001Sglebiusisc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
258290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
259290001Sglebius
260290001Sglebius	mpctx->methods->put(mpctx, mem FLARG_PASS);
261290001Sglebius}
262290001Sglebius
263290001Sglebiusunsigned int
264290001Sglebiusisc_mempool_getallocated(isc_mempool_t *mpctx) {
265290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
266290001Sglebius
267290001Sglebius	return (mpctx->methods->getallocated(mpctx));
268290001Sglebius}
269290001Sglebius
270290001Sglebiusvoid
271290001Sglebiusisc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
272290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
273290001Sglebius
274290001Sglebius	mpctx->methods->setmaxalloc(mpctx, limit);
275290001Sglebius}
276290001Sglebius
277290001Sglebiusvoid
278290001Sglebiusisc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
279290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
280290001Sglebius
281290001Sglebius	mpctx->methods->setfreemax(mpctx, limit);
282290001Sglebius}
283290001Sglebius
284290001Sglebiusvoid
285290001Sglebiusisc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
286290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
287290001Sglebius
288290001Sglebius	mpctx->methods->setname(mpctx, name);
289290001Sglebius}
290290001Sglebius
291290001Sglebiusvoid
292290001Sglebiusisc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
293290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
294290001Sglebius
295290001Sglebius	mpctx->methods->associatelock(mpctx, lock);
296290001Sglebius}
297290001Sglebius
298290001Sglebiusvoid
299290001Sglebiusisc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
300290001Sglebius	REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
301290001Sglebius
302290001Sglebius	mpctx->methods->setfillcount(mpctx, limit);
303290001Sglebius}
304