mem.c revision 90989375ca062ee06d708cb1dc50ed12f1db130a
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * Copyright (C) 1997-2001 Internet Software Consortium.
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * Permission to use, copy, modify, and distribute this software for any
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * purpose with or without fee is hereby granted, provided that the above
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * copyright notice and this permission notice appear in all copies.
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
ef491b68cd4d65839f09171df243aeaf013247bfAndreas Gustafsson * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
89beab759407cc76083deb7a2c5215f00bf9a82eAndreas Gustafsson/* $Id: mem.c,v 1.99 2001/08/30 05:40:04 marka Exp $ */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas GustafssonLIBISC_EXTERNAL_DATA unsigned int isc_mem_debugging = ISC_MEM_DEBUGGING;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc()
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson * implementation in preference to the system one. The internal malloc()
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson * is very space-efficient, and quite fast on uniprocessor systems. It
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson * performs poorly on multiprocessor machines.
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define ALIGNMENT_SIZE 8 /* must be a power of 2 */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define NUM_BASIC_BLOCKS 64 /* must be > 1 */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define FLARG , const char *file, int line
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafssontypedef struct {
89beab759407cc76083deb7a2c5215f00bf9a82eAndreas Gustafsson * This structure must be ALIGNMENT_SIZE bytes.
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned long gets;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned long blocks;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C')
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC)
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafssontypedef ISC_LIST(debuglink_t) debuglist_t;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned char ** basic_table;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned char * lowest;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned char * highest;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p')
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define VALID_MEMPOOL(c) ISC_MAGIC_VALID(c, MEMPOOL_MAGIC)
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson /* always unlocked */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson isc_mem_t *mctx; /* our memory context */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson /* locked via the memory context's lock */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson ISC_LINK(isc_mempool_t) link; /* next pool in this mem context */
89beab759407cc76083deb7a2c5215f00bf9a82eAndreas Gustafsson /* optionally locked from here down */
89beab759407cc76083deb7a2c5215f00bf9a82eAndreas Gustafsson element *items; /* low water item list */
89beab759407cc76083deb7a2c5215f00bf9a82eAndreas Gustafsson size_t size; /* size of each item on this pool */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned int maxalloc; /* max number of items allowed */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned int allocated; /* # of items currently given out */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned int freecount; /* # of items on reserved list */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned int freemax; /* # of items allowed on free list */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned int fillcount; /* # of items to fetch on each fill */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson /* Stats only. */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned int gets; /* # of requests to this pool */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson /* Debugging only. */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson char name[16]; /* printed name in stats reports */
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson * Private Inline-able.
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define ADD_TRACE(a, b, c, d, e)
89beab759407cc76083deb7a2c5215f00bf9a82eAndreas Gustafsson#define DELETE_TRACE(a, b, c, d, e)
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define ADD_TRACE(a, b, c, d, e) \
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson do { if (b != NULL) add_trace_entry(a, b, c, d, e); } while (0)
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define DELETE_TRACE(a, b, c, d, e) delete_trace_entry(a, b, c, d, e)
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson#define MEM_TRACE ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0)
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson * mctx must be locked.
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafssonstatic inline void
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafssonadd_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson unsigned int i;
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson "add %p size %u "
22aa1c0bc258e6c2c7491e2e330e3c363daa2b80Andreas Gustafsson "file %s line %u mctx %p\n"),
goto next;
for (i = 0 ; i < DEBUGLIST_COUNT ; i++) {
next:
if (MEM_TRACE)
for (i = 0 ; i < DEBUGLIST_COUNT ; i++) {
static inline size_t
static inline size_t
if (size == 0)
return (ALIGNMENT_SIZE);
static inline isc_boolean_t
void *new;
unsigned char **table;
unsigned int table_size;
return (ISC_FALSE);
table_size * sizeof (unsigned char *));
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
static inline isc_boolean_t
int i, frags;
void *new;
return (ISC_FALSE);
if (total_size > 0) {
return (ISC_TRUE);
void *ret;
goto done;
goto done;
return (NULL);
done:
#if ISC_MEM_FILL
return (ret);
unsigned char *cp;
cp++;
size++;
#if ISC_MEM_FILL
#if ISC_MEM_FILL
char *ret;
#if ISC_MEM_FILL
# if ISC_MEM_CHECKOVERRUN
return (ret);
#if ISC_MEM_FILL
return (ISC_R_NOMEMORY);
if (init_max_size == 0)
goto error;
if (target_size == 0)
goto error;
goto error;
goto error;
return (ISC_R_SUCCESS);
if (ctx) {
return (result);
ctxp));
if (want_destroy)
if (want_destroy)
return (res);
void *ptr;
if (ptr)
if (call_water) {
return (ptr);
if (call_water) {
const char *format;
for (j = 0 ; j < DEBUGLIST_COUNT ; j++)
if (!found)
size_t i;
const struct stats *s;
return (NULL);
return (si);
char *ns;
return (ns);
return (quota);
return (inuse);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
goto out;
goto out;
goto out;
out:
return (item);
unsigned int freemax;
return (freemax);
unsigned int freecount;
return (freecount);
unsigned int maxalloc;
return (maxalloc);
unsigned int allocated;
return (allocated);
unsigned int fillcount;
return (fillcount);