mem.h 11.6 KB
Newer Older
Bob Halley's avatar
update    
Bob Halley committed
1
/*
Brian Wellington's avatar
Brian Wellington committed
2
 * Copyright (C) 1997-2001  Internet Software Consortium.
3
 *
Bob Halley's avatar
update    
Bob Halley committed
4
5
6
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
7
 *
8
9
10
11
12
13
14
15
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Bob Halley's avatar
update    
Bob Halley committed
16
17
 */

18
/* $Id: mem.h,v 1.53 2001/06/27 23:29:29 marka Exp $ */
David Lawrence's avatar
David Lawrence committed
19

20
21
#ifndef ISC_MEM_H
#define ISC_MEM_H 1
Bob Halley's avatar
update    
Bob Halley committed
22
23
24

#include <stdio.h>

Michael Graff's avatar
Michael Graff committed
25
26
27
#include <isc/lang.h>
#include <isc/mutex.h>
#include <isc/types.h>
Bob Halley's avatar
update    
Bob Halley committed
28

Bob Halley's avatar
Bob Halley committed
29
30
ISC_LANG_BEGINDECLS

31
32
33
34
#define ISC_MEM_LOWATER 0
#define ISC_MEM_HIWATER 1
typedef void (*isc_mem_water_t)(void *, int);

35
36
37
typedef void * (*isc_memalloc_t)(void *, size_t);
typedef void (*isc_memfree_t)(void *, void *);

38
/*
39
 * ISC_MEM_DEBUG is enabled by default; set ISC_MEM_DEBUG=0 to disable it.
40
 */
41
42
#ifndef ISC_MEM_DEBUG
#define ISC_MEM_DEBUG 1
43
#endif
Michael Graff's avatar
Michael Graff committed
44
45

/*
46
 * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory allocation
Michael Graff's avatar
Michael Graff committed
47
48
 * and freeing by file and line number.
 */
49
50
#ifndef ISC_MEM_TRACKLINES
#define ISC_MEM_TRACKLINES 0
Michael Graff's avatar
Michael Graff committed
51
52
53
#endif

/*
54
 * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside
Michael Graff's avatar
Michael Graff committed
55
56
 * the requested space.  This will increase the size of each allocation.
 */
57
58
#ifndef ISC_MEM_CHECKOVERRUN
#define ISC_MEM_CHECKOVERRUN 0
Michael Graff's avatar
Michael Graff committed
59
60
61
62
63
64
65
66
#endif

/*
 * Define ISC_MEM_FILL to fill each block of memory returned to the system
 * with the byte string '0xbe'.  This helps track down uninitialized pointers
 * and the like.  On freeing memory, the space is filled with '0xde' for
 * the same reasons.
 */
67
68
69
#ifndef ISC_MEM_FILL
#define ISC_MEM_FILL 1
#endif
Michael Graff's avatar
Michael Graff committed
70
71
72
73

/*
 * Define this to turn on memory pool names.
 */
74
75
76
#ifndef ISC_MEMPOOL_NAMES
#define ISC_MEMPOOL_NAMES 1
#endif
Michael Graff's avatar
Michael Graff committed
77
78
79
80
81
82
83
84

/*
 * _DEBUGTRACE
 *	log (to isc_lctx) each allocation and free.
 *
 * _DEBUGRECORD
 *	remember each allocation, and match them up on free.  Crash if
 *	a free doesn't match an allocation
85
86
87
 * _DEBUGUSAGE
 *	if a hi_water mark is set print the maximium inuse memory every
 *	time it is raised once it exceeds the hi_water mark
Michael Graff's avatar
Michael Graff committed
88
89
90
91
 */
extern unsigned int isc_mem_debugging;
#define ISC_MEM_DEBUGTRACE		0x00000001U
#define ISC_MEM_DEBUGRECORD		0x00000002U
92
#define ISC_MEM_DEBUGUSAGE		0x00000004U
Michael Graff's avatar
Michael Graff committed
93

94
#if ISC_MEM_TRACKLINES
Michael Graff's avatar
Michael Graff committed
95
96
97
98
99
100
101
102
103
104
105
#define _ISC_MEM_FILELINE	, __FILE__, __LINE__
#define _ISC_MEM_FLARG		, const char *, int
#else
#define _ISC_MEM_FILELINE
#define _ISC_MEM_FLARG
#endif

