Return to mem.h CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / includes / isc-dhcp |
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 */