mem.c revision ec5347e2c775f027573ce5648b910361aa926c01
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * Copyright (C) 1997-2003 Internet Software Consortium.
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * Permission to use, copy, modify, and/or distribute this software for any
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * purpose with or without fee is hereby granted, provided that the above
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * copyright notice and this permission notice appear in all copies.
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * PERFORMANCE OF THIS SOFTWARE.
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt/* $Id: mem.c,v 1.135 2007/06/18 23:47:44 tbox Exp $ */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt#define MCTXLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) LOCK(l)
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt#define MCTXUNLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) UNLOCK(l)
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan HuntLIBISC_EXTERNAL_DATA unsigned int isc_mem_debugging = ISC_MEM_DEBUGGING;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * Constants.
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt#define ALIGNMENT_SIZE 8 /*%< must be a power of 2 */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int count;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunttypedef struct {
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt * This structure must be ALIGNMENT_SIZE bytes.
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned long gets;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned long totalgets;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned long blocks;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned long freefrags;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt#define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC)
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt/* List of all active memory contexts. */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int magic;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int flags;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int references;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt /* ISC_MEMFLAG_INTERNAL */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned char ** basic_table;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned char * lowest;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned char * highest;
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p')
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt#define VALID_MEMPOOL(c) ISC_MAGIC_VALID(c, MEMPOOL_MAGIC)
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt /* always unlocked */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt /*%< locked via the memory context's lock */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt ISC_LINK(isc_mempool_t) link; /*%< next pool in this mem context */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt /*%< optionally locked from here down */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt size_t size; /*%< size of each item on this pool */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int maxalloc; /*%< max number of items allowed */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int allocated; /*%< # of items currently given out */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int freecount; /*%< # of items on reserved list */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int freemax; /*%< # of items allowed on free list */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int fillcount; /*%< # of items to fetch on each fill */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt /*%< Stats only. */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt unsigned int gets; /*%< # of requests to this pool */
3b9ba6bd74e2cbbc0f821e5483ebf46fa8c4d8deEvan Hunt /*%< Debugging only. */
#if ! ISC_MEM_TRACKLINES
#define ADD_TRACE(a, b, c, d, e)
#define DELETE_TRACE(a, b, c, d, e)
#define ADD_TRACE(a, b, c, d, e) \
ISC_MEM_DEBUGRECORD)) != 0 && \
b != NULL) \
add_trace_entry(a, b, c, d, e); \
goto next;
for (i = 0; i < DEBUGLIST_COUNT; i++) {
next:
for (i = 0; i < DEBUGLIST_COUNT; i++) {
static inline size_t
static inline size_t
if (size == 0U)
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 > 0U) {
return (ISC_TRUE);
void *ret;
goto done;
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
if (size == 0U)
initialize_action(void) {
return (ISC_R_NOMEMORY);
return (result);
if (init_max_size == 0U)
goto error;
if (target_size == 0U)
sizeof(element *));
goto error;
goto error;
return (ISC_R_SUCCESS);
return (result);
if (want_destroy)
if (want_destroy)
if (want_destroy)
return (res);
void *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);
si++;
if (call_water)
return (si);
if (call_water)
char *ns;
return (ns);
return (quota);
return (inuse);
void *oldwater_arg;
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);
#if !ISC_MEM_TRACKLINES
#if !ISC_MEM_TRACKLINES
INSIST(0);
#ifdef HAVE_LIBXML2
size_t i;
const struct stats *s;
s->blocks);
s->freefrags);