diff options
-rw-r--r-- | source3/include/talloc.h | 17 | ||||
-rw-r--r-- | source3/lib/talloc.c | 78 | ||||
-rw-r--r-- | source3/lib/talloctort.c | 11 |
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; } |