Annotation of embedaddon/dhcp/includes/isc-dhcp/mem.h, revision 1.1
1.1 ! misho 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.2 2007-11-16 11:04:11 shane 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>