* SOFTWARE.
*/
-/* $Id: mem.h,v 1.37 2000/06/28 03:46:37 tale Exp $ */
+/* $Id: mem.h,v 1.38 2000/07/26 19:06:20 explorer Exp $ */
#ifndef ISC_MEM_H
#define ISC_MEM_H 1
#if !defined(ISC_MEM_DEBUG) && !defined(ISC_MEM_DEBUGOFF)
#define ISC_MEM_DEBUG
#endif
-extern isc_boolean_t isc_mem_debugging;
+
+/*
+ * Define ISC_MEM_TRACKLINES to turn on detailed tracing of memory allocation
+ * and freeing by file and line number.
+ */
+#if 0
+#define ISC_MEM_TRACKLINES
+#endif
+
+/*
+ * Define ISC_MEM_CHECKOVERRUN to turn on checks for using memory outside
+ * the requested space. This will increase the size of each allocation.
+ */
+#if 0
+#define ISC_MEM_CHECKOVERRUN
+#endif
+
+/*
+ * Define ISC_MEM_FILL to fill each block of memory returned to the system
+ * with the byte string '0xbe'. This helps track down uninitialized pointers
+ * and the like. On freeing memory, the space is filled with '0xde' for
+ * the same reasons.
+ */
+#define ISC_MEM_FILL
+
+/*
+ * Define this to turn on memory pool names.
+ */
+#define ISC_MEMPOOL_NAMES
+
+/*
+ * _DEBUGTRACE
+ * log (to isc_lctx) each allocation and free.
+ *
+ * _DEBUGRECORD
+ * remember each allocation, and match them up on free. Crash if
+ * a free doesn't match an allocation
+ */
+extern unsigned int isc_mem_debugging;
+#define ISC_MEM_DEBUGTRACE 0x00000001U
+#define ISC_MEM_DEBUGRECORD 0x00000002U
+
+#ifdef ISC_MEM_TRACKLINES
+#define _ISC_MEM_FILELINE , __FILE__, __LINE__
+#define _ISC_MEM_FLARG , const char *, int
+#else
+#define _ISC_MEM_FILELINE
+#define _ISC_MEM_FLARG
+#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_strdup(c, p) isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_get(c) isc__mempool_get((c) _ISC_MEM_FILELINE)
#ifdef ISC_MEM_DEBUG
-#define isc_mem_get(c, s) isc__mem_getdebug(c, s, __FILE__, __LINE__)
-#define isc_mem_put(c, p, s) isc__mem_putdebug(c, p, s, __FILE__, __LINE__)
-#define isc_mem_allocate(c, s) isc__mem_allocatedebug(c, s, \
- __FILE__, __LINE__)
-#define isc_mem_free(c, p) isc__mem_freedebug(c, p, __FILE__, __LINE__)
-#define isc_mem_strdup(c, p) isc__mem_strdupdebug(c, p, \
- __FILE__, __LINE__)
-#define isc_mempool_get(c) isc__mempool_getdebug(c, __FILE__, __LINE__)
-#define isc_mempool_put(c, p) isc__mempool_putdebug(c, p, \
- __FILE__, __LINE__)
+#define isc_mem_put(c, p, s) \
+ do { \
+ isc__mem_put((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); \
+ (p) = NULL; \
+ } while (0)
+#define isc_mempool_put(c, p) \
+ do { \
+ isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
+ (p) = NULL; \
+ } while (0)
#else
-#define isc_mem_get isc__mem_get
-#define isc_mem_put isc__mem_put
-#define isc_mem_allocate isc__mem_allocate
-#define isc_mem_free isc__mem_free
-#define isc_mem_strdup isc__mem_strdup
-#define isc_mempool_get isc__mempool_get
-#define isc_mempool_put isc__mempool_put
-#endif /* ISC_MEM_DEBUG */
+#define isc_mem_put(c, p, s) isc__mem_put((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)
+#endif
isc_result_t isc_mem_create(size_t, size_t, isc_mem_t **);
void isc_mem_attach(isc_mem_t *, isc_mem_t **);
isc_result_t isc_mem_ondestroy(isc_mem_t *ctx,
isc_task_t *task,
isc_event_t **event);
-void * isc__mem_get(isc_mem_t *, size_t);
-void isc__mem_put(isc_mem_t *, void *, size_t);
-void * isc__mem_getdebug(isc_mem_t *, size_t,
- const char *, int);
-void isc__mem_putdebug(isc_mem_t *, void *,
- size_t, const char *, int);
+void * isc__mem_get(isc_mem_t *, size_t
+ _ISC_MEM_FLARG);
+void isc__mem_put(isc_mem_t *, void *,
+ size_t _ISC_MEM_FLARG);
isc_result_t isc_mem_preallocate(isc_mem_t *);
void isc_mem_stats(isc_mem_t *, FILE *);
isc_boolean_t isc_mem_valid(isc_mem_t *, void *);
-void * isc__mem_allocate(isc_mem_t *, size_t);
-void * isc__mem_allocatedebug(isc_mem_t *, size_t,
- const char *, int);
-void isc__mem_free(isc_mem_t *, void *);
-void isc__mem_freedebug(isc_mem_t *, void *,
- const char *, int);
-char * isc__mem_strdup(isc_mem_t *, const char *);
-char * isc__mem_strdupdebug(isc_mem_t *,
- const char *,
- const char *, int);
+void * isc__mem_allocate(isc_mem_t *, size_t
+ _ISC_MEM_FLARG);
+void isc__mem_free(isc_mem_t *, void *
+ _ISC_MEM_FLARG);
+char * isc__mem_strdup(isc_mem_t *, const char *
+ _ISC_MEM_FLARG);
void isc_mem_setdestroycheck(isc_mem_t *,
isc_boolean_t);
void isc_mem_setsplit(isc_mem_t *, isc_boolean_t);
void *arg, isc_mem_t **);
isc_result_t isc_mem_restore(isc_mem_t *);
-#ifdef ISC_MEMCLUSTER_LEGACY
-
-/*
- * Legacy.
- */
-
-#define meminit isc__legacy_meminit
-#define mem_default_context isc__legacy_mem_default_context
-#ifdef MEMCLUSTER_DEBUG
-#define memget(s) isc__legacy_memget_debug(s, __FILE__, __LINE__)
-#define memput(p, s) isc__legacy_memput_debug(p, s, \
- __FILE__, __LINE__)
-#else
-#define memget isc__legacy_memget
-#define memput isc__legacy_memput
-#endif
-#define memvalid isc__legacy_memvalid
-#define memstats isc__legacy_memstats
-
-int meminit(size_t, size_t);
-isc_mem_t * mem_default_context(void);
-void * isc__legacy_memget(size_t);
-void isc__legacy_memput(void *, size_t);
-void * isc__legacy_memget_debug(size_t, const char *,
- int);
-void isc__legacy_memput_debug(void *, size_t,
- const char *, int);
-int memvalid(void *);
-void memstats(FILE *);
-
-#endif /* ISC_MEMCLUSTER_LEGACY */
-
/*
* Memory pools
*/
* Internal (but public) functions. Don't call these from application
* code. Use isc_mempool_get() and isc_mempool_put() instead.
*/
-void * isc__mempool_get(isc_mempool_t *);
-void isc__mempool_put(isc_mempool_t *, void *);
-void * isc__mempool_getdebug(isc_mempool_t *, const char *, int);
-void isc__mempool_putdebug(isc_mempool_t *, void *,
- const char *, int);
+void * isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
+void isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
isc_result_t
isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
* SOFTWARE.
*/
-/* $Id: mem.c,v 1.53 2000/06/26 20:27:42 bwelling Exp $ */
+/* $Id: mem.c,v 1.54 2000/07/26 19:06:19 explorer Exp $ */
#include <config.h>
#define UNLOCK(l)
#endif
-isc_boolean_t isc_mem_debugging = ISC_FALSE;
-
-#ifndef ISC_MEM_FILL
- /*
- * XXXMPA
- * We want this on during development to catch:
- * 1. some reference after free bugs.
- * 2. some failure to initalise bugs.
- */
-#define ISC_MEM_FILL 1
-#endif
-
-#ifndef ISC_MEMPOOL_NAMES
-/*
- * During development it is nice to be able to see names associated with
- * memory pools.
- */
-#define ISC_MEMPOOL_NAMES 1
-#endif
-
+unsigned int isc_mem_debugging = 0;
/*
* Constants.
#define ALIGNMENT_SIZE 8
#define NUM_BASIC_BLOCKS 64 /* must be > 1 */
#define TABLE_INCREMENT 1024
+#define DEBUGLIST_COUNT 1024
/*
* Types.
*/
+#ifdef ISC_MEM_TRACKLINES
+typedef struct debuglink debuglink_t;
+struct debuglink {
+ ISC_LINK(debuglink_t) link;
+ const void *ptr[DEBUGLIST_COUNT];
+ const char *file[DEBUGLIST_COUNT];
+ unsigned int line[DEBUGLIST_COUNT];
+ unsigned int count;
+};
-typedef struct element element;
+#define FLARG_PASS , file, line
+#define FLARG , const char *file, int line
+#else
+#define FLARG_PASS
+#define FLARG
+#endif
+typedef struct element element;
struct element {
element * next;
};
size_t total;
size_t inuse;
ISC_LIST(isc_mempool_t) pools;
+#ifdef ISC_MEM_TRACKLINES
+ ISC_LIST(debuglink_t) debuglist;
+#endif
};
#define MEMPOOL_MAGIC 0x4D454d70U /* MEMp. */
/* Stats only. */
unsigned int gets; /* # of requests to this pool */
/* Debugging only. */
-#if ISC_MEMPOOL_NAMES
+#ifdef ISC_MEMPOOL_NAMES
char name[16]; /* printed name in stats reports */
#endif
};
* Private Inline-able.
*/
+#ifndef ISC_MEM_TRACKLINES
+#define ADD_TRACE(a, b, c, d, e)
+#define DELETE_TRACE(a, b, c, d, e)
+#else
+#define ADD_TRACE(a, b, c, d, e) add_trace_entry(a, b, c, d, e)
+#define DELETE_TRACE(a, b, c, d, e) delete_trace_entry(a, b, c, d, e)
+
+#define MEM_TRACE ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0)
+#define MEM_RECORD ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0)
+
+/*
+ * mctx must be locked.
+ */
+static inline void
+add_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
+ const char *file, int line)
+{
+ debuglink_t *dl;
+ unsigned int i;
+
+ if (MEM_TRACE)
+ fprintf(stderr, "add %p size %u file %s line %u\n",
+ ptr, size, file, line);
+
+ if (!MEM_RECORD)
+ return;
+
+ dl = ISC_LIST_HEAD(mctx->debuglist);
+ while (dl != NULL) {
+ if (dl->count == DEBUGLIST_COUNT)
+ goto next;
+ for (i = 0 ; i < DEBUGLIST_COUNT ; i++) {
+ if (dl->ptr[i] == NULL) {
+ dl->ptr[i] = ptr;
+ dl->file[i] = file;
+ dl->line[i] = line;
+ dl->count++;
+ return;
+ }
+ }
+ next:
+ dl = ISC_LIST_NEXT(dl, link);
+ }
+
+ dl = malloc(sizeof(debuglink_t));
+ INSIST(dl != NULL);
+
+ ISC_LINK_INIT(dl, link);
+ for (i = 1 ; i < DEBUGLIST_COUNT ; i++) {
+ dl->ptr[i] = NULL;
+ dl->file[i] = NULL;
+ dl->line[i] = 0;
+ }
+
+ dl->ptr[0] = ptr;
+ dl->file[0] = file;
+ dl->line[0] = line;
+ dl->count = 1;
+
+ ISC_LIST_PREPEND(mctx->debuglist, dl, link);
+}
+
+static inline void
+delete_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size,
+ const char *file, unsigned int line)
+{
+ debuglink_t *dl;
+ unsigned int i;
+
+ if (MEM_TRACE)
+ fprintf(stderr, "del %p size %u file %s line %u\n",
+ ptr, size, file, line);
+
+ if (!MEM_RECORD)
+ return;
+
+ dl = ISC_LIST_HEAD(mctx->debuglist);
+ while (dl != NULL) {
+ for (i = 0 ; i < DEBUGLIST_COUNT ; i++) {
+ if (dl->ptr[i] == ptr) {
+ dl->ptr[i] = NULL;
+ dl->file[i] = NULL;
+ dl->line[i] = 0;
+
+ INSIST(dl->count > 0);
+ dl->count--;
+ if (dl->count == 0) {
+ ISC_LIST_UNLINK(mctx->debuglist,
+ dl, link);
+ free(dl);
+ }
+ return;
+ }
+ }
+ dl = ISC_LIST_NEXT(dl, link);
+ }
+
+ /*
+ * If we get here, we didn't find the item on the list. We're
+ * screwed.
+ */
+ INSIST(dl != NULL);
+}
+#endif /* ISC_MEM_TRACKLINES */
+
static inline size_t
quantize(size_t size) {
int temp;
done:
-#if ISC_MEM_FILL
+#ifdef ISC_MEM_FILL
if (ret != NULL)
memset(ret, 0xbe, new_size); /* Mnemonic for "beef". */
#endif
/*
* memput() called on something beyond our upper limit.
*/
-#if ISC_MEM_FILL
+#ifdef ISC_MEM_FILL
memset(mem, 0xde, size); /* Mnemonic for "dead". */
#endif
(ctx->memfree)(ctx->arg, mem);
return;
}
-#if ISC_MEM_FILL
-#if ISC_MEM_CHECKOVERRUN
+#ifdef ISC_MEM_FILL
+#ifdef ISC_MEM_CHECKOVERRUN
check_overrun(mem, size, new_size);
#endif
memset(mem, 0xde, new_size); /* Mnemonic for "dead". */
ctx->magic = MEM_MAGIC;
isc_ondestroy_init(&ctx->ondestroy);
ISC_LIST_INIT(ctx->pools);
+#ifdef ISC_MEM_TRACKLINES
+ ISC_LIST_INIT(ctx->debuglist);
+#endif
*ctxp = ctx;
return (ISC_R_SUCCESS);
ctx->magic = 0;
INSIST(ISC_LIST_EMPTY(ctx->pools));
+#ifdef ISC_MEM_TRACKLINES
+ INSIST(ISC_LIST_EMPTY(ctx->debuglist));
+#endif
INSIST(ctx->references == 0);
if (ctx->checkfree) {
return (result);
}
-void *
-isc__mem_get(isc_mem_t *ctx, size_t size) {
- void *ret;
-
- REQUIRE(VALID_CONTEXT(ctx));
-
- LOCK(&ctx->lock);
- ret = mem_getunlocked(ctx, size);
- UNLOCK(&ctx->lock);
-
- return (ret);
-}
-
-#if ISC_MEM_FILL != 0 && ISC_MEM_CHECKOVERRUN != 0
+#if defined(ISC_MEM_FILL) && defined(ISC_MEM_CHECKOVERRUN)
static inline void
check_overrun(void *mem, size_t size, size_t new_size) {
unsigned char *cp;
}
#endif
-void
-isc__mem_put(isc_mem_t *ctx, void *mem, size_t size) {
+void *
+isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
+ void *ptr;
+
REQUIRE(VALID_CONTEXT(ctx));
LOCK(&ctx->lock);
- mem_putunlocked(ctx, mem, size);
+ ptr = mem_getunlocked(ctx, size);
+ ADD_TRACE(ctx, ptr, size, file, line);
UNLOCK(&ctx->lock);
-}
-
-void *
-isc__mem_getdebug(isc_mem_t *ctx, size_t size, const char *file, int line) {
- void *ptr;
-
- ptr = isc__mem_get(ctx, size);
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: mem_get(%p, %lu) -> %p\n", file, line,
- ctx, (unsigned long)size, ptr);
return (ptr);
}
void
-isc__mem_putdebug(isc_mem_t *ctx, void *ptr, size_t size, const char *file,
- int line)
+isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
{
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: mem_put(%p, %p, %lu)\n", file, line,
- ctx, ptr, (unsigned long)size);
- isc__mem_put(ctx, ptr, size);
+ REQUIRE(VALID_CONTEXT(ctx));
+ REQUIRE(ptr != NULL);
+
+ LOCK(&ctx->lock);
+ DELETE_TRACE(ctx, ptr, size, file, line);
+ mem_putunlocked(ctx, ptr, size);
+ UNLOCK(&ctx->lock);
}
isc_result_t
pool = ISC_LIST_NEXT(pool, link);
}
+#ifdef ISC_MEM_TRACKLINES
+ if (isc_mem_debugging > 1) {
+ debuglink_t *dl;
+ unsigned int i;
+
+ fprintf(out, "DUMP OF ALL OUTSTANDING MEMORY ALLOCATIONS\n");
+ dl = ISC_LIST_HEAD(ctx->debuglist);
+ if (dl == NULL)
+ fprintf(out, "\tNone.\n");
+ while (dl != NULL) {
+ for (i = 0 ; i < DEBUGLIST_COUNT ; i++)
+ if (dl->ptr[i] != NULL)
+ fprintf(out,
+ "\tptr %p file %s line %u\n",
+ dl->ptr[i], dl->file[i],
+ dl->line[i]);
+ dl = ISC_LIST_NEXT(dl, link);
+ }
+ }
+#endif
+
UNLOCK(&ctx->lock);
}
* size of the object allocated (with some additional overhead).
*/
-void *
-isc__mem_allocate(isc_mem_t *ctx, size_t size) {
+static void *
+isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) {
size_info *si;
size += ALIGNMENT_SIZE;
- si = isc__mem_get(ctx, size);
+ si = mem_getunlocked(ctx, size);
if (si == NULL)
return (NULL);
si->u.size = size;
}
void *
-isc__mem_allocatedebug(isc_mem_t *ctx, size_t size, const char *file,
- int line) {
+isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
size_info *si;
- si = isc__mem_allocate(ctx, size);
- if (si == NULL)
- return (NULL);
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: mem_get(%p, %lu) -> %p\n", file, line,
- ctx, (unsigned long)si[-1].u.size, si);
- return (si);
-}
+ REQUIRE(VALID_CONTEXT(ctx));
-void
-isc__mem_free(isc_mem_t *ctx, void *ptr) {
- size_info *si;
+ LOCK(&ctx->lock);
+ si = isc__mem_allocateunlocked(ctx, size);
+#ifdef ISC_MEM_TRACKLINES
+ if (si != NULL)
+ ADD_TRACE(ctx, si, si[-1].u.size, file, line);
+#endif
+ UNLOCK(&ctx->lock);
- si = &(((size_info *)ptr)[-1]);
- isc__mem_put(ctx, si, si->u.size);
+ return (si);
}
void
-isc__mem_freedebug(isc_mem_t *ctx, void *ptr, const char *file, int line) {
+isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
size_info *si;
+ REQUIRE(VALID_CONTEXT(ctx));
+ REQUIRE(ptr != NULL);
+
si = &(((size_info *)ptr)[-1]);
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: mem_put(%p, %p, %lu)\n", file, line,
- ctx, ptr, (unsigned long)si->u.size);
- isc__mem_put(ctx, si, si->u.size);
+ LOCK(&ctx->lock);
+ DELETE_TRACE(ctx, ptr, si->u.size, file, line);
+ mem_putunlocked(ctx, si, si->u.size);
+ UNLOCK(&ctx->lock);
}
/*
*/
char *
-isc__mem_strdup(isc_mem_t *mctx, const char *s) {
+isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
size_t len;
char *ns;
+ REQUIRE(VALID_CONTEXT(mctx));
+ REQUIRE(s != NULL);
+
len = strlen(s);
- ns = isc__mem_allocate(mctx, len + 1);
- if (ns == NULL)
- return (NULL);
- strncpy(ns, s, len + 1);
-
- return (ns);
-}
-char *
-isc__mem_strdupdebug(isc_mem_t *mctx, const char *s, const char *file,
- int line) {
- char *ptr;
- size_info *si;
+ ns = isc__mem_allocate(mctx, len + 1 FLARG_PASS);
- ptr = isc__mem_strdup(mctx, s);
- si = &(((size_info *)ptr)[-1]);
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: mem_get(%p, %lu) -> %p\n", file, line,
- mctx, (unsigned long)si->u.size, ptr);
- return (ptr);
+ if (ns != NULL)
+ strncpy(ns, s, len + 1);
+
+ return (ns);
}
void
return (inuse);
}
-#ifdef ISC_MEMCLUSTER_LEGACY
-
-/*
- * Public Legacy.
- */
-
-static isc_mem_t *default_context = NULL;
-
-int
-meminit(size_t init_max_size, size_t target_size) {
- /*
- * Need default_context lock here.
- */
- if (default_context != NULL)
- return (-1);
- return (isc_mem_create(init_max_size, target_size, &default_context));
-}
-
-isc_mem_t *
-mem_default_context(void) {
- /*
- * Need default_context lock here.
- */
- if (default_context == NULL && meminit(0, 0) == -1)
- return (NULL);
- return (default_context);
-}
-
-void *
-isc__legacy_memget(size_t size) {
- /*
- * Need default_context lock here.
- */
- if (default_context == NULL && meminit(0, 0) == -1)
- return (NULL);
- return (isc__mem_get(default_context, size));
-}
-
-void
-isc__legacy_memput(void *mem, size_t size) {
- /*
- * Need default_context lock here.
- */
- REQUIRE(default_context != NULL);
- isc__mem_put(default_context, mem, size);
-}
-
-void *
-isc__legacy_memget_debug(size_t size, const char *file, int line) {
- void *ptr;
- ptr = isc__legacy_memget(size);
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: memget(%lu) -> %p\n", file, line,
- (unsigned long)size, ptr);
- return (ptr);
-}
-
-void
-isc__legacy_memput_debug(void *ptr, size_t size, const char *file, int line) {
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: memput(%p, %lu)\n", file, line,
- ptr, (unsigned long)size);
- isc__legacy_memput(ptr, size);
-}
-
-int
-memvalid(void *ptr) {
- /*
- * Need default_context lock here.
- */
- REQUIRE(default_context != NULL);
- return (isc_mem_valid(default_context, ptr));
-}
-
-void
-memstats(FILE *out) {
- /*
- * Need default_context lock here.
- */
- REQUIRE(default_context != NULL);
- isc_mem_stats(default_context, out);
-}
-
-#endif /* ISC_MEMCLUSTER_LEGACY */
-
-
/*
* Memory pool stuff
*/
mpctx->freemax = 1;
mpctx->fillcount = 1;
mpctx->gets = 0;
-#if ISC_MEMPOOL_NAMES
+#ifdef ISC_MEMPOOL_NAMES
mpctx->name[0] = 0;
#endif
mpctx->items = NULL;
isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
REQUIRE(name != NULL);
-#if ISC_MEMPOOL_NAMES
+#ifdef ISC_MEMPOOL_NAMES
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
}
void *
-isc__mempool_get(isc_mempool_t *mpctx) {
+isc__mempool_get(isc_mempool_t *mpctx FLARG) {
element *item;
isc_mem_t *mctx;
unsigned int i;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
+ if (item != NULL) {
+ LOCK(&mctx->lock);
+ ADD_TRACE(mctx, item, mpctx->size, file, line);
+ UNLOCK(&mctx->lock);
+ }
+
return (item);
}
void
-isc__mempool_put(isc_mempool_t *mpctx, void *mem) {
+isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
isc_mem_t *mctx;
element *item;
INSIST(mpctx->allocated > 0);
mpctx->allocated--;
+ DELETE_TRACE(mctx, mem, mpctx->size, file, line);
+
/*
* If our free list is full, return this to the mctx directly.
*/
if (mpctx->freecount >= mpctx->freemax) {
- isc__mem_put(mctx, mem, mpctx->size);
+ LOCK(&mctx->lock);
+ mem_putunlocked(mctx, mem, mpctx->size);
+ UNLOCK(&mctx->lock);
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return;
UNLOCK(mpctx->lock);
}
-void *
-isc__mempool_getdebug(isc_mempool_t *mpctx, const char *file, int line) {
- void *ptr;
-
- ptr = isc__mempool_get(mpctx);
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: mempool_get(%p) -> %p\n", file, line,
- mpctx, ptr);
-
- return (ptr);
-}
-
-void
-isc__mempool_putdebug(isc_mempool_t *mpctx, void *ptr, const char *file,
- int line)
-{
- if (isc_mem_debugging)
- fprintf(stderr, "%s:%d: mempool_put(%p, %p)\n", file, line,
- mpctx, ptr);
- isc__mempool_put(mpctx, ptr);
-}
-
/*
* Quotas
*/