#define isc_mem_get(c, s)	isc__mem_get((c), (s) _ISC_MEM_FILELINE)
#define isc_mem_allocate(c, s)	isc__mem_allocate((c), (s) _ISC_MEM_FILELINE)
#define isc_mem_strdup(c, p)	isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
#define isc_mempool_get(c)	isc__mempool_get((c) _ISC_MEM_FILELINE)
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * isc_mem_putanddetach() is a convienence function for use where you
 * have a structure with an attached memory context.
 *
 * Given:
 *
 * struct {
 *	...
 *	isc_mem_t *mctx;
 *	...
 * } *ptr;
 *
 * isc_mem_t *mctx;
 *
 * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr));
 *
 * is the equivalent of:
 *
 * mctx = NULL;
 * isc_mem_attach(ptr->mctx, &mctx);
 * isc_mem_detach(&ptr->mctx);
 * isc_mem_put(mctx, ptr, sizeof(*ptr));
 * isc_mem_detach(&mctx);
 */

132
#if ISC_MEM_DEBUG
Michael Graff's avatar
Michael Graff committed
133
134
135
136
137
#define isc_mem_put(c, p, s) \
	do { \
		isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \
		(p) = NULL; \
	} while (0)
138
139
140
141
142
#define isc_mem_putanddetach(c, p, s) \
	do { \
		isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \
		(p) = NULL; \
	} while (0)
Michael Graff's avatar
Michael Graff committed
143
144
145
146
147
148
149
150
151
152
#define isc_mem_free(c, p) \
	do { \
		isc__mem_free((c), (p) _ISC_MEM_FILELINE); \
		(p) = NULL; \
	} while (0)
#define isc_mempool_put(c, p) \
	do { \
		isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
		(p) = NULL; \
	} while (0)
Bob Halley's avatar
update    
Bob Halley committed
153
#else
Michael Graff's avatar
Michael Graff committed
154
#define isc_mem_put(c, p, s)	isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE)
155
156
#define isc_mem_putanddetach(c, p, s) \
	isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE)
Michael Graff's avatar
Michael Graff committed
157
158
159
#define isc_mem_free(c, p)	isc__mem_free((c), (p) _ISC_MEM_FILELINE)
#define isc_mempool_put(c, p)	isc__mempool_put((c), (p) _ISC_MEM_FILELINE)
#endif
Bob Halley's avatar
update    
Bob Halley committed
160

161
162
isc_result_t 
isc_mem_create(size_t max_size, size_t target_size,
163
164
			    isc_mem_t **mctxp);

165
166
isc_result_t 
isc_mem_createx(size_t max_size, size_t target_size,
167
168
169
170
171
			     isc_memalloc_t memalloc, isc_memfree_t memfree,
			     void *arg, isc_mem_t **mctxp);
/*
 * Create a memory context.
 *
172
173
174
175
176
177
178
179
 * 'max_size' and 'target_size' are tuning parameters.  When
 * ISC_MEM_USE_INTERNAL_MALLOC is true, allocations smaller than
 * 'max_size' will be satisfied by getting blocks of size
 * 'target_size' from the system allocator and breaking them up into
 * pieces; larger allocations will use the system allocator directly.
 * If 'max_size' and/or 'target_size' are zero, default values will be
 * used.  When ISC_MEM_USE_INTERNAL_MALLOC is false, 'max_size' and
 * 'target_size' are ignored.
180
181
182
183
184
185
186
187
 *
 * A memory context created using isc_mem_createx() will obtain
 * memory from the system by calling 'memalloc' and 'memfree',
 * passing them the argument 'arg'.  A memory context created
 * using isc_mem_create() will use the standard library malloc()
 * and free().
 *
 * Requires:
188
 * mctxp != NULL && *mctxp == NULL */
189

