1: /*
2: * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
3: * Copyright (C) 1997-2001 Internet Software Consortium.
4: *
5: * Permission to use, copy, modify, and/or distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15: * PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: /* $Id: mem.h,v 1.1.1.1 2012/10/09 09:06:54 misho Exp $ */
19:
20: #ifndef ISC_MEM_H
21: #define ISC_MEM_H 1
22:
23: /*! \file isc/mem.h */
24:
25: #include <stdio.h>
26:
27: #include <isc-dhcp/lang.h>
28: /*#include <isc-dhcp/mutex.h>*/
29: /*#include <isc-dhcp/platform.h>*/
30: #include <isc-dhcp/types.h>
31: /*#include <isc-dhcp/xml.h>*/
32: #include <isc-dhcp/result.h>
33:
34: ISC_LANG_BEGINDECLS
35:
36: #define ISC_MEM_LOWATER 0
37: #define ISC_MEM_HIWATER 1
38: typedef void (*isc_mem_water_t)(void *, int);
39:
40: typedef void * (*isc_memalloc_t)(void *, size_t);
41: typedef void (*isc_memfree_t)(void *, void *);
42:
43: /*%
44: * Define ISC_MEM_DEBUG=1 to make all functions that free memory
45: * set the pointer being freed to NULL after being freed.
46: * This is the default; set ISC_MEM_DEBUG=0 to disable it.
47: */
48: #ifndef ISC_MEM_DEBUG
49: #define ISC_MEM_DEBUG 1
50: #endif
51:
52: /*%
53: * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory
54: * allocation and freeing by file and line number.
55: */
56: #ifndef ISC_MEM_TRACKLINES
57: #define ISC_MEM_TRACKLINES 1
58: #endif
59:
60: /*%
61: * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside
62: * the requested space. This will increase the size of each allocation.
63: */
64: #ifndef ISC_MEM_CHECKOVERRUN
65: #define ISC_MEM_CHECKOVERRUN 1
66: #endif
67:
68: /*%
69: * Define ISC_MEM_FILL=1 to fill each block of memory returned to the system
70: * with the byte string '0xbe'. This helps track down uninitialized pointers
71: * and the like. On freeing memory, the space is filled with '0xde' for
72: * the same reasons.
73: */
74: #ifndef ISC_MEM_FILL
75: #define ISC_MEM_FILL 1
76: #endif
77:
78: /*%
79: * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic
80: * name so that the leaking pool can be more readily identified in
81: * case of a memory leak.
82: */
83: #ifndef ISC_MEMPOOL_NAMES
84: #define ISC_MEMPOOL_NAMES 1
85: #endif
86:
87: extern unsigned int isc_mem_debugging;
88: /*@{*/
89: #define ISC_MEM_DEBUGTRACE 0x00000001U
90: #define ISC_MEM_DEBUGRECORD 0x00000002U
91: #define ISC_MEM_DEBUGUSAGE 0x00000004U
92: #define ISC_MEM_DEBUGSIZE 0x00000008U
93: #define ISC_MEM_DEBUGCTX 0x00000010U
94: #define ISC_MEM_DEBUGALL 0x0000001FU
95: /*!<
96: * The variable isc_mem_debugging holds a set of flags for
97: * turning certain memory debugging options on or off at
98: * runtime. Its is intialized to the value ISC_MEM_DEGBUGGING,
99: * which is 0 by default but may be overridden at compile time.
100: * The following flags can be specified:
101: *
102: * \li #ISC_MEM_DEBUGTRACE
103: * Log each allocation and free to isc_lctx.
104: *
105: * \li #ISC_MEM_DEBUGRECORD
106: * Remember each allocation, and match them up on free.
107: * Crash if a free doesn't match an allocation.
108: *
109: * \li #ISC_MEM_DEBUGUSAGE
110: * If a hi_water mark is set, print the maximium inuse memory
111: * every time it is raised once it exceeds the hi_water mark.
112: *
113: * \li #ISC_MEM_DEBUGSIZE
114: * Check the size argument being passed to isc_mem_put() matches
115: * that passed to isc_mem_get().
116: *
117: * \li #ISC_MEM_DEBUGCTX
118: * Check the mctx argument being passed to isc_mem_put() matches
119: * that passed to isc_mem_get().
120: */
121: /*@}*/
122:
123: #if ISC_MEM_TRACKLINES
124: #define _ISC_MEM_FILELINE , __FILE__, __LINE__
125: #define _ISC_MEM_FLARG , const char *, int
126: #else
127: #define _ISC_MEM_FILELINE
128: #define _ISC_MEM_FLARG
129: #endif
130:
131: /*!
132: * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc()
133: * implementation in preference to the system one. The internal malloc()
134: * is very space-efficient, and quite fast on uniprocessor systems. It
135: * performs poorly on multiprocessor machines.
136: * JT: we can overcome the performance issue on multiprocessor machines
137: * by carefully separating memory contexts.
138: */
139:
140: #ifndef ISC_MEM_USE_INTERNAL_MALLOC
141: #define ISC_MEM_USE_INTERNAL_MALLOC 1
142: #endif
143:
144: /*
145: * Flags for isc_mem_create2()calls.
146: */
147: #define ISC_MEMFLAG_NOLOCK 0x00000001 /* no lock is necessary */
148: #define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */
149: #if ISC_MEM_USE_INTERNAL_MALLOC
150: #define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL
151: #else
152: #define ISC_MEMFLAG_DEFAULT 0
153: #endif
154:
155:
156: #define isc_mem_get(c, s) isc__mem_get((c), (s) _ISC_MEM_FILELINE)
157: #define isc_mem_allocate(c, s) isc__mem_allocate((c), (s) _ISC_MEM_FILELINE)
158: #define isc_mem_strdup(c, p) isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
159: #define isc_mempool_get(c) isc__mempool_get((c) _ISC_MEM_FILELINE)
160:
161: /*%
162: * isc_mem_putanddetach() is a convienence function for use where you
163: * have a structure with an attached memory context.
164: *
165: * Given:
166: *
167: * \code
168: * struct {
169: * ...
170: * isc_mem_t *mctx;
171: * ...
172: * } *ptr;
173: *
174: * isc_mem_t *mctx;
175: *
176: * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr));
177: * \endcode
178: *
179: * is the equivalent of:
180: *
181: * \code
182: * mctx = NULL;
183: * isc_mem_attach(ptr->mctx, &mctx);
184: * isc_mem_detach(&ptr->mctx);
185: * isc_mem_put(mctx, ptr, sizeof(*ptr));
186: * isc_mem_detach(&mctx);
187: * \endcode
188: */
189:
190: #if ISC_MEM_DEBUG
191: #define isc_mem_put(c, p, s) \
192: do { \
193: isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \
194: (p) = NULL; \
195: } while (0)
196: #define isc_mem_putanddetach(c, p, s) \
197: do { \
198: isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \
199: (p) = NULL; \
200: } while (0)
201: #define isc_mem_free(c, p) \
202: do { \
203: isc__mem_free((c), (p) _ISC_MEM_FILELINE); \
204: (p) = NULL; \
205: } while (0)
206: #define isc_mempool_put(c, p) \
207: do { \
208: isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
209: (p) = NULL; \
210: } while (0)
211: #else
212: #define isc_mem_put(c, p, s) isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE)
213: #define isc_mem_putanddetach(c, p, s) \
214: isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE)
215: #define isc_mem_free(c, p) isc__mem_free((c), (p) _ISC_MEM_FILELINE)
216: #define isc_mempool_put(c, p) isc__mempool_put((c), (p) _ISC_MEM_FILELINE)
217: #endif
218:
219: /*@{*/
220: isc_result_t
221: isc_mem_create(size_t max_size, size_t target_size,
222: isc_mem_t **mctxp);
223:
224: isc_result_t
225: isc_mem_create2(size_t max_size, size_t target_size,
226: isc_mem_t **mctxp, unsigned int flags);
227:
228: isc_result_t
229: isc_mem_createx(size_t max_size, size_t target_size,
230: isc_memalloc_t memalloc, isc_memfree_t memfree,
231: void *arg, isc_mem_t **mctxp);
232:
233: isc_result_t
234: isc_mem_createx2(size_t max_size, size_t target_size,
235: isc_memalloc_t memalloc, isc_memfree_t memfree,
236: void *arg, isc_mem_t **mctxp, unsigned int flags);
237:
238: /*!<
239: * \brief Create a memory context.
240: *
241: * 'max_size' and 'target_size' are tuning parameters. When
242: * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size'
243: * will be satisfied by getting blocks of size 'target_size' from the
244: * system allocator and breaking them up into pieces; larger allocations
245: * will use the system allocator directly. If 'max_size' and/or
246: * 'target_size' are zero, default values will be * used. When
247: * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored.
248: *
249: * 'max_size' is also used to size the statistics arrays and the array
250: * used to record active memory when ISC_MEM_DEBUGRECORD is set. Settin
251: * 'max_size' too low can have detrimental effects on performance.
252: *
253: * A memory context created using isc_mem_createx() will obtain
254: * memory from the system by calling 'memalloc' and 'memfree',
255: * passing them the argument 'arg'. A memory context created
256: * using isc_mem_create() will use the standard library malloc()
257: * and free().
258: *
259: * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context
260: * will be accessed without locking. The user who creates the context must
261: * ensure there be no race. Since this can be a source of bug, it is generally
262: * inadvisable to use this flag unless the user is very sure about the race
263: * condition and the access to the object is highly performance sensitive.
264: *
265: * Requires:
266: * mctxp != NULL && *mctxp == NULL */
267: /*@}*/
268:
269: /*@{*/
270: void
271: isc_mem_attach(isc_mem_t *, isc_mem_t **);
272: void
273: isc_mem_detach(isc_mem_t **);
274: /*!<
275: * \brief Attach to / detach from a memory context.
276: *
277: * This is intended for applications that use multiple memory contexts
278: * in such a way that it is not obvious when the last allocations from
279: * a given context has been freed and destroying the context is safe.
280: *
281: * Most applications do not need to call these functions as they can
282: * simply create a single memory context at the beginning of main()
283: * and destroy it at the end of main(), thereby guaranteeing that it
284: * is not destroyed while there are outstanding allocations.
285: */
286: /*@}*/
287:
288: void
289: isc_mem_destroy(isc_mem_t **);
290: /*%<
291: * Destroy a memory context.
292: */
293:
294: isc_result_t
295: isc_mem_ondestroy(isc_mem_t *ctx,
296: isc_task_t *task,
297: isc_event_t **event);
298: /*%<
299: * Request to be notified with an event when a memory context has
300: * been successfully destroyed.
301: */
302:
303: void
304: isc_mem_stats(isc_mem_t *mctx, FILE *out);
305: /*%<
306: * Print memory usage statistics for 'mctx' on the stream 'out'.
307: */
308:
309: void
310: isc_mem_setdestroycheck(isc_mem_t *mctx,
311: isc_boolean_t on);
312: /*%<
313: * If 'on' is ISC_TRUE, 'mctx' will check for memory leaks when
314: * destroyed and abort the program if any are present.
315: */
316:
317: /*@{*/
318: void
319: isc_mem_setquota(isc_mem_t *, size_t);
320: size_t
321: isc_mem_getquota(isc_mem_t *);
322: /*%<
323: * Set/get the memory quota of 'mctx'. This is a hard limit
324: * on the amount of memory that may be allocated from mctx;
325: * if it is exceeded, allocations will fail.
326: */
327: /*@}*/
328:
329: size_t
330: isc_mem_inuse(isc_mem_t *mctx);
331: /*%<
332: * Get an estimate of the number of memory in use in 'mctx', in bytes.
333: * This includes quantization overhead, but does not include memory
334: * allocated from the system but not yet used.
335: */
336:
337: void
338: isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg,
339: size_t hiwater, size_t lowater);
340: /*%<
341: * Set high and low water marks for this memory context.
342: *
343: * When the memory
344: * usage of 'mctx' exceeds 'hiwater', '(water)(water_arg, #ISC_MEM_HIWATER)'
345: * will be called. When the usage drops below 'lowater', 'water' will
346: * again be called, this time with #ISC_MEM_LOWATER.
347: *
348: * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are
349: * ignored and the state is reset.
350: *
351: * Requires:
352: *
353: * 'water' is not NULL.
354: * hi_water >= lo_water
355: */
356:
357: void
358: isc_mem_printactive(isc_mem_t *mctx, FILE *file);
359: /*%<
360: * Print to 'file' all active memory in 'mctx'.
361: *
362: * Requires ISC_MEM_DEBUGRECORD to have been set.
363: */
364:
365: void
366: isc_mem_printallactive(FILE *file);
367: /*%<
368: * Print to 'file' all active memory in all contexts.
369: *
370: * Requires ISC_MEM_DEBUGRECORD to have been set.
371: */
372:
373: void
374: isc_mem_checkdestroyed(FILE *file);
375: /*%<
376: * Check that all memory contexts have been destroyed.
377: * Prints out those that have not been.
378: * Fatally fails if there are still active contexts.
379: */
380:
381: /*
382: * Memory pools
383: */
384:
385: isc_result_t
386: isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
387: /*%<
388: * Create a memory pool.
389: *
390: * Requires:
391: *\li mctx is a valid memory context.
392: *\li size > 0
393: *\li mpctxp != NULL and *mpctxp == NULL
394: *
395: * Defaults:
396: *\li maxalloc = UINT_MAX
397: *\li freemax = 1
398: *\li fillcount = 1
399: *
400: * Returns:
401: *\li #ISC_R_NOMEMORY -- not enough memory to create pool
402: *\li #ISC_R_SUCCESS -- all is well.
403: */
404:
405: void
406: isc_mempool_destroy(isc_mempool_t **mpctxp);
407: /*%<
408: * Destroy a memory pool.
409: *
410: * Requires:
411: *\li mpctxp != NULL && *mpctxp is a valid pool.
412: *\li The pool has no un"put" allocations outstanding
413: */
414:
415: void
416: isc_mempool_setname(isc_mempool_t *mpctx, const char *name);
417: /*%<
418: * Associate a name with a memory pool. At most 15 characters may be used.
419: *
420: * Requires:
421: *\li mpctx is a valid pool.
422: *\li name != NULL;
423: */
424:
425: /*
426: void
427: isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
428: */
429: /*%<
430: * Associate a lock with this memory pool.
431: *
432: * This lock is used when getting or putting items using this memory pool,
433: * and it is also used to set or get internal state via the isc_mempool_get*()
434: * and isc_mempool_set*() set of functions.
435: *
436: * Mutiple pools can each share a single lock. For instance, if "manager"
437: * type object contained pools for various sizes of events, and each of
438: * these pools used a common lock. Note that this lock must NEVER be used
439: * by other than mempool routines once it is given to a pool, since that can
440: * easily cause double locking.
441: *
442: * Requires:
443: *
444: *\li mpctpx is a valid pool.
445: *
446: *\li lock != NULL.
447: *
448: *\li No previous lock is assigned to this pool.
449: *
450: *\li The lock is initialized before calling this function via the normal
451: * means of doing that.
452: */
453:
454: /*
455: * The following functions get/set various parameters. Note that due to
456: * the unlocked nature of pools these are potentially random values unless
457: * the imposed externally provided locking protocols are followed.
458: *
459: * Also note that the quota limits will not always take immediate effect.
460: * For instance, setting "maxalloc" to a number smaller than the currently
461: * allocated count is permitted. New allocations will be refused until
462: * the count drops below this threshold.
463: *
464: * All functions require (in addition to other requirements):
465: * mpctx is a valid memory pool
466: */
467:
468: unsigned int
469: isc_mempool_getfreemax(isc_mempool_t *mpctx);
470: /*%<
471: * Returns the maximum allowed size of the free list.
472: */
473:
474: void
475: isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
476: /*%<
477: * Sets the maximum allowed size of the free list.
478: */
479:
480: unsigned int
481: isc_mempool_getfreecount(isc_mempool_t *mpctx);
482: /*%<
483: * Returns current size of the free list.
484: */
485:
486: unsigned int
487: isc_mempool_getmaxalloc(isc_mempool_t *mpctx);
488: /*!<
489: * Returns the maximum allowed number of allocations.
490: */
491:
492: void
493: isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
494: /*%<
495: * Sets the maximum allowed number of allocations.
496: *
497: * Additional requirements:
498: *\li limit > 0
499: */
500:
501: unsigned int
502: isc_mempool_getallocated(isc_mempool_t *mpctx);
503: /*%<
504: * Returns the number of items allocated from this pool.
505: */
506:
507: unsigned int
508: isc_mempool_getfillcount(isc_mempool_t *mpctx);
509: /*%<
510: * Returns the number of items allocated as a block from the parent memory
511: * context when the free list is empty.
512: */
513:
514: void
515: isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
516: /*%<
517: * Sets the fillcount.
518: *
519: * Additional requirements:
520: *\li limit > 0
521: */
522:
523:
524: /*
525: * Pseudo-private functions for use via macros. Do not call directly.
526: */
527: void *
528: isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG);
529: void
530: isc__mem_putanddetach(isc_mem_t **, void *,
531: size_t _ISC_MEM_FLARG);
532: void
533: isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
534: void *
535: isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG);
536: void
537: isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG);
538: char *
539: isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG);
540: void *
541: isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
542: void
543: isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
544:
545: #ifdef HAVE_LIBXML2
546: void
547: isc_mem_renderxml(isc_mem_t *mgr, xmlTextWriterPtr writer);
548: #endif /* HAVE_LIBXML2 */
549:
550: ISC_LANG_ENDDECLS
551:
552: #endif /* ISC_MEM_H */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>