diff options
Diffstat (limited to 'lib/isc/include/isc/mem.h')
-rw-r--r-- | lib/isc/include/isc/mem.h | 175 |
1 files changed, 148 insertions, 27 deletions
diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index 480a934078ed..5101ea3fed1c 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mem.h,v 1.78.120.3 2009/02/11 03:07:01 jinmei Exp $ */ +/* $Id$ */ #ifndef ISC_MEM_H #define ISC_MEM_H 1 @@ -121,7 +121,7 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging; #if ISC_MEM_TRACKLINES #define _ISC_MEM_FILELINE , __FILE__, __LINE__ -#define _ISC_MEM_FLARG , const char *, int +#define _ISC_MEM_FLARG , const char *, unsigned int #else #define _ISC_MEM_FILELINE #define _ISC_MEM_FLARG @@ -152,11 +152,29 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging; #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_reallocate(c, p, s) isc__mem_reallocate((c), (p), (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) +/*%< + * We use either isc___mem (three underscores) or isc__mem (two) depending on + * whether it's for BIND9's internal purpose (with -DBIND9) or generic export + * library. This condition is generally handled in isc/namespace.h, but for + * Windows it doesn't work if it involves multiple times of macro expansion + * (such as isc_mem to isc__mem then to isc___mem). The following definitions + * are used to work around this portability issue. Right now, we don't support + * the export library for Windows, so we always use the three-underscore + * version. + */ +#ifdef WIN32 +#define ISCMEMFUNC(sfx) isc___mem_ ## sfx +#define ISCMEMPOOLFUNC(sfx) isc___mempool_ ## sfx +#else +#define ISCMEMFUNC(sfx) isc__mem_ ## sfx +#define ISCMEMPOOLFUNC(sfx) isc__mempool_ ## sfx +#endif + +#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s) _ISC_MEM_FILELINE) +#define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s) _ISC_MEM_FILELINE) +#define isc_mem_reallocate(c, p, s) ISCMEMFUNC(reallocate)((c), (p), (s) _ISC_MEM_FILELINE) +#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE) +#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE) /*% * isc_mem_putanddetach() is a convenience function for use where you @@ -187,33 +205,102 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging; * \endcode */ +/*% memory and memory pool methods */ +typedef struct isc_memmethods { + void (*attach)(isc_mem_t *source, isc_mem_t **targetp); + void (*detach)(isc_mem_t **mctxp); + void (*destroy)(isc_mem_t **mctxp); + void *(*memget)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG); + void (*memput)(isc_mem_t *mctx, void *ptr, size_t size _ISC_MEM_FLARG); + void (*memputanddetach)(isc_mem_t **mctxp, void *ptr, + size_t size _ISC_MEM_FLARG); + void *(*memallocate)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG); + void *(*memreallocate)(isc_mem_t *mctx, void *ptr, + size_t size _ISC_MEM_FLARG); + char *(*memstrdup)(isc_mem_t *mctx, const char *s _ISC_MEM_FLARG); + void (*memfree)(isc_mem_t *mctx, void *ptr _ISC_MEM_FLARG); + void (*setdestroycheck)(isc_mem_t *mctx, isc_boolean_t flag); + void (*setwater)(isc_mem_t *ctx, isc_mem_water_t water, + void *water_arg, size_t hiwater, size_t lowater); + void (*waterack)(isc_mem_t *ctx, int flag); + size_t (*inuse)(isc_mem_t *mctx); + isc_boolean_t (*isovermem)(isc_mem_t *mctx); + isc_result_t (*mpcreate)(isc_mem_t *mctx, size_t size, + isc_mempool_t **mpctxp); +} isc_memmethods_t; + +typedef struct isc_mempoolmethods { + void (*destroy)(isc_mempool_t **mpctxp); + void *(*get)(isc_mempool_t *mpctx _ISC_MEM_FLARG); + void (*put)(isc_mempool_t *mpctx, void *mem _ISC_MEM_FLARG); + unsigned int (*getallocated)(isc_mempool_t *mpctx); + void (*setmaxalloc)(isc_mempool_t *mpctx, unsigned int limit); + void (*setfreemax)(isc_mempool_t *mpctx, unsigned int limit); + void (*setname)(isc_mempool_t *mpctx, const char *name); + void (*associatelock)(isc_mempool_t *mpctx, isc_mutex_t *lock); + void (*setfillcount)(isc_mempool_t *mpctx, unsigned int limit); +} isc_mempoolmethods_t; + +/*% + * This structure is actually just the common prefix of a memory context + * implementation's version of an isc_mem_t. + * \brief + * Direct use of this structure by clients is forbidden. mctx implementations + * may change the structure. 'magic' must be ISCAPI_MCTX_MAGIC for any of the + * isc_mem_ routines to work. mctx implementations must maintain all mctx + * invariants. + */ +struct isc_mem { + unsigned int impmagic; + unsigned int magic; + isc_memmethods_t *methods; +}; + +#define ISCAPI_MCTX_MAGIC ISC_MAGIC('A','m','c','x') +#define ISCAPI_MCTX_VALID(m) ((m) != NULL && \ + (m)->magic == ISCAPI_MCTX_MAGIC) + +/*% + * This is the common prefix of a memory pool context. The same note as + * that for the mem structure applies. + */ +struct isc_mempool { + unsigned int impmagic; + unsigned int magic; + isc_mempoolmethods_t *methods; +}; + +#define ISCAPI_MPOOL_MAGIC ISC_MAGIC('A','m','p','l') +#define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \ + (mp)->magic == ISCAPI_MPOOL_MAGIC) + #if ISC_MEM_DEBUG #define isc_mem_put(c, p, s) \ do { \ - isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \ + ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) #define isc_mem_putanddetach(c, p, s) \ do { \ - isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \ + ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) #define isc_mem_free(c, p) \ do { \ - isc__mem_free((c), (p) _ISC_MEM_FILELINE); \ + ISCMEMFUNC(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); \ + ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) #else -#define isc_mem_put(c, p, s) isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE) +#define isc_mem_put(c, p, s) ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE) #define isc_mem_putanddetach(c, p, s) \ - isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE) -#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) + ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE) +#define isc_mem_free(c, p) ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE) +#define isc_mempool_put(c, p) ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE) #endif /*@{*/ @@ -247,7 +334,7 @@ isc_mem_createx2(size_t max_size, size_t target_size, * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored. * * 'max_size' is also used to size the statistics arrays and the array - * used to record active memory when ISC_MEM_DEBUGRECORD is set. Settin + * used to record active memory when ISC_MEM_DEBUGRECORD is set. Setting * 'max_size' too low can have detrimental effects on performance. * * A memory context created using isc_mem_createx() will obtain @@ -334,6 +421,14 @@ isc_mem_inuse(isc_mem_t *mctx); * allocated from the system but not yet used. */ +isc_boolean_t +isc_mem_isovermem(isc_mem_t *mctx); +/*%< + * Return true iff the memory context is in "over memory" state, i.e., + * a hiwater mark has been set and the used amount of memory has exceeds + * the mark. + */ + void isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater); @@ -605,24 +700,50 @@ isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit); * Pseudo-private functions for use via macros. Do not call directly. */ void * -isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG); +ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG); void -isc__mem_putanddetach(isc_mem_t **, void *, - size_t _ISC_MEM_FLARG); +ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG); void -isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); +ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); void * -isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG); +ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG); void * -isc__mem_reallocate(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); +ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); void -isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG); +ISCMEMFUNC(free)(isc_mem_t *, void * _ISC_MEM_FLARG); char * -isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG); +ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG); void * -isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG); +ISCMEMPOOLFUNC(get)(isc_mempool_t * _ISC_MEM_FLARG); void -isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG); +ISCMEMPOOLFUNC(put)(isc_mempool_t *, void * _ISC_MEM_FLARG); + +#ifdef USE_MEMIMPREGISTER + +/*%< + * See isc_mem_create2() above. + */ +typedef isc_result_t +(*isc_memcreatefunc_t)(size_t init_max_size, size_t target_size, + isc_mem_t **ctxp, unsigned int flags); + +isc_result_t +isc_mem_register(isc_memcreatefunc_t createfunc); +/*%< + * Register a new memory management implementation and add it to the list of + * supported implementations. This function must be called when a different + * memory management library is used than the one contained in the ISC library. + */ + +isc_result_t +isc__mem_register(void); +/*%< + * A short cut function that specifies the memory management module in the ISC + * library for isc_mem_register(). An application that uses the ISC library + * usually do not have to care about this function: it would call + * isc_lib_register(), which internally calls this function. + */ +#endif /* USE_MEMIMPREGISTER */ ISC_LANG_ENDDECLS |