190
191
192
193
void 
isc_mem_attach(isc_mem_t *, isc_mem_t **);
void 
isc_mem_detach(isc_mem_t **);
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 * Attach to / detach from a memory context.
 *
 * This is intended for applications that use multiple memory contexts
 * in such a way that it is not obvious when the last allocations from
 * a given context has been freed and destroying the context is safe.
 * 
 * Most applications do not need to call these functions as they can
 * simply create a single memory context at the beginning of main()
 * and destroy it at the end of main(), thereby guaranteeing that it
 * is not destroyed while there are outstanding allocations.
 */

207
208
void 
isc_mem_destroy(isc_mem_t **);
209
210
211
212
/*
 * Destroy a memory context.
 */

213
214
isc_result_t 
isc_mem_ondestroy(isc_mem_t *ctx,
215
216
217
218
219
220
221
			       isc_task_t *task,
			       isc_event_t **event);
/*
 * Request to be notified with an event when a memory context has
 * been successfully destroyed.
 */

222
223
void 
isc_mem_stats(isc_mem_t *mctx, FILE *out);
224
225
226
227
/*
 * Print memory usage statistics for 'mctx' on the stream 'out'.
 */

228
229
void 
isc_mem_setdestroycheck(isc_mem_t *mctx,
230
231
232
233
234
235
			     isc_boolean_t on);
/*
 * Iff 'on' is ISC_TRUE, 'mctx' will check for memory leaks when
 * destroyed and abort the program if any are present.
 */

236
237
238
239
void 
isc_mem_setquota(isc_mem_t *, size_t);
size_t 
isc_mem_getquota(isc_mem_t *);
240
241
242
243
244
245
/*
 * Set/get the memory quota of 'mctx'.  This is a hard limit
 * on the amount of memory that may be allocated from mctx;
 * if it is exceeded, allocations will fail.
 */

246
247
size_t 
isc_mem_inuse(isc_mem_t *mctx);
248
249
250
251
252
253
/*
 * Get an estimate of the number of memory in use in 'mctx', in bytes.
 * This includes quantization overhead, but does not include memory
 * allocated from the system but not yet used.
 */

254
255
256
257
258
259
260
261
262
void
isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg,
		 size_t hiwater, size_t lowater);
/*
 * Set high and low water marks for this memory context.  When the memory
 * usage of 'mctx' exceeds 'hiwater', '(water)(water_arg, ISC_MEM_HIWATER)'
 * will be called.  When the usage drops below 'lowater', 'water' will
 * again be called, this time with ISC_MEM_LOWATER.
 *
263
264
265
 * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are
 * ignored and the state is reset.
 *
266
 * Requires:
Andreas Gustafsson's avatar
Andreas Gustafsson committed
267
 *
268
269
 *	'water' is not NULL.
 *	hi_water >= lo_water
270
271
 */

Michael Graff's avatar
Michael Graff committed
272
273
274
/*
 * Memory pools
 */
Michael Graff's avatar
Michael Graff committed
275

Michael Graff's avatar
Michael Graff committed
276
277
isc_result_t
isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
Michael Graff's avatar
Michael Graff committed
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/*
 * Create a memory pool.
 *
 * Requires:
 *	mctx is a valid memory context.
 *	size > 0
 *	mpctxp != NULL and *mpctxp == NULL
 *
 * Defaults:
 *	maxalloc = UINT_MAX
 *	freemax = 1
 *	fillcount = 1
 *
 * Returns:
 *	ISC_R_NOMEMORY		-- not enough memory to create pool
 *	ISC_R_SUCCESS		-- all is well.
 */

Michael Graff's avatar
Michael Graff committed
296
297
void
isc_mempool_destroy(isc_mempool_t **mpctxp);
Michael Graff's avatar
Michael Graff committed
298
299
300
301
/*
 * Destroy a memory pool.
 *
 * Requires:
Michael Graff's avatar
Michael Graff committed
302
 *	mpctxp != NULL && *mpctxp is a valid pool.
Michael Graff's avatar
Michael Graff committed
303
304
305
 *	The pool has no un"put" allocations outstanding
 */

Michael Graff's avatar
Michael Graff committed
306
void
David Lawrence's avatar
David Lawrence committed
307
isc_mempool_setname(isc_mempool_t *mpctx, const char *name);
Michael Graff's avatar
Michael Graff committed
308
309
310
311
312
313
314
315
/*
 * Associate a name with a memory pool.  At most 15 characters may be used.
 *
 * Requires:
 *	mpctx is a valid pool.
 *	name != NULL;
 */

Michael Graff's avatar
Michael Graff committed
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
void
isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
/*
 * Associate a lock with this memory pool.
 *
 * This lock is used when getting or putting items using this memory pool,
 * and it is also used to set or get internal state via the isc_mempool_get*()
 * and isc_mempool_set*() set of functions.
 *
 * Mutiple pools can each share a single lock.  For instance, if "manager"
 * type object contained pools for various sizes of events, and each of
 * these pools used a common lock.  Note that this lock must NEVER be used
 * by other than mempool routines once it is given to a pool, since that can
 * easily cause double locking.
 *
 * Requires:
 *
 *	mpctpx is a valid pool.
 *
 *	lock != NULL.
 *
 *	No previous lock is assigned to this pool.
 *
 *	The lock is initialized before calling this function via the normal
 *	means of doing that.
 */
Michael Graff's avatar
Michael Graff committed
342
343
344
345
346
347
348

/*
 * The following functions get/set various parameters.  Note that due to
 * the unlocked nature of pools these are potentially random values unless
 * the imposed externally provided locking protocols are followed.
 *
 * Also note that the quota limits will not always take immediate effect.
Michael Graff's avatar
Michael Graff committed
349
 * For instance, setting "maxalloc" to a number smaller than the currently
Michael Graff's avatar
Michael Graff committed
350
351
352
353
354
355
356
 * allocated count is permitted.  New allocations will be refused until
 * the count drops below this threshold.
 *
 * All functions require (in addition to other requirements):
 *	mpctx is a valid memory pool
 */

357
358
unsigned int
isc_mempool_getfreemax(isc_mempool_t *mpctx);
Michael Graff's avatar
Michael Graff committed
359
360
361
362
/*
 * Returns the maximum allowed size of the free list.
 */

363
364
void
isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
Michael Graff's avatar
Michael Graff committed
365
366
367
368
/*
 * Sets the maximum allowed size of the free list.
 */

369
370
unsigned int
isc_mempool_getfreecount(isc_mempool_t *mpctx);
Michael Graff's avatar
Michael Graff committed
371
372
373
374
/*
 * Returns current size of the free list.
 */

375
376
unsigned int
isc_mempool_getmaxalloc(isc_mempool_t *mpctx);
Michael Graff's avatar
Michael Graff committed
377
378
379
380
/*
 * Returns the maximum allowed number of allocations.
 */

381
382
void
isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
Michael Graff's avatar
Michael Graff committed
383
384
385
386
387
388
389
/*
 * Sets the maximum allowed number of allocations.
 *
 * Additional requirements:
 *	limit > 0
 */

390
391
unsigned int
isc_mempool_getallocated(isc_mempool_t *mpctx);
Michael Graff's avatar
Michael Graff committed
392
393
394
395
/*
 * Returns the number of items allocated from this pool.
 */

396
397
unsigned int
isc_mempool_getfillcount(isc_mempool_t *mpctx);
Michael Graff's avatar
Michael Graff committed
398
399
400
401
402
/*
 * Returns the number of items allocated as a block from the parent memory
 * context when the free list is empty.
 */

403
404
void
isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
Michael Graff's avatar
Michael Graff committed
405
406
407
408
409
410
/*
 * Sets the fillcount.
 *
 * Additional requirements:
 *	limit > 0
 */
Michael Graff's avatar
Michael Graff committed
411

412
413
414
415

/*
 * Pseudo-private functions for use via macros.  Do not call directly.
 */
416
417
418
419
void *		
isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG);
void 		
isc__mem_putanddetach(isc_mem_t **, void *,
420
				      size_t _ISC_MEM_FLARG);
421
422
423
424
425
426
427
428
429
430
431
432
void 		
isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
void *		
isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG);
void		
isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG);
char *		
isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG);
void *		
isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
void 		
isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
433

Bob Halley's avatar
Bob Halley committed
434
435
ISC_LANG_ENDDECLS

436
#endif /* ISC_MEM_H */