* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mem.h,v 1.66 2005/10/26 04:35:55 marka Exp $ */
+/* $Id: mem.h,v 1.67 2006/01/04 03:16:47 marka Exp $ */
#ifndef ISC_MEM_H
#define ISC_MEM_H 1
* hi_water >= lo_water
*/
+void
+isc_mem_printactive(isc_mem_t *mctx, FILE *file);
+/*%<
+ * Print to 'file' all active memory in 'mctx'.
+ *
+ * Requires ISC_MEM_DEBUGRECORD to have been set.
+ */
+
+void
+isc_mem_printallactive(FILE *file);
+/*%<
+ * Print to 'file' all active memory in all contexts.
+ *
+ * Requires ISC_MEM_DEBUGRECORD to have been set.
+ */
+
+void
+isc_mem_checkdestroyed(FILE *file);
+/*%<
+ * Check that all memory contexts have been destroyed.
+ * Prints out those that have not been.
+ * Fatally fails if there are still active contexts.
+ */
+
/*
* Memory pools
*/
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mem.c,v 1.124 2005/08/23 04:05:50 marka Exp $ */
+/* $Id: mem.c,v 1.125 2006/01/04 03:16:47 marka Exp $ */
/*! \file */
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/msgs.h>
+#include <isc/once.h>
#include <isc/ondestroy.h>
#include <isc/string.h>
typedef ISC_LIST(debuglink_t) debuglist_t;
#endif
+/* List of all active memory contexts. */
+
+static ISC_LIST(isc_mem_t) contexts;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_mutex_t lock;
+
struct isc_mem {
unsigned int magic;
isc_ondestroy_t ondestroy;
#endif
unsigned int memalloc_failures;
+ ISC_LINK(isc_mem_t) link;
};
#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p')
free(ptr);
}
+static void
+initialize_action(void) {
+ RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
+}
+
/*
* Public.
*/
INSIST((ALIGNMENT_SIZE & (ALIGNMENT_SIZE - 1)) == 0);
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+
ctx = (memalloc)(arg, sizeof(*ctx));
if (ctx == NULL)
return (ISC_R_NOMEMORY);
ctx->memalloc_failures = 0;
+ LOCK(&lock);
+ ISC_LIST_INITANDAPPEND(contexts, ctx, link);
+ UNLOCK(&lock);
+
*ctxp = ctx;
return (ISC_R_SUCCESS);
ctx->magic = 0;
+ LOCK(&lock);
+ ISC_LIST_UNLINK(contexts, ctx, link);
+ UNLOCK(&lock);
+
INSIST(ISC_LIST_EMPTY(ctx->pools));
#if ISC_MEM_TRACKLINES
return (fillcount);
}
+
+void
+isc_mem_printactive(isc_mem_t *ctx, FILE *file) {
+
+ REQUIRE(VALID_CONTEXT(ctx));
+ REQUIRE(file != NULL);
+
+#if !ISC_MEM_TRACKLINES
+ UNUSED(ctx);
+ UNUSED(file);
+#else
+ print_active(ctx, file);
+#endif
+}
+
+void
+isc_mem_printallactive(FILE *file) {
+#if !ISC_MEM_TRACKLINES
+ UNUSED(file);
+#else
+ isc_mem_t *ctx;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+
+ LOCK(&lock);
+ for (ctx = ISC_LIST_HEAD(contexts);
+ ctx != NULL;
+ ctx = ISC_LIST_NEXT(ctx, link)) {
+ fprintf(file, "context: %p\n", ctx);
+ print_active(ctx, file);
+ }
+ UNLOCK(&lock);
+#endif
+}
+
+void
+isc_mem_checkdestroyed(FILE *file) {
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+
+ LOCK(&lock);
+ if (!ISC_LIST_EMPTY(contexts)) {
+#if ISC_MEM_TRACKLINES
+ isc_mem_t *ctx;
+
+ for (ctx = ISC_LIST_HEAD(contexts);
+ ctx != NULL;
+ ctx = ISC_LIST_NEXT(ctx, link)) {
+ fprintf(file, "context: %p\n", ctx);
+ print_active(ctx, file);
+ }
+ fflush(file);
+#endif
+ INSIST(1);
+ }
+ UNLOCK(&lock);
+}
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task.c,v 1.95 2005/07/12 01:00:18 marka Exp $ */
+/* $Id: task.c,v 1.96 2006/01/04 03:16:47 marka Exp $ */
/*! \file
* \author Principal Author: Bob Halley
UNLOCK(&manager->lock);
while (isc__taskmgr_ready())
(void)isc__taskmgr_dispatch();
+ if (!ISC_LIST_EMPTY(manager->tasks))
+ isc_mem_printallactive(stderr);
INSIST(ISC_LIST_EMPTY(manager->tasks));
#endif /* ISC_PLATFORM_USETHREADS */