1d54cfbdroberto/*
2047f369cy * Copyright (C) 2004-2012  Internet Systems Consortium, Inc. ("ISC")
3d54cfbdroberto * Copyright (C) 1997-2001  Internet Software Consortium.
4d54cfbdroberto *
5d54cfbdroberto * Permission to use, copy, modify, and/or distribute this software for any
6d54cfbdroberto * purpose with or without fee is hereby granted, provided that the above
7d54cfbdroberto * copyright notice and this permission notice appear in all copies.
8d54cfbdroberto *
9d54cfbdroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10d54cfbdroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11d54cfbdroberto * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12d54cfbdroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13d54cfbdroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14d54cfbdroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15d54cfbdroberto * PERFORMANCE OF THIS SOFTWARE.
16d54cfbdroberto */
17d54cfbdroberto
18047f369cy/* $Id$ */
19d54cfbdroberto
20d54cfbdroberto#ifndef ISC_MEM_H
21d54cfbdroberto#define ISC_MEM_H 1
22d54cfbdroberto
23d54cfbdroberto/*! \file isc/mem.h */
24d54cfbdroberto
25d54cfbdroberto#include <stdio.h>
26d54cfbdroberto
27d54cfbdroberto#include <isc/lang.h>
28d54cfbdroberto#include <isc/mutex.h>
29d54cfbdroberto#include <isc/platform.h>
30d54cfbdroberto#include <isc/types.h>
31d54cfbdroberto#include <isc/xml.h>
32d54cfbdroberto
33d54cfbdrobertoISC_LANG_BEGINDECLS
34d54cfbdroberto
35d54cfbdroberto#define ISC_MEM_LOWATER 0
36d54cfbdroberto#define ISC_MEM_HIWATER 1
37d54cfbdrobertotypedef void (*isc_mem_water_t)(void *, int);
38d54cfbdroberto
39d54cfbdrobertotypedef void * (*isc_memalloc_t)(void *, size_t);
40d54cfbdrobertotypedef void (*isc_memfree_t)(void *, void *);
41d54cfbdroberto
42d54cfbdroberto/*%
43d54cfbdroberto * Define ISC_MEM_DEBUG=1 to make all functions that free memory
44d54cfbdroberto * set the pointer being freed to NULL after being freed.
45d54cfbdroberto * This is the default; set ISC_MEM_DEBUG=0 to disable it.
46d54cfbdroberto */
47d54cfbdroberto#ifndef ISC_MEM_DEBUG
48d54cfbdroberto#define ISC_MEM_DEBUG 1
49d54cfbdroberto#endif
50d54cfbdroberto
51d54cfbdroberto/*%
52d54cfbdroberto * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory
53d54cfbdroberto * allocation and freeing by file and line number.
54d54cfbdroberto */
55d54cfbdroberto#ifndef ISC_MEM_TRACKLINES
56d54cfbdroberto#define ISC_MEM_TRACKLINES 1
57d54cfbdroberto#endif
58d54cfbdroberto
59d54cfbdroberto/*%
60d54cfbdroberto * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside
61d54cfbdroberto * the requested space.  This will increase the size of each allocation.
62d54cfbdroberto */
63d54cfbdroberto#ifndef ISC_MEM_CHECKOVERRUN
64d54cfbdroberto#define ISC_MEM_CHECKOVERRUN 1
65d54cfbdroberto#endif
66d54cfbdroberto
67d54cfbdroberto/*%
68d54cfbdroberto * Define ISC_MEM_FILL=1 to fill each block of memory returned to the system
69d54cfbdroberto * with the byte string '0xbe'.  This helps track down uninitialized pointers
70d54cfbdroberto * and the like.  On freeing memory, the space is filled with '0xde' for
71d54cfbdroberto * the same reasons.
72d54cfbdroberto */
73d54cfbdroberto#ifndef ISC_MEM_FILL
74d54cfbdroberto#define ISC_MEM_FILL 1
75d54cfbdroberto#endif
76d54cfbdroberto
77d54cfbdroberto/*%
78d54cfbdroberto * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic
79d54cfbdroberto * name so that the leaking pool can be more readily identified in
80d54cfbdroberto * case of a memory leak.
81d54cfbdroberto */
82d54cfbdroberto#ifndef ISC_MEMPOOL_NAMES
83d54cfbdroberto#define ISC_MEMPOOL_NAMES 1
84d54cfbdroberto#endif
85d54cfbdroberto
86d54cfbdrobertoLIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging;
87d54cfbdroberto/*@{*/
88d54cfbdroberto#define ISC_MEM_DEBUGTRACE		0x00000001U
89d54cfbdroberto#define ISC_MEM_DEBUGRECORD		0x00000002U
90d54cfbdroberto#define ISC_MEM_DEBUGUSAGE		0x00000004U
91d54cfbdroberto#define ISC_MEM_DEBUGSIZE		0x00000008U
92d54cfbdroberto#define ISC_MEM_DEBUGCTX		0x00000010U
93d54cfbdroberto#define ISC_MEM_DEBUGALL		0x0000001FU
94d54cfbdroberto/*!<
95d54cfbdroberto * The variable isc_mem_debugging holds a set of flags for
96d54cfbdroberto * turning certain memory debugging options on or off at
97d54cfbdroberto * runtime.  It is initialized to the value ISC_MEM_DEGBUGGING,
98d54cfbdroberto * which is 0 by default but may be overridden at compile time.
99d54cfbdroberto * The following flags can be specified:
100d54cfbdroberto *
101d54cfbdroberto * \li #ISC_MEM_DEBUGTRACE
102d54cfbdroberto *	Log each allocation and free to isc_lctx.
103d54cfbdroberto *
104d54cfbdroberto * \li #ISC_MEM_DEBUGRECORD
105d54cfbdroberto *	Remember each allocation, and match them up on free.
106d54cfbdroberto *	Crash if a free doesn't match an allocation.
107d54cfbdroberto *
108d54cfbdroberto * \li #ISC_MEM_DEBUGUSAGE
109d54cfbdroberto *	If a hi_water mark is set, print the maximum inuse memory
110d54cfbdroberto *	every time it is raised once it exceeds the hi_water mark.
111d54cfbdroberto *
112d54cfbdroberto * \li #ISC_MEM_DEBUGSIZE
113d54cfbdroberto *	Check the size argument being passed to isc_mem_put() matches
114d54cfbdroberto *	that passed to isc_mem_get().
115d54cfbdroberto *
116d54cfbdroberto * \li #ISC_MEM_DEBUGCTX
117d54cfbdroberto *	Check the mctx argument being passed to isc_mem_put() matches
118d54cfbdroberto *	that passed to isc_mem_get().
119d54cfbdroberto */
120d54cfbdroberto/*@}*/
121d54cfbdroberto
122d54cfbdroberto#if ISC_MEM_TRACKLINES
123d54cfbdroberto#define _ISC_MEM_FILELINE	, __FILE__, __LINE__
124047f369cy#define _ISC_MEM_FLARG		, const char *, unsigned int
125d54cfbdroberto#else
126d54cfbdroberto#define _ISC_MEM_FILELINE
127d54cfbdroberto#define _ISC_MEM_FLARG
128d54cfbdroberto#endif
129d54cfbdroberto
130d54cfbdroberto/*!
131d54cfbdroberto * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc()
132d54cfbdroberto * implementation in preference to the system one.  The internal malloc()
133d54cfbdroberto * is very space-efficient, and quite fast on uniprocessor systems.  It
134d54cfbdroberto * performs poorly on multiprocessor machines.
135d54cfbdroberto * JT: we can overcome the performance issue on multiprocessor machines
136d54cfbdroberto * by carefully separating memory contexts.
137d54cfbdroberto */
138d54cfbdroberto
139d54cfbdroberto#ifndef ISC_MEM_USE_INTERNAL_MALLOC
140d54cfbdroberto#define ISC_MEM_USE_INTERNAL_MALLOC 1
141d54cfbdroberto#endif
142d54cfbdroberto
143d54cfbdroberto/*
144d54cfbdroberto * Flags for isc_mem_create2()calls.
145d54cfbdroberto */
146d54cfbdroberto#define ISC_MEMFLAG_NOLOCK	0x00000001	 /* no lock is necessary */
147d54cfbdroberto#define ISC_MEMFLAG_INTERNAL	0x00000002	 /* use internal malloc */
148d54cfbdroberto#if ISC_MEM_USE_INTERNAL_MALLOC
149d54cfbdroberto#define ISC_MEMFLAG_DEFAULT 	ISC_MEMFLAG_INTERNAL
150d54cfbdroberto#else
151d54cfbdroberto#define ISC_MEMFLAG_DEFAULT 	0
152d54cfbdroberto#endif
153d54cfbdroberto
154d54cfbdroberto
155047f369cy/*%<
156047f369cy * We use either isc___mem (three underscores) or isc__mem (two) depending on
157047f369cy * whether it's for BIND9's internal purpose (with -DBIND9) or generic export
158047f369cy * library.  This condition is generally handled in isc/namespace.h, but for
159047f369cy * Windows it doesn't work if it involves multiple times of macro expansion
160047f369cy * (such as isc_mem to isc__mem then to isc___mem).  The following definitions
161047f369cy * are used to work around this portability issue.  Right now, we don't support
162047f369cy * the export library for Windows, so we always use the three-underscore
163047f369cy * version.
164047f369cy */
165047f369cy#ifdef WIN32
166047f369cy#define ISCMEMFUNC(sfx) isc___mem_ ## sfx
167047f369cy#define ISCMEMPOOLFUNC(sfx) isc___mempool_ ## sfx
168047f369cy#else
169047f369cy#define ISCMEMFUNC(sfx) isc__mem_ ## sfx
170047f369cy#define ISCMEMPOOLFUNC(sfx) isc__mempool_ ## sfx
171047f369cy#endif
172047f369cy
173047f369cy#define isc_mem_get(c, s)	ISCMEMFUNC(get)((c), (s) _ISC_MEM_FILELINE)
174047f369cy#define isc_mem_allocate(c, s)	ISCMEMFUNC(allocate)((c), (s) _ISC_MEM_FILELINE)
175047f369cy#define isc_mem_reallocate(c, p, s) ISCMEMFUNC(reallocate)((c), (p), (s) _ISC_MEM_FILELINE)
176047f369cy#define isc_mem_strdup(c, p)	ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE)
177047f369cy#define isc_mempool_get(c)	ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE)
178d54cfbdroberto
179d54cfbdroberto/*%
180d54cfbdroberto * isc_mem_putanddetach() is a convenience function for use where you
181d54cfbdroberto * have a structure with an attached memory context.
182d54cfbdroberto *
183d54cfbdroberto * Given:
184d54cfbdroberto *
185d54cfbdroberto * \code
186d54cfbdroberto * struct {
187d54cfbdroberto *	...
188d54cfbdroberto *	isc_mem_t *mctx;
189d54cfbdroberto *	...
190d54cfbdroberto * } *ptr;
191d54cfbdroberto *
192d54cfbdroberto * isc_mem_t *mctx;
193d54cfbdroberto *
194d54cfbdroberto * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr));
195d54cfbdroberto * \endcode
196d54cfbdroberto *
197d54cfbdroberto * is the equivalent of:
198d54cfbdroberto *
199d54cfbdroberto * \code
200d54cfbdroberto * mctx = NULL;
201d54cfbdroberto * isc_mem_attach(ptr->mctx, &mctx);
202d54cfbdroberto * isc_mem_detach(&ptr->mctx);
203d54cfbdroberto * isc_mem_put(mctx, ptr, sizeof(*ptr));
204d54cfbdroberto * isc_mem_detach(&mctx);
205d54cfbdroberto * \endcode
206d54cfbdroberto */
207d54cfbdroberto
208047f369cy/*% memory and memory pool methods */
209047f369cytypedef struct isc_memmethods {
210047f369cy	void (*attach)(isc_mem_t *source, isc_mem_t **targetp);
211047f369cy	void (*detach)(isc_mem_t **mctxp);
212047f369cy	void (*destroy)(isc_mem_t **mctxp);
213047f369cy	void *(*memget)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
214047f369cy	void (*memput)(isc_mem_t *mctx, void *ptr, size_t size _ISC_MEM_FLARG);
215047f369cy	void (*memputanddetach)(isc_mem_t **mctxp, void *ptr,
216047f369cy				size_t size _ISC_MEM_FLARG);
217047f369cy	void *(*memallocate)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
218047f369cy	void *(*memreallocate)(isc_mem_t *mctx, void *ptr,
219047f369cy			       size_t size _ISC_MEM_FLARG);
220047f369cy	char *(*memstrdup)(isc_mem_t *mctx, const char *s _ISC_MEM_FLARG);
221047f369cy	void (*memfree)(isc_mem_t *mctx, void *ptr _ISC_MEM_FLARG);
222047f369cy	void (*setdestroycheck)(isc_mem_t *mctx, isc_boolean_t flag);
223047f369cy	void (*setwater)(isc_mem_t *ctx, isc_mem_water_t water,
224047f369cy			 void *water_arg, size_t hiwater, size_t lowater);
225047f369cy	void (*waterack)(isc_mem_t *ctx, int flag);
226047f369cy	size_t (*inuse)(isc_mem_t *mctx);
227047f369cy	isc_boolean_t (*isovermem)(isc_mem_t *mctx);
228047f369cy	isc_result_t (*mpcreate)(isc_mem_t *mctx, size_t size,
229047f369cy				 isc_mempool_t **mpctxp);
230047f369cy} isc_memmethods_t;
231047f369cy
232047f369cytypedef struct isc_mempoolmethods {
233047f369cy	void (*destroy)(isc_mempool_t **mpctxp);
234047f369cy	void *(*get)(isc_mempool_t *mpctx _ISC_MEM_FLARG);
235047f369cy	void (*put)(isc_mempool_t *mpctx, void *mem _ISC_MEM_FLARG);
236047f369cy	unsigned int (*getallocated)(isc_mempool_t *mpctx);
237047f369cy	void (*setmaxalloc)(isc_mempool_t *mpctx, unsigned int limit);
238047f369cy	void (*setfreemax)(isc_mempool_t *mpctx, unsigned int limit);
239047f369cy	void (*setname)(isc_mempool_t *mpctx, const char *name);
240047f369cy	void (*associatelock)(isc_mempool_t *mpctx, isc_mutex_t *lock);
241047f369cy	void (*setfillcount)(isc_mempool_t *mpctx, unsigned int limit);
242047f369cy} isc_mempoolmethods_t;
243047f369cy
244047f369cy/*%
245047f369cy * This structure is actually just the common prefix of a memory context
246047f369cy * implementation's version of an isc_mem_t.
247047f369cy * \brief
248047f369cy * Direct use of this structure by clients is forbidden.  mctx implementations
249047f369cy * may change the structure.  'magic' must be ISCAPI_MCTX_MAGIC for any of the
250047f369cy * isc_mem_ routines to work.  mctx implementations must maintain all mctx
251047f369cy * invariants.
252047f369cy */
253047f369cystruct isc_mem {
254047f369cy	unsigned int		impmagic;
255047f369cy	unsigned int		magic;
256047f369cy	isc_memmethods_t	*methods;
257047f369cy};
258047f369cy
259047f369cy#define ISCAPI_MCTX_MAGIC	ISC_MAGIC('A','m','c','x')
260047f369cy#define ISCAPI_MCTX_VALID(m)	((m) != NULL && \
261047f369cy				 (m)->magic == ISCAPI_MCTX_MAGIC)
262047f369cy
263047f369cy/*%
264047f369cy * This is the common prefix of a memory pool context.  The same note as
265047f369cy * that for the mem structure applies.
266047f369cy */
267047f369cystruct isc_mempool {
268047f369cy	unsigned int		impmagic;
269047f369cy	unsigned int		magic;
270047f369cy	isc_mempoolmethods_t	*methods;
271047f369cy};
272047f369cy
273047f369cy#define ISCAPI_MPOOL_MAGIC	ISC_MAGIC('A','m','p','l')
274047f369cy#define ISCAPI_MPOOL_VALID(mp)	((mp) != NULL && \
275047f369cy				 (mp)->magic == ISCAPI_MPOOL_MAGIC)
276047f369cy
277d54cfbdroberto#if ISC_MEM_DEBUG
278d54cfbdroberto#define isc_mem_put(c, p, s) \
279d54cfbdroberto	do { \
280047f369cy		ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE);	\
281d54cfbdroberto		(p) = NULL; \
282d54cfbdroberto	} while (0)
283d54cfbdroberto#define isc_mem_putanddetach(c, p, s) \
284d54cfbdroberto	do { \
285047f369cy		ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE); \
286d54cfbdroberto		(p) = NULL; \
287d54cfbdroberto	} while (0)
288d54cfbdroberto#define isc_mem_free(c, p) \
289d54cfbdroberto	do { \
290047f369cy		ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE);	\
291d54cfbdroberto		(p) = NULL; \
292d54cfbdroberto	} while (0)
293d54cfbdroberto#define isc_mempool_put(c, p) \
294d54cfbdroberto	do { \
295047f369cy		ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE);	\
296d54cfbdroberto		(p) = NULL; \
297d54cfbdroberto	} while (0)
298d54cfbdroberto#else
299047f369cy#define isc_mem_put(c, p, s)	ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE)
300d54cfbdroberto#define isc_mem_putanddetach(c, p, s) \
301047f369cy	ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE)
302047f369cy#define isc_mem_free(c, p)	ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE)
303047f369cy#define isc_mempool_put(c, p)	ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE)
304d54cfbdroberto#endif
305d54cfbdroberto
306d54cfbdroberto/*@{*/
307d54cfbdrobertoisc_result_t
308d54cfbdrobertoisc_mem_create(size_t max_size, size_t target_size,
309d54cfbdroberto	       isc_mem_t **mctxp);
310d54cfbdroberto
311d54cfbdrobertoisc_result_t
312d54cfbdrobertoisc_mem_create2(size_t max_size, size_t target_size,
313d54cfbdroberto		isc_mem_t **mctxp, unsigned int flags);
314d54cfbdroberto
315d54cfbdrobertoisc_result_t
316d54cfbdrobertoisc_mem_createx(size_t max_size, size_t target_size,
317d54cfbdroberto		isc_memalloc_t memalloc, isc_memfree_t memfree,
318d54cfbdroberto		void *arg, isc_mem_t **mctxp);
319d54cfbdroberto
320d54cfbdrobertoisc_result_t
321d54cfbdrobertoisc_mem_createx2(size_t max_size, size_t target_size,
322d54cfbdroberto		 isc_memalloc_t memalloc, isc_memfree_t memfree,
323d54cfbdroberto		 void *arg, isc_mem_t **mctxp, unsigned int flags);
324d54cfbdroberto
325d54cfbdroberto/*!<
326d54cfbdroberto * \brief Create a memory context.
327d54cfbdroberto *
328d54cfbdroberto * 'max_size' and 'target_size' are tuning parameters.  When
329d54cfbdroberto * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size'
330d54cfbdroberto * will be satisfied by getting blocks of size 'target_size' from the
331d54cfbdroberto * system allocator and breaking them up into pieces; larger allocations
332d54cfbdroberto * will use the system allocator directly. If 'max_size' and/or
333d54cfbdroberto * 'target_size' are zero, default values will be * used.  When
334d54cfbdroberto * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored.
335d54cfbdroberto *
336d54cfbdroberto * 'max_size' is also used to size the statistics arrays and the array
337047f369cy * used to record active memory when ISC_MEM_DEBUGRECORD is set.  Setting
338d54cfbdroberto * 'max_size' too low can have detrimental effects on performance.
339d54cfbdroberto *
340d54cfbdroberto * A memory context created using isc_mem_createx() will obtain
341d54cfbdroberto * memory from the system by calling 'memalloc' and 'memfree',
342d54cfbdroberto * passing them the argument 'arg'.  A memory context created
343d54cfbdroberto * using isc_mem_create() will use the standard library malloc()
344d54cfbdroberto * and free().
345d54cfbdroberto *
346d54cfbdroberto * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context
347d54cfbdroberto * will be accessed without locking.  The user who creates the context must
348d54cfbdroberto * ensure there be no race.  Since this can be a source of bug, it is generally
349d54cfbdroberto * inadvisable to use this flag unless the user is very sure about the race
350d54cfbdroberto * condition and the access to the object is highly performance sensitive.
351d54cfbdroberto *
352d54cfbdroberto * Requires:
353d54cfbdroberto * mctxp != NULL && *mctxp == NULL */
354d54cfbdroberto/*@}*/
355d54cfbdroberto
356d54cfbdroberto/*@{*/
357d54cfbdrobertovoid
358d54cfbdrobertoisc_mem_attach(isc_mem_t *, isc_mem_t **);
359d54cfbdrobertovoid
360d54cfbdrobertoisc_mem_detach(isc_mem_t **);
361d54cfbdroberto/*!<
362d54cfbdroberto * \brief Attach to / detach from a memory context.
363d54cfbdroberto *
364d54cfbdroberto * This is intended for applications that use multiple memory contexts
365d54cfbdroberto * in such a way that it is not obvious when the last allocations from
366d54cfbdroberto * a given context has been freed and destroying the context is safe.
367d54cfbdroberto *
368d54cfbdroberto * Most applications do not need to call these functions as they can
369d54cfbdroberto * simply create a single memory context at the beginning of main()
370d54cfbdroberto * and destroy it at the end of main(), thereby guaranteeing that it
371d54cfbdroberto * is not destroyed while there are outstanding allocations.
372d54cfbdroberto */
373d54cfbdroberto/*@}*/
374d54cfbdroberto
375d54cfbdrobertovoid
376d54cfbdrobertoisc_mem_destroy(isc_mem_t **);
377d54cfbdroberto/*%<
378d54cfbdroberto * Destroy a memory context.
379d54cfbdroberto */
380d54cfbdroberto
381d54cfbdrobertoisc_result_t
382d54cfbdrobertoisc_mem_ondestroy(isc_mem_t *ctx,
383d54cfbdroberto		  isc_task_t *task,
384d54cfbdroberto		  isc_event_t **event);
385d54cfbdroberto/*%<
386d54cfbdroberto * Request to be notified with an event when a memory context has
387d54cfbdroberto * been successfully destroyed.
388d54cfbdroberto */
389d54cfbdroberto
390d54cfbdrobertovoid
391d54cfbdrobertoisc_mem_stats(isc_mem_t *mctx, FILE *out);
392d54cfbdroberto/*%<
393d54cfbdroberto * Print memory usage statistics for 'mctx' on the stream 'out'.
394d54cfbdroberto */
395d54cfbdroberto
396d54cfbdrobertovoid
397d54cfbdrobertoisc_mem_setdestroycheck(isc_mem_t *mctx,
398d54cfbdroberto			isc_boolean_t on);
399d54cfbdroberto/*%<
400d54cfbdroberto * If 'on' is ISC_TRUE, 'mctx' will check for memory leaks when
401d54cfbdroberto * destroyed and abort the program if any are present.
402d54cfbdroberto */
403d54cfbdroberto
404d54cfbdroberto/*@{*/
405d54cfbdrobertovoid
406d54cfbdrobertoisc_mem_setquota(isc_mem_t *, size_t);
407d54cfbdrobertosize_t
408d54cfbdrobertoisc_mem_getquota(isc_mem_t *);
409d54cfbdroberto/*%<
410d54cfbdroberto * Set/get the memory quota of 'mctx'.  This is a hard limit
411d54cfbdroberto * on the amount of memory that may be allocated from mctx;
412d54cfbdroberto * if it is exceeded, allocations will fail.
413d54cfbdroberto */
414d54cfbdroberto/*@}*/
415d54cfbdroberto
416d54cfbdrobertosize_t
417d54cfbdrobertoisc_mem_inuse(isc_mem_t *mctx);
418d54cfbdroberto/*%<
419d54cfbdroberto * Get an estimate of the number of memory in use in 'mctx', in bytes.
420d54cfbdroberto * This includes quantization overhead, but does not include memory
421d54cfbdroberto * allocated from the system but not yet used.
422d54cfbdroberto */
423d54cfbdroberto
424047f369cyisc_boolean_t
425047f369cyisc_mem_isovermem(isc_mem_t *mctx);
426047f369cy/*%<
427047f369cy * Return true iff the memory context is in "over memory" state, i.e.,
428047f369cy * a hiwater mark has been set and the used amount of memory has exceeds
429047f369cy * the mark.
430047f369cy */
431047f369cy
432d54cfbdrobertovoid
433d54cfbdrobertoisc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg,
434d54cfbdroberto		 size_t hiwater, size_t lowater);
435d54cfbdroberto/*%<
436d54cfbdroberto * Set high and low water marks for this memory context.
437d54cfbdroberto *
438d54cfbdroberto * When the memory usage of 'mctx' exceeds 'hiwater',
439d54cfbdroberto * '(water)(water_arg, #ISC_MEM_HIWATER)' will be called.  'water' needs to
440d54cfbdroberto * call isc_mem_waterack() with #ISC_MEM_HIWATER to acknowledge the state
441d54cfbdroberto * change.  'water' may be called multiple times.
442d54cfbdroberto *
443d54cfbdroberto * When the usage drops below 'lowater', 'water' will again be called, this
444d54cfbdroberto * time with #ISC_MEM_LOWATER.  'water' need to calls isc_mem_waterack() with
445d54cfbdroberto * #ISC_MEM_LOWATER to acknowledge the change.
446d54cfbdroberto *
447d54cfbdroberto *	static void
448d54cfbdroberto *	water(void *arg, int mark) {
449d54cfbdroberto *		struct foo *foo = arg;
450d54cfbdroberto *
451d54cfbdroberto *		LOCK(&foo->marklock);
452d54cfbdroberto *		if (foo->mark != mark) {
453d54cfbdroberto * 			foo->mark = mark;
454d54cfbdroberto *			....
455d54cfbdroberto *			isc_mem_waterack(foo->mctx, mark);
456d54cfbdroberto *		}
457d54cfbdroberto *		UNLOCK(&foo->marklock);
458d54cfbdroberto *	}
459d54cfbdroberto *
460d54cfbdroberto * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are
461d54cfbdroberto * ignored and the state is reset.
462d54cfbdroberto *
463d54cfbdroberto * Requires:
464d54cfbdroberto *
465d54cfbdroberto *	'water' is not NULL.
466d54cfbdroberto *	hi_water >= lo_water
467d54cfbdroberto */
468d54cfbdroberto
469d54cfbdrobertovoid
470d54cfbdrobertoisc_mem_waterack(isc_mem_t *ctx, int mark);
471d54cfbdroberto/*%<
472d54cfbdroberto * Called to acknowledge changes in signaled by calls to 'water'.
473d54cfbdroberto */
474d54cfbdroberto
475d54cfbdrobertovoid
476d54cfbdrobertoisc_mem_printactive(isc_mem_t *mctx, FILE *file);
477d54cfbdroberto/*%<
478d54cfbdroberto * Print to 'file' all active memory in 'mctx'.
479d54cfbdroberto *
480d54cfbdroberto * Requires ISC_MEM_DEBUGRECORD to have been set.
481d54cfbdroberto */
482d54cfbdroberto
483d54cfbdrobertovoid
484d54cfbdrobertoisc_mem_printallactive(FILE *file);
485d54cfbdroberto/*%<
486d54cfbdroberto * Print to 'file' all active memory in all contexts.
487d54cfbdroberto *
488d54cfbdroberto * Requires ISC_MEM_DEBUGRECORD to have been set.
489d54cfbdroberto */
490d54cfbdroberto
491d54cfbdrobertovoid
492d54cfbdrobertoisc_mem_checkdestroyed(FILE *file);
493d54cfbdroberto/*%<
494d54cfbdroberto * Check that all memory contexts have been destroyed.
495d54cfbdroberto * Prints out those that have not been.
496d54cfbdroberto * Fatally fails if there are still active contexts.
497d54cfbdroberto */
498d54cfbdroberto
499d54cfbdrobertounsigned int
500d54cfbdrobertoisc_mem_references(isc_mem_t *ctx);
501d54cfbdroberto/*%<
502d54cfbdroberto * Return the current reference count.
503d54cfbdroberto */
504d54cfbdroberto
505d54cfbdrobertovoid
506d54cfbdrobertoisc_mem_setname(isc_mem_t *ctx, const char *name, void *tag);
507d54cfbdroberto/*%<
508d54cfbdroberto * Name 'ctx'.
509d54cfbdroberto *
510d54cfbdroberto * Notes:
511d54cfbdroberto *
512d54cfbdroberto *\li	Only the first 15 characters of 'name' will be copied.
513d54cfbdroberto *
514d54cfbdroberto *\li	'tag' is for debugging purposes only.
515d54cfbdroberto *
516d54cfbdroberto * Requires:
517d54cfbdroberto *
518d54cfbdroberto *\li	'ctx' is a valid ctx.
519d54cfbdroberto */
520d54cfbdroberto
521d54cfbdrobertoconst char *
522d54cfbdrobertoisc_mem_getname(isc_mem_t *ctx);
523d54cfbdroberto/*%<
524d54cfbdroberto * Get the name of 'ctx', as previously set using isc_mem_setname().
525d54cfbdroberto *
526d54cfbdroberto * Requires:
527d54cfbdroberto *\li	'ctx' is a valid ctx.
528d54cfbdroberto *
529d54cfbdroberto * Returns:
530d54cfbdroberto *\li	A non-NULL pointer to a null-terminated string.
531d54cfbdroberto * 	If the ctx has not been named, the string is
532d54cfbdroberto * 	empty.
533d54cfbdroberto */
534d54cfbdroberto
535d54cfbdrobertovoid *
536d54cfbdrobertoisc_mem_gettag(isc_mem_t *ctx);
537d54cfbdroberto/*%<
538d54cfbdroberto * Get the tag value for  'task', as previously set using isc_mem_setname().
539d54cfbdroberto *
540d54cfbdroberto * Requires:
541d54cfbdroberto *\li	'ctx' is a valid ctx.
542d54cfbdroberto *
543d54cfbdroberto * Notes:
544d54cfbdroberto *\li	This function is for debugging purposes only.
545d54cfbdroberto *
546d54cfbdroberto * Requires:
547d54cfbdroberto *\li	'ctx' is a valid task.
548d54cfbdroberto */
549d54cfbdroberto
550d54cfbdroberto#ifdef HAVE_LIBXML2
551d54cfbdrobertovoid
552d54cfbdrobertoisc_mem_renderxml(xmlTextWriterPtr writer);
553d54cfbdroberto/*%<
554d54cfbdroberto * Render all contexts' statistics and status in XML for writer.
555d54cfbdroberto */
556d54cfbdroberto#endif /* HAVE_LIBXML2 */
557d54cfbdroberto
558d54cfbdroberto/*
559d54cfbdroberto * Memory pools
560d54cfbdroberto */
561d54cfbdroberto
562d54cfbdrobertoisc_result_t
563d54cfbdrobertoisc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
564d54cfbdroberto/*%<
565d54cfbdroberto * Create a memory pool.
566d54cfbdroberto *
567d54cfbdroberto * Requires:
568d54cfbdroberto *\li	mctx is a valid memory context.
569d54cfbdroberto *\li	size > 0
570d54cfbdroberto *\li	mpctxp != NULL and *mpctxp == NULL
571d54cfbdroberto *
572d54cfbdroberto * Defaults:
573d54cfbdroberto *\li	maxalloc = UINT_MAX
574d54cfbdroberto *\li	freemax = 1
575d54cfbdroberto *\li	fillcount = 1
576d54cfbdroberto *
577d54cfbdroberto * Returns:
578d54cfbdroberto *\li	#ISC_R_NOMEMORY		-- not enough memory to create pool
579d54cfbdroberto *\li	#ISC_R_SUCCESS		-- all is well.
580d54cfbdroberto */
581d54cfbdroberto
582d54cfbdrobertovoid
583d54cfbdrobertoisc_mempool_destroy(isc_mempool_t **mpctxp);
584d54cfbdroberto/*%<
585d54cfbdroberto * Destroy a memory pool.
586d54cfbdroberto *
587d54cfbdroberto * Requires:
588d54cfbdroberto *\li	mpctxp != NULL && *mpctxp is a valid pool.
589d54cfbdroberto *\li	The pool has no un"put" allocations outstanding
590d54cfbdroberto */
591d54cfbdroberto
592d54cfbdrobertovoid
593d54cfbdrobertoisc_mempool_setname(isc_mempool_t *mpctx, const char *name);
594d54cfbdroberto/*%<
595d54cfbdroberto * Associate a name with a memory pool.  At most 15 characters may be used.
596d54cfbdroberto *
597d54cfbdroberto * Requires:
598d54cfbdroberto *\li	mpctx is a valid pool.
599d54cfbdroberto *\li	name != NULL;
600d54cfbdroberto */
601d54cfbdroberto
602d54cfbdrobertovoid
603d54cfbdrobertoisc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
604d54cfbdroberto/*%<
605d54cfbdroberto * Associate a lock with this memory pool.
606d54cfbdroberto *
607d54cfbdroberto * This lock is used when getting or putting items using this memory pool,
608d54cfbdroberto * and it is also used to set or get internal state via the isc_mempool_get*()
609d54cfbdroberto * and isc_mempool_set*() set of functions.
610d54cfbdroberto *
611d54cfbdroberto * Multiple pools can each share a single lock.  For instance, if "manager"
612d54cfbdroberto * type object contained pools for various sizes of events, and each of
613d54cfbdroberto * these pools used a common lock.  Note that this lock must NEVER be used
614d54cfbdroberto * by other than mempool routines once it is given to a pool, since that can
615d54cfbdroberto * easily cause double locking.
616d54cfbdroberto *
617d54cfbdroberto * Requires:
618d54cfbdroberto *
619d54cfbdroberto *\li	mpctpx is a valid pool.
620d54cfbdroberto *
621d54cfbdroberto *\li	lock != NULL.
622d54cfbdroberto *
623d54cfbdroberto *\li	No previous lock is assigned to this pool.
624d54cfbdroberto *
625d54cfbdroberto *\li	The lock is initialized before calling this function via the normal
626d54cfbdroberto *	means of doing that.
627d54cfbdroberto */
628d54cfbdroberto
629d54cfbdroberto/*
630d54cfbdroberto * The following functions get/set various parameters.  Note that due to
631d54cfbdroberto * the unlocked nature of pools these are potentially random values unless
632d54cfbdroberto * the imposed externally provided locking protocols are followed.
633d54cfbdroberto *
634d54cfbdroberto * Also note that the quota limits will not always take immediate effect.
635d54cfbdroberto * For instance, setting "maxalloc" to a number smaller than the currently
636d54cfbdroberto * allocated count is permitted.  New allocations will be refused until
637d54cfbdroberto * the count drops below this threshold.
638d54cfbdroberto *
639d54cfbdroberto * All functions require (in addition to other requirements):
640d54cfbdroberto *	mpctx is a valid memory pool
641d54cfbdroberto */
642d54cfbdroberto
643d54cfbdrobertounsigned int
644d54cfbdrobertoisc_mempool_getfreemax(isc_mempool_t *mpctx);
645d54cfbdroberto/*%<
646d54cfbdroberto * Returns the maximum allowed size of the free list.
647d54cfbdroberto */
648d54cfbdroberto
649d54cfbdrobertovoid
650d54cfbdrobertoisc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
651d54cfbdroberto/*%<
652d54cfbdroberto * Sets the maximum allowed size of the free list.
653d54cfbdroberto */
654d54cfbdroberto
655d54cfbdrobertounsigned int
656d54cfbdrobertoisc_mempool_getfreecount(isc_mempool_t *mpctx);
657d54cfbdroberto/*%<
658d54cfbdroberto * Returns current size of the free list.
659d54cfbdroberto */
660d54cfbdroberto
661d54cfbdrobertounsigned int
662d54cfbdrobertoisc_mempool_getmaxalloc(isc_mempool_t *mpctx);
663d54cfbdroberto/*!<
664d54cfbdroberto * Returns the maximum allowed number of allocations.
665d54cfbdroberto */
666d54cfbdroberto
667d54cfbdrobertovoid
668d54cfbdrobertoisc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
669d54cfbdroberto/*%<
670d54cfbdroberto * Sets the maximum allowed number of allocations.
671d54cfbdroberto *
672d54cfbdroberto * Additional requirements:
673d54cfbdroberto *\li	limit > 0
674d54cfbdroberto */
675d54cfbdroberto
676d54cfbdrobertounsigned int
677d54cfbdrobertoisc_mempool_getallocated(isc_mempool_t *mpctx);
678d54cfbdroberto/*%<
679d54cfbdroberto * Returns the number of items allocated from this pool.
680d54cfbdroberto */
681d54cfbdroberto
682d54cfbdrobertounsigned int
683d54cfbdrobertoisc_mempool_getfillcount(isc_mempool_t *mpctx);
684d54cfbdroberto/*%<
685d54cfbdroberto * Returns the number of items allocated as a block from the parent memory
686d54cfbdroberto * context when the free list is empty.
687d54cfbdroberto */
688d54cfbdroberto
689d54cfbdrobertovoid
690d54cfbdrobertoisc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
691d54cfbdroberto/*%<
692d54cfbdroberto * Sets the fillcount.
693d54cfbdroberto *
694d54cfbdroberto * Additional requirements:
695d54cfbdroberto *\li	limit > 0
696d54cfbdroberto */
697d54cfbdroberto
698d54cfbdroberto
699d54cfbdroberto/*
700d54cfbdroberto * Pseudo-private functions for use via macros.  Do not call directly.
701d54cfbdroberto */
702d54cfbdrobertovoid *
703047f369cyISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG);
704d54cfbdrobertovoid
705047f369cyISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG);
706d54cfbdrobertovoid
707047f369cyISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
708d54cfbdrobertovoid *
709047f369cyISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG);
710d54cfbdrobertovoid *
711047f369cyISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
712d54cfbdrobertovoid
713047f369cyISCMEMFUNC(free)(isc_mem_t *, void * _ISC_MEM_FLARG);
714d54cfbdrobertochar *
715047f369cyISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG);
716d54cfbdrobertovoid *
717047f369cyISCMEMPOOLFUNC(get)(isc_mempool_t * _ISC_MEM_FLARG);
718d54cfbdrobertovoid
719047f369cyISCMEMPOOLFUNC(put)(isc_mempool_t *, void * _ISC_MEM_FLARG);
720047f369cy
721047f369cy#ifdef USE_MEMIMPREGISTER
722047f369cy
723047f369cy/*%<
724047f369cy * See isc_mem_create2() above.
725047f369cy */
726047f369cytypedef isc_result_t
727047f369cy(*isc_memcreatefunc_t)(size_t init_max_size, size_t target_size,
728047f369cy		       isc_mem_t **ctxp, unsigned int flags);
729047f369cy
730047f369cyisc_result_t
731047f369cyisc_mem_register(isc_memcreatefunc_t createfunc);
732047f369cy/*%<
733047f369cy * Register a new memory management implementation and add it to the list of
734047f369cy * supported implementations.  This function must be called when a different
735047f369cy * memory management library is used than the one contained in the ISC library.
736047f369cy */
737047f369cy
738047f369cyisc_result_t
739047f369cyisc__mem_register(void);
740047f369cy/*%<
741047f369cy * A short cut function that specifies the memory management module in the ISC
742047f369cy * library for isc_mem_register().  An application that uses the ISC library
743047f369cy * usually do not have to care about this function: it would call
744047f369cy * isc_lib_register(), which internally calls this function.
745047f369cy */
746047f369cy#endif /* USE_MEMIMPREGISTER */
747d54cfbdroberto
748d54cfbdrobertoISC_LANG_ENDDECLS
749d54cfbdroberto
750d54cfbdroberto#endif /* ISC_MEM_H */
751