2 Samba Unix SMB/CIFS implementation.
4 Samba trivial allocation library - new interface
6 NOTE: Please read talloc_guide.txt for full documentation
8 Copyright (C) Andrew Tridgell 2004
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 inspired by http://swapped.cc/halloc/
39 /* assume a modern system */
43 /* use this to force every realloc to change the pointer, to stress test
44 code that might not cope */
45 #define ALWAYS_REALLOC 0
48 #define MAX_TALLOC_SIZE 0x10000000
49 #define TALLOC_MAGIC 0xe814ec4f
50 #define TALLOC_MAGIC_FREE 0x7faebef3
51 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
53 /* by default we abort when given a bad pointer (such as when talloc_free() is called
54 on a pointer that came from malloc() */
56 #define TALLOC_ABORT(reason) abort()
59 #ifndef discard_const_p
60 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
61 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
63 # define discard_const_p(type, ptr) ((type *)(ptr))
67 /* this null_context is only used if talloc_enable_leak_report() or
68 talloc_enable_leak_report_full() is called, otherwise it remains
71 static const void *null_context;
72 static void *cleanup_context;
75 struct talloc_reference_handle {
76 struct talloc_reference_handle *next, *prev;
80 typedef int (*talloc_destructor_t)(void *);
83 struct talloc_chunk *next, *prev;
84 struct talloc_chunk *parent, *child;
85 struct talloc_reference_handle *refs;
88 talloc_destructor_t destructor;
92 /* panic if we get a bad magic value */
93 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
95 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
96 if (tc->magic != TALLOC_MAGIC) {
97 if (tc->magic == TALLOC_MAGIC_FREE) {
98 TALLOC_ABORT("Bad talloc magic value - double free");
100 TALLOC_ABORT("Bad talloc magic value - unknown value");
107 /* hook into the front of the list */
108 #define _TLIST_ADD(list, p) \
112 (p)->next = (p)->prev = NULL; \
114 (list)->prev = (p); \
115 (p)->next = (list); \
121 /* remove an element from a list - element doesn't have to be in list. */
122 #define _TLIST_REMOVE(list, p) \
124 if ((p) == (list)) { \
125 (list) = (p)->next; \
126 if (list) (list)->prev = NULL; \
128 if ((p)->prev) (p)->prev->next = (p)->next; \
129 if ((p)->next) (p)->next->prev = (p)->prev; \
131 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
136 return the parent chunk of a pointer
138 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
140 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
141 while (tc->prev) tc=tc->prev;
145 void *talloc_parent(const void *ptr)
147 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
148 return (void *)(tc+1);
152 Allocate a bit of memory as a child of an existing pointer
154 void *_talloc(const void *context, size_t size)
156 struct talloc_chunk *tc;
158 if (context == NULL) {
159 context = null_context;
162 if (size >= MAX_TALLOC_SIZE) {
166 tc = malloc(sizeof(*tc)+size);
167 if (tc == NULL) return NULL;
170 tc->magic = TALLOC_MAGIC;
171 tc->destructor = NULL;
177 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
182 parent->child->parent = NULL;
185 _TLIST_ADD(parent->child, tc);
187 tc->next = tc->prev = tc->parent = NULL;
190 return (void *)(tc+1);
195 setup a destructor to be called on free of a pointer
196 the destructor should return 0 on success, or -1 on failure.
197 if the destructor fails then the free is failed, and the memory can
198 be continued to be used
200 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
202 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
203 tc->destructor = destructor;
207 increase the reference count on a piece of memory.
209 void talloc_increase_ref_count(const void *ptr)
211 talloc_reference(null_context, ptr);
215 helper for talloc_reference()
217 static int talloc_reference_destructor(void *ptr)
219 struct talloc_reference_handle *handle = ptr;
220 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
221 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
222 if (tc1->destructor != (talloc_destructor_t)-1) {
223 tc1->destructor = NULL;
225 _TLIST_REMOVE(tc2->refs, handle);
231 make a secondary reference to a pointer, hanging off the given context.
232 the pointer remains valid until both the original caller and this given
235 the major use for this is when two different structures need to reference the
236 same underlying data, and you want to be able to free the two instances separately,
239 void *talloc_reference(const void *context, const void *ptr)
241 struct talloc_chunk *tc;
242 struct talloc_reference_handle *handle;
243 if (ptr == NULL) return NULL;
245 tc = talloc_chunk_from_ptr(ptr);
246 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
248 if (handle == NULL) return NULL;
250 /* note that we hang the destructor off the handle, not the
251 main context as that allows the caller to still setup their
252 own destructor on the context if they want to */
253 talloc_set_destructor(handle, talloc_reference_destructor);
254 handle->ptr = discard_const_p(void, ptr);
255 _TLIST_ADD(tc->refs, handle);
260 remove a secondary reference to a pointer. This undo's what
261 talloc_reference() has done. The context and pointer arguments
262 must match those given to a talloc_reference()
264 static int talloc_unreference(const void *context, const void *ptr)
266 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
267 struct talloc_reference_handle *h;
269 if (context == NULL) {
270 context = null_context;
273 for (h=tc->refs;h;h=h->next) {
274 struct talloc_chunk *p = talloc_parent_chunk(h);
275 if ((p==NULL && context==NULL) || p+1 == context) break;
281 talloc_set_destructor(h, NULL);
282 _TLIST_REMOVE(tc->refs, h);
288 remove a specific parent context from a pointer. This is a more
289 controlled varient of talloc_free()
291 int talloc_unlink(const void *context, void *ptr)
293 struct talloc_chunk *tc_p, *new_p;
300 if (context == NULL) {
301 context = null_context;
304 if (talloc_unreference(context, ptr) == 0) {
308 if (context == NULL) {
309 if (talloc_parent_chunk(ptr) != NULL) {
313 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
318 tc_p = talloc_chunk_from_ptr(ptr);
320 if (tc_p->refs == NULL) {
321 return talloc_free(ptr);
324 new_p = talloc_parent_chunk(tc_p->refs);
326 new_parent = new_p+1;
331 if (talloc_unreference(new_parent, ptr) != 0) {
335 talloc_steal(new_parent, ptr);
341 add a name to an existing pointer - va_list version
343 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
345 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
347 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
348 tc->name = talloc_vasprintf(ptr, fmt, ap);
350 talloc_set_name_const(tc->name, ".name");
355 add a name to an existing pointer
357 void talloc_set_name(const void *ptr, const char *fmt, ...)
361 talloc_set_name_v(ptr, fmt, ap);
366 more efficient way to add a name to a pointer - the name must point to a
369 void talloc_set_name_const(const void *ptr, const char *name)
371 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
376 create a named talloc pointer. Any talloc pointer can be named, and
377 talloc_named() operates just like talloc() except that it allows you
380 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
385 ptr = _talloc(context, size);
386 if (ptr == NULL) return NULL;
389 talloc_set_name_v(ptr, fmt, ap);
396 create a named talloc pointer. Any talloc pointer can be named, and
397 talloc_named() operates just like talloc() except that it allows you
400 void *talloc_named_const(const void *context, size_t size, const char *name)
404 ptr = _talloc(context, size);
409 talloc_set_name_const(ptr, name);
415 return the name of a talloc ptr, or "UNNAMED"
417 const char *talloc_get_name(const void *ptr)
419 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
420 if (tc->name == TALLOC_MAGIC_REFERENCE) {
431 check if a pointer has the given name. If it does, return the pointer,
432 otherwise return NULL
434 void *talloc_check_name(const void *ptr, const char *name)
437 if (ptr == NULL) return NULL;
438 pname = talloc_get_name(ptr);
439 if (pname == name || strcmp(pname, name) == 0) {
440 return discard_const_p(void, ptr);
447 this is for compatibility with older versions of talloc
449 void *talloc_init(const char *fmt, ...)
454 ptr = _talloc(NULL, 0);
455 if (ptr == NULL) return NULL;
458 talloc_set_name_v(ptr, fmt, ap);
466 free a talloc pointer. This also frees all child pointers of this
469 return 0 if the memory is actually freed, otherwise -1. The memory
470 will not be freed if the ref_count is > 1 or the destructor (if
471 any) returns non-zero
473 int talloc_free(void *ptr)
475 struct talloc_chunk *tc;
481 tc = talloc_chunk_from_ptr(ptr);
484 talloc_reference_destructor(tc->refs);
488 if (tc->destructor) {
489 talloc_destructor_t d = tc->destructor;
490 if (d == (talloc_destructor_t)-1) {
493 tc->destructor = (talloc_destructor_t)-1;
498 tc->destructor = NULL;
502 /* we need to work out who will own an abandoned child
503 if it cannot be freed. In priority order, the first
504 choice is owner of any remaining reference to this
505 pointer, the second choice is our parent, and the
506 final choice is the null context. */
507 void *child = tc->child+1;
508 const void *new_parent = null_context;
509 if (tc->child->refs) {
510 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
511 if (p) new_parent = p+1;
513 if (talloc_free(child) == -1) {
514 if (new_parent == null_context) {
515 struct talloc_chunk *p = talloc_parent_chunk(ptr);
516 if (p) new_parent = p+1;
518 talloc_steal(new_parent, child);
523 _TLIST_REMOVE(tc->parent->child, tc);
524 if (tc->parent->child) {
525 tc->parent->child->parent = tc->parent;
528 if (tc->prev) tc->prev->next = tc->next;
529 if (tc->next) tc->next->prev = tc->prev;
532 tc->magic = TALLOC_MAGIC_FREE;
541 A talloc version of realloc. The context argument is only used if
544 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
546 struct talloc_chunk *tc;
549 /* size zero is equivalent to free() */
555 if (size >= MAX_TALLOC_SIZE) {
559 /* realloc(NULL) is equavalent to malloc() */
561 return talloc_named_const(context, size, name);
564 tc = talloc_chunk_from_ptr(ptr);
566 /* don't allow realloc on referenced pointers */
571 /* by resetting magic we catch users of the old memory */
572 tc->magic = TALLOC_MAGIC_FREE;
575 new_ptr = malloc(size + sizeof(*tc));
577 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
581 new_ptr = realloc(tc, size + sizeof(*tc));
584 tc->magic = TALLOC_MAGIC;
589 tc->magic = TALLOC_MAGIC;
591 tc->parent->child = new_ptr;
594 tc->child->parent = new_ptr;
605 talloc_set_name_const(tc+1, name);
607 return (void *)(tc+1);
611 move a lump of memory from one talloc context to another return the
612 ptr on success, or NULL if it could not be transferred
614 void *talloc_steal(const void *new_ctx, const void *ptr)
616 struct talloc_chunk *tc, *new_tc;
622 if (new_ctx == NULL) {
623 new_ctx = null_context;
626 tc = talloc_chunk_from_ptr(ptr);
628 if (new_ctx == NULL) {
630 _TLIST_REMOVE(tc->parent->child, tc);
631 if (tc->parent->child) {
632 tc->parent->child->parent = tc->parent;
635 if (tc->prev) tc->prev->next = tc->next;
636 if (tc->next) tc->next->prev = tc->prev;
639 tc->parent = tc->next = tc->prev = NULL;
640 return discard_const_p(void, ptr);
643 new_tc = talloc_chunk_from_ptr(new_ctx);
646 return discard_const_p(void, ptr);
650 _TLIST_REMOVE(tc->parent->child, tc);
651 if (tc->parent->child) {
652 tc->parent->child->parent = tc->parent;
655 if (tc->prev) tc->prev->next = tc->next;
656 if (tc->next) tc->next->prev = tc->prev;
660 if (new_tc->child) new_tc->child->parent = NULL;
661 _TLIST_ADD(new_tc->child, tc);
663 return discard_const_p(void, ptr);
667 return the total size of a talloc pool (subtree)
669 off_t talloc_total_size(const void *ptr)
672 struct talloc_chunk *c, *tc;
681 tc = talloc_chunk_from_ptr(ptr);
684 for (c=tc->child;c;c=c->next) {
685 total += talloc_total_size(c+1);
691 return the total number of blocks in a talloc pool (subtree)
693 off_t talloc_total_blocks(const void *ptr)
696 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
699 for (c=tc->child;c;c=c->next) {
700 total += talloc_total_blocks(c+1);
706 return the number of external references to a pointer
708 static int talloc_reference_count(const void *ptr)
710 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
711 struct talloc_reference_handle *h;
714 for (h=tc->refs;h;h=h->next) {
721 report on memory usage by all children of a pointer, giving a full tree view
723 void talloc_report_depth(const void *ptr, FILE *f, int depth)
725 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
727 for (c=tc->child;c;c=c->next) {
728 if (c->name == TALLOC_MAGIC_REFERENCE) {
729 struct talloc_reference_handle *handle = (void *)(c+1);
730 const char *name2 = talloc_get_name(handle->ptr);
731 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
733 const char *name = talloc_get_name(c+1);
734 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
737 (unsigned long)talloc_total_size(c+1),
738 (unsigned long)talloc_total_blocks(c+1),
739 talloc_reference_count(c+1));
740 talloc_report_depth(c+1, f, depth+1);
747 report on memory usage by all children of a pointer, giving a full tree view
749 void talloc_report_full(const void *ptr, FILE *f)
754 if (ptr == NULL) return;
756 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
757 talloc_get_name(ptr),
758 (unsigned long)talloc_total_size(ptr),
759 (unsigned long)talloc_total_blocks(ptr));
761 talloc_report_depth(ptr, f, 1);
766 report on memory usage by all children of a pointer
768 void talloc_report(const void *ptr, FILE *f)
770 struct talloc_chunk *c, *tc;
775 if (ptr == NULL) return;
777 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
778 talloc_get_name(ptr),
779 (unsigned long)talloc_total_size(ptr),
780 (unsigned long)talloc_total_blocks(ptr));
782 tc = talloc_chunk_from_ptr(ptr);
784 for (c=tc->child;c;c=c->next) {
785 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
786 talloc_get_name(c+1),
787 (unsigned long)talloc_total_size(c+1),
788 (unsigned long)talloc_total_blocks(c+1));
794 report on any memory hanging off the null context
796 static void talloc_report_null(void)
798 if (talloc_total_size(null_context) != 0) {
799 talloc_report(null_context, stderr);
804 report on any memory hanging off the null context
806 static void talloc_report_null_full(void)
808 if (talloc_total_size(null_context) != 0) {
809 talloc_report_full(null_context, stderr);
814 enable leak reporting on exit
816 void talloc_enable_leak_report(void)
818 null_context = talloc_named_const(NULL, 0, "null_context");
819 atexit(talloc_report_null);
823 enable full leak reporting on exit
825 void talloc_enable_leak_report_full(void)
827 null_context = talloc_named_const(NULL, 0, "null_context");
828 atexit(talloc_report_null_full);
832 talloc and zero memory.
834 void *_talloc_zero(const void *ctx, size_t size, const char *name)
836 void *p = talloc_named_const(ctx, size, name);
839 memset(p, '\0', size);
847 memdup with a talloc.
849 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
851 void *newp = talloc_named_const(t, size, name);
854 memcpy(newp, p, size);
863 char *talloc_strdup(const void *t, const char *p)
869 ret = talloc_memdup(t, p, strlen(p) + 1);
871 talloc_set_name_const(ret, ret);
877 strndup with a talloc
879 char *talloc_strndup(const void *t, const char *p, size_t n)
884 for (len=0; p[len] && len<n; len++) ;
886 ret = _talloc(t, len + 1);
887 if (!ret) { return NULL; }
890 talloc_set_name_const(ret, ret);
896 #define VA_COPY(dest, src) va_copy(dest, src)
897 #elif defined(HAVE___VA_COPY)
898 #define VA_COPY(dest, src) __va_copy(dest, src)
900 #define VA_COPY(dest, src) (dest) = (src)
904 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
912 len = vsnprintf(NULL, 0, fmt, ap2);
914 ret = _talloc(t, len+1);
917 vsnprintf(ret, len+1, fmt, ap2);
918 talloc_set_name_const(ret, ret);
926 Perform string formatting, and return a pointer to newly allocated
927 memory holding the result, inside a memory pool.
929 char *talloc_asprintf(const void *t, const char *fmt, ...)
935 ret = talloc_vasprintf(t, fmt, ap);
942 * Realloc @p s to append the formatted result of @p fmt and @p ap,
943 * and return @p s, which may have moved. Good for gradually
944 * accumulating output into a string buffer.
947 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
949 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
951 struct talloc_chunk *tc;
956 return talloc_vasprintf(NULL, fmt, ap);
959 tc = talloc_chunk_from_ptr(s);
963 s_len = tc->size - 1;
964 len = vsnprintf(NULL, 0, fmt, ap2);
966 s = talloc_realloc(NULL, s, char, s_len + len+1);
971 vsnprintf(s+s_len, len+1, fmt, ap2);
972 talloc_set_name_const(s, s);
978 Realloc @p s to append the formatted result of @p fmt and return @p
979 s, which may have moved. Good for gradually accumulating output
980 into a string buffer.
982 char *talloc_asprintf_append(char *s, const char *fmt, ...)
987 s = talloc_vasprintf_append(s, fmt, ap);
993 alloc an array, checking for integer overflow in the array size
995 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
997 if (count >= MAX_TALLOC_SIZE/el_size) {
1000 return talloc_named_const(ctx, el_size * count, name);
1004 alloc an zero array, checking for integer overflow in the array size
1006 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1008 if (count >= MAX_TALLOC_SIZE/el_size) {
1011 return _talloc_zero(ctx, el_size * count, name);
1016 realloc an array, checking for integer overflow in the array size
1018 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1020 if (count >= MAX_TALLOC_SIZE/el_size) {
1023 return _talloc_realloc(ctx, ptr, el_size * count, name);
1027 a function version of talloc_realloc(), so it can be passed as a function pointer
1028 to libraries that want a realloc function (a realloc function encapsulates
1029 all the basic capabilities of an allocation library, which is why this is useful)
1031 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1033 return _talloc_realloc(context, ptr, size, NULL);
1037 static void talloc_autofree(void)
1039 talloc_free(cleanup_context);
1040 cleanup_context = NULL;
1044 return a context which will be auto-freed on exit
1045 this is useful for reducing the noise in leak reports
1047 void *talloc_autofree_context(void)
1049 if (cleanup_context == NULL) {
1050 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1051 atexit(talloc_autofree);
1053 return cleanup_context;