summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/talloc.h17
-rw-r--r--source3/lib/talloc.c78
-rw-r--r--source3/lib/talloctort.c11
3 files changed, 83 insertions, 23 deletions
diff --git a/source3/include/talloc.h b/source3/include/talloc.h
index 198a27b49b..d8a98f07e6 100644
--- a/source3/include/talloc.h
+++ b/source3/include/talloc.h
@@ -28,25 +28,10 @@
* @sa talloc.c
*/
-struct talloc_chunk {
- struct talloc_chunk *next;
- size_t size;
- void *ptr;
-};
-
-
/**
* talloc allocation pool. All allocated blocks can be freed in one go.
**/
-typedef struct {
- struct talloc_chunk *list;
- size_t total_alloc_size;
-
- /** The name recorded for this pool, if any. Should describe
- * the purpose for which it was allocated. The string is
- * allocated within the pool. **/
- char *name;
-} TALLOC_CTX;
+typedef struct talloc_ctx TALLOC_CTX;
TALLOC_CTX *talloc_init_named(char const *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
diff --git a/source3/lib/talloc.c b/source3/lib/talloc.c
index e882af2071..7d7ec86cc2 100644
--- a/source3/lib/talloc.c
+++ b/source3/lib/talloc.c
@@ -49,6 +49,65 @@
#include "includes.h"
+struct talloc_chunk {
+ struct talloc_chunk *next;
+ size_t size;
+ void *ptr;
+};
+
+
+struct talloc_ctx {
+ struct talloc_chunk *list;
+ size_t total_alloc_size;
+
+ /** The name recorded for this pool, if any. Should describe
+ * the purpose for which it was allocated. The string is
+ * allocated within the pool. **/
+ char *name;
+
+ /** Pointer to the next allocate talloc pool, so that we can
+ * summarize all talloc memory usage. **/
+ struct talloc_ctx *next_ctx;
+};
+
+
+/**
+ * Start of linked list of all talloc pools.
+ **/
+TALLOC_CTX *list_head = NULL;
+
+
+/**
+ * Add to the global list
+ **/
+static void talloc_enroll(TALLOC_CTX *t)
+{
+ t->next_ctx = list_head;
+ list_head = t;
+}
+
+
+static void talloc_disenroll(TALLOC_CTX *t)
+{
+ TALLOC_CTX **ttmp;
+
+ /* Use a double-* so that no special case is required for the
+ * list head. */
+ for (ttmp = &list_head; *ttmp; ttmp = &((*ttmp)->next_ctx))
+ if (*ttmp == t) {
+ /* ttmp is the link that points to t, either
+ * list_head or the next_ctx link in its
+ * predecessor */
+ *ttmp = t->next_ctx;
+ t->next_ctx = NULL; /* clobber */
+ return;
+ }
+ abort(); /* oops, this talloc was already
+ * clobbered or something else went
+ * wrong. */
+}
+
+
/** Create a new talloc context. **/
TALLOC_CTX *talloc_init(void)
{
@@ -59,6 +118,8 @@ TALLOC_CTX *talloc_init(void)
t->list = NULL;
t->total_alloc_size = 0;
+ t->name = NULL;
+ talloc_enroll(t);
return t;
}
@@ -75,10 +136,12 @@ TALLOC_CTX *talloc_init(void)
va_list ap;
t = talloc_init();
- va_start(ap, fmt);
- t->name = talloc_vasprintf(t, fmt, ap);
- va_end(ap);
-
+ if (fmt) {
+ va_start(ap, fmt);
+ t->name = talloc_vasprintf(t, fmt, ap);
+ va_end(ap);
+ }
+
return t;
}
@@ -161,6 +224,7 @@ void talloc_destroy(TALLOC_CTX *t)
if (!t)
return;
talloc_destroy_pool(t);
+ talloc_disenroll(t);
memset(t, 0, sizeof(*t));
SAFE_FREE(t);
}
@@ -171,6 +235,12 @@ size_t talloc_pool_size(TALLOC_CTX *t)
return t->total_alloc_size;
}
+const char * talloc_pool_name(TALLOC_CTX const *t)
+{
+ return t->name;
+}
+
+
/** talloc and zero memory. */
void *talloc_zero(TALLOC_CTX *t, size_t size)
{
diff --git a/source3/lib/talloctort.c b/source3/lib/talloctort.c
index 61f9532f6e..f43a4e4f9f 100644
--- a/source3/lib/talloctort.c
+++ b/source3/lib/talloctort.c
@@ -41,16 +41,21 @@ int main(void)
p = talloc(ctx[i], size);
if (!p) {
fprintf(stderr,
- "failed to talloc %0.f bytes\n", size);
+ "failed to talloc %.0f bytes\n",
+ (double) size);
exit(1);
}
}
}
for (i = 0; i < NCTX; i++) {
- printf("talloc@%p %-40s %db\n", ctx[i], ctx[i]->name,
- ctx[i]->total_alloc_size);
+ printf("talloc@%p %-40s %db\n", ctx[i],
+ talloc_pool_name(ctx[i]),
+ talloc_pool_size(ctx[i]));
}
+ for (i = NCTX - 1; i >= 0; i--)
+ talloc_destroy(ctx[i]);
+
return 0;
}