2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

Improve time taken to free memory when ISC_MEM_DEBUGRECORD is set.

This commit is contained in:
Mark Andrews
2001-08-30 05:40:04 +00:00
parent bd3091eb7d
commit 90989375ca

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: mem.c,v 1.98 2001/07/17 10:02:46 marka Exp $ */ /* $Id: mem.c,v 1.99 2001/08/30 05:40:04 marka Exp $ */
#include <config.h> #include <config.h>
@@ -107,6 +107,8 @@ struct stats {
#define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C') #define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C')
#define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC) #define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC)
typedef ISC_LIST(debuglink_t) debuglist_t;
struct isc_mem { struct isc_mem {
unsigned int magic; unsigned int magic;
isc_ondestroy_t ondestroy; isc_ondestroy_t ondestroy;
@@ -141,8 +143,7 @@ struct isc_mem {
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ #endif /* ISC_MEM_USE_INTERNAL_MALLOC */
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
ISC_LIST(debuglink_t) debuglist; debuglist_t * debuglist;
unsigned int debugging;
#endif #endif
unsigned int memalloc_failures; unsigned int memalloc_failures;
@@ -187,7 +188,6 @@ struct isc_mempool {
#define DELETE_TRACE(a, b, c, d, e) delete_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_TRACE ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0)
#define MEM_RECORD ((mctx->debugging & ISC_MEM_DEBUGRECORD) != 0)
static void static void
print_active(isc_mem_t *ctx, FILE *out); print_active(isc_mem_t *ctx, FILE *out);
@@ -209,10 +209,13 @@ add_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
"file %s line %u mctx %p\n"), "file %s line %u mctx %p\n"),
ptr, size, file, line, mctx); ptr, size, file, line, mctx);
if (!MEM_RECORD) if (mctx->debuglist == NULL)
return; return;
dl = ISC_LIST_HEAD(mctx->debuglist); if (size > mctx->max_size)
size = mctx->max_size;
dl = ISC_LIST_HEAD(mctx->debuglist[size]);
while (dl != NULL) { while (dl != NULL) {
if (dl->count == DEBUGLIST_COUNT) if (dl->count == DEBUGLIST_COUNT)
goto next; goto next;
@@ -244,7 +247,7 @@ add_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
dl->line[0] = line; dl->line[0] = line;
dl->count = 1; dl->count = 1;
ISC_LIST_PREPEND(mctx->debuglist, dl, link); ISC_LIST_PREPEND(mctx->debuglist[size], dl, link);
} }
static inline void static inline void
@@ -261,10 +264,13 @@ delete_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size,
"file %s line %u mctx %p\n"), "file %s line %u mctx %p\n"),
ptr, size, file, line, mctx); ptr, size, file, line, mctx);
if (!MEM_RECORD) if (mctx->debuglist == NULL)
return; return;
dl = ISC_LIST_HEAD(mctx->debuglist); if (size > mctx->max_size)
size = mctx->max_size;
dl = ISC_LIST_HEAD(mctx->debuglist[size]);
while (dl != NULL) { while (dl != NULL) {
for (i = 0 ; i < DEBUGLIST_COUNT ; i++) { for (i = 0 ; i < DEBUGLIST_COUNT ; i++) {
if (dl->ptr[i] == ptr) { if (dl->ptr[i] == ptr) {
@@ -275,7 +281,7 @@ delete_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size,
INSIST(dl->count > 0); INSIST(dl->count > 0);
dl->count--; dl->count--;
if (dl->count == 0) { if (dl->count == 0) {
ISC_LIST_UNLINK(mctx->debuglist, ISC_LIST_UNLINK(mctx->debuglist[size],
dl, link); dl, link);
free(dl); free(dl);
} }
@@ -719,6 +725,7 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
ctx->arg = arg; ctx->arg = arg;
ctx->stats = NULL; ctx->stats = NULL;
ctx->checkfree = ISC_TRUE; ctx->checkfree = ISC_TRUE;
ctx->debuglist = NULL;
ISC_LIST_INIT(ctx->pools); ISC_LIST_INIT(ctx->pools);
#if ISC_MEM_USE_INTERNAL_MALLOC #if ISC_MEM_USE_INTERNAL_MALLOC
@@ -763,8 +770,18 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
} }
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
ISC_LIST_INIT(ctx->debuglist); if ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0) {
ctx->debugging = isc_mem_debugging; unsigned int i;
ctx->debuglist = (memalloc)(arg,
(ctx->max_size+1) * sizeof (debuglist_t));
if (ctx->debuglist == NULL) {
result = ISC_R_NOMEMORY;
goto error;
}
for (i = 0; i <= ctx->max_size; i++)
ISC_LIST_INIT(ctx->debuglist[i]);
}
#endif #endif
ctx->memalloc_failures = 0; ctx->memalloc_failures = 0;
@@ -780,6 +797,10 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
if (ctx->freelists) if (ctx->freelists)
(memfree)(arg, ctx->freelists); (memfree)(arg, ctx->freelists);
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ #endif /* ISC_MEM_USE_INTERNAL_MALLOC */
#if ISC_MEM_TRACKLINES
if (ctx->debuglist)
(ctx->memfree)(ctx->arg, ctx->debuglist);
#endif /* ISC_MEM_TRACKLINES */
(memfree)(arg, ctx); (memfree)(arg, ctx);
} }
@@ -807,19 +828,26 @@ destroy(isc_mem_t *ctx) {
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ #endif /* ISC_MEM_USE_INTERNAL_MALLOC */
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
if (ctx->checkfree) { if (ctx->debuglist != NULL) {
if (!ISC_LIST_EMPTY(ctx->debuglist)) if (ctx->checkfree) {
print_active(ctx, stderr); for (i = 0; i <= ctx->max_size; i++) {
INSIST(ISC_LIST_EMPTY(ctx->debuglist)); if (!ISC_LIST_EMPTY(ctx->debuglist[i]))
} else { print_active(ctx, stderr);
debuglink_t *dl; INSIST(ISC_LIST_EMPTY(ctx->debuglist[i]));
}
} else {
debuglink_t *dl;
for (dl = ISC_LIST_HEAD(ctx->debuglist); for (i = 0; i <= ctx->max_size; i++)
dl != NULL; for (dl = ISC_LIST_HEAD(ctx->debuglist[i]);
dl = ISC_LIST_HEAD(ctx->debuglist)) { dl != NULL;
ISC_LIST_UNLINK(ctx->debuglist, dl, link); dl = ISC_LIST_HEAD(ctx->debuglist[i])) {
free(dl); ISC_LIST_UNLINK(ctx->debuglist[i],
dl, link);
free(dl);
}
} }
(ctx->memfree)(ctx->arg, ctx->debuglist);
} }
#endif #endif
INSIST(ctx->references == 0); INSIST(ctx->references == 0);
@@ -1050,33 +1078,38 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
static void static void
print_active(isc_mem_t *mctx, FILE *out) { print_active(isc_mem_t *mctx, FILE *out) {
if (MEM_RECORD) { if (mctx->debuglist != NULL) {
debuglink_t *dl; debuglink_t *dl;
unsigned int i; unsigned int i, j;
const char *format;
isc_boolean_t found;
fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
ISC_MSG_DUMPALLOC, ISC_MSG_DUMPALLOC,
"Dump of all outstanding " "Dump of all outstanding "
"memory allocations:\n")); "memory allocations:\n"));
dl = ISC_LIST_HEAD(mctx->debuglist); found = ISC_FALSE;
if (dl == NULL) format = isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_PTRFILELINE,
ISC_MSG_NONE, "\tptr %p file %s line %u\n");
"\tNone.\n")); for (i = 0; i <= mctx->max_size; i++) {
while (dl != NULL) { dl = ISC_LIST_HEAD(mctx->debuglist[i]);
for (i = 0 ; i < DEBUGLIST_COUNT ; i++)
if (dl->ptr[i] != NULL) if (dl != NULL)
fprintf(out, found = ISC_TRUE;
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_MEM, while (dl != NULL) {
ISC_MSG_PTRFILELINE, for (j = 0 ; j < DEBUGLIST_COUNT ; j++)
"\tptr %p " if (dl->ptr[j] != NULL)
"file %s " fprintf(out, format,
"line %u\n"), dl->ptr[j], dl->file[j],
dl->ptr[i], dl->file[i], dl->line[j]);
dl->line[i]); dl = ISC_LIST_NEXT(dl, link);
dl = ISC_LIST_NEXT(dl, link); }
} }
if (!found)
fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,
ISC_MSG_NONE, "\tNone.\n"));
} }
} }
#endif #endif