Fix warnings on SuSE 9.0.
[Samba.git] / source / lib / talloc / talloc.c
blob99210f3e1bd6362b61561a776d12118499326632
1 /*
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
9 Copyright (C) Stefan Metzmacher 2006
11 ** NOTE! The following LGPL license applies to the talloc
12 ** library. This does NOT imply that all of Samba is released
13 ** under the LGPL
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 3 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, see <http://www.gnu.org/licenses/>.
30 inspired by http://swapped.cc/halloc/
33 #ifdef _SAMBA_BUILD_
34 #include "version.h"
35 #if (SAMBA_VERSION_MAJOR<4)
36 #include "includes.h"
37 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
38 * we trust ourselves... */
39 #ifdef malloc
40 #undef malloc
41 #endif
42 #ifdef realloc
43 #undef realloc
44 #endif
45 #define _TALLOC_SAMBA3
46 #endif /* (SAMBA_VERSION_MAJOR<4) */
47 #endif /* _SAMBA_BUILD_ */
49 #ifndef _TALLOC_SAMBA3
50 #include "replace.h"
51 #include "talloc.h"
52 #endif /* not _TALLOC_SAMBA3 */
54 /* use this to force every realloc to change the pointer, to stress test
55 code that might not cope */
56 #define ALWAYS_REALLOC 0
59 #define MAX_TALLOC_SIZE 0x10000000
60 #define TALLOC_MAGIC 0xe814ec70
61 #define TALLOC_FLAG_FREE 0x01
62 #define TALLOC_FLAG_LOOP 0x02
63 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
64 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
65 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
67 /* by default we abort when given a bad pointer (such as when talloc_free() is called
68 on a pointer that came from malloc() */
69 #ifndef TALLOC_ABORT
70 #define TALLOC_ABORT(reason) abort()
71 #endif
73 #ifndef discard_const_p
74 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
75 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
76 #else
77 # define discard_const_p(type, ptr) ((type *)(ptr))
78 #endif
79 #endif
81 /* these macros gain us a few percent of speed on gcc */
82 #if (__GNUC__ >= 3)
83 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
84 as its first argument */
85 #ifndef likely
86 #define likely(x) __builtin_expect(!!(x), 1)
87 #endif
88 #ifndef unlikely
89 #define unlikely(x) __builtin_expect(!!(x), 0)
90 #endif
91 #else
92 #ifndef likely
93 #define likely(x) (x)
94 #endif
95 #ifndef unlikely
96 #define unlikely(x) (x)
97 #endif
98 #endif
100 /* this null_context is only used if talloc_enable_leak_report() or
101 talloc_enable_leak_report_full() is called, otherwise it remains
102 NULL
104 static void *null_context;
105 static void *autofree_context;
107 struct talloc_reference_handle {
108 struct talloc_reference_handle *next, *prev;
109 void *ptr;
112 typedef int (*talloc_destructor_t)(void *);
114 struct talloc_chunk {
115 struct talloc_chunk *next, *prev;
116 struct talloc_chunk *parent, *child;
117 struct talloc_reference_handle *refs;
118 talloc_destructor_t destructor;
119 const char *name;
120 size_t size;
121 unsigned flags;
124 * "pool" has dual use:
126 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
127 * marks the end of the currently allocated area.
129 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
130 * is a pointer to the struct talloc_chunk of the pool that it was
131 * allocated from. This way children can quickly find the pool to chew
132 * from.
134 void *pool;
137 /* 16 byte alignment seems to keep everyone happy */
138 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
139 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
141 static void talloc_abort_double_free(void)
143 TALLOC_ABORT("Bad talloc magic value - double free");
146 static void talloc_abort_unknown_value(void)
148 TALLOC_ABORT("Bad talloc magic value - unknown value");
151 /* panic if we get a bad magic value */
152 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
154 const char *pp = (const char *)ptr;
155 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
156 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
157 if (tc->flags & TALLOC_FLAG_FREE) {
158 talloc_abort_double_free();
159 } else {
160 talloc_abort_unknown_value();
163 return tc;
166 /* hook into the front of the list */
167 #define _TLIST_ADD(list, p) \
168 do { \
169 if (!(list)) { \
170 (list) = (p); \
171 (p)->next = (p)->prev = NULL; \
172 } else { \
173 (list)->prev = (p); \
174 (p)->next = (list); \
175 (p)->prev = NULL; \
176 (list) = (p); \
178 } while (0)
180 /* remove an element from a list - element doesn't have to be in list. */
181 #define _TLIST_REMOVE(list, p) \
182 do { \
183 if ((p) == (list)) { \
184 (list) = (p)->next; \
185 if (list) (list)->prev = NULL; \
186 } else { \
187 if ((p)->prev) (p)->prev->next = (p)->next; \
188 if ((p)->next) (p)->next->prev = (p)->prev; \
190 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
191 } while (0)
195 return the parent chunk of a pointer
197 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
199 struct talloc_chunk *tc;
201 if (unlikely(ptr == NULL)) {
202 return NULL;
205 tc = talloc_chunk_from_ptr(ptr);
206 while (tc->prev) tc=tc->prev;
208 return tc->parent;
211 void *talloc_parent(const void *ptr)
213 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
214 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
218 find parents name
220 const char *talloc_parent_name(const void *ptr)
222 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
223 return tc? tc->name : NULL;
227 A pool carries an in-pool object count count in the first 16 bytes.
228 bytes. This is done to support talloc_steal() to a parent outside of the
229 pool. The count includes the pool itself, so a talloc_free() on a pool will
230 only destroy the pool if the count has dropped to zero. A talloc_free() of a
231 pool member will reduce the count, and eventually also call free(3) on the
232 pool memory.
234 The object count is not put into "struct talloc_chunk" because it is only
235 relevant for talloc pools and the alignment to 16 bytes would increase the
236 memory footprint of each talloc chunk by those 16 bytes.
239 #define TALLOC_POOL_HDR_SIZE 16
241 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
243 return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
247 Allocate from a pool
250 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
251 size_t size)
253 struct talloc_chunk *pool_ctx = NULL;
254 size_t space_left;
255 struct talloc_chunk *result;
256 size_t chunk_size;
258 if (parent == NULL) {
259 return NULL;
262 if (parent->flags & TALLOC_FLAG_POOL) {
263 pool_ctx = parent;
265 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
266 pool_ctx = (struct talloc_chunk *)parent->pool;
269 if (pool_ctx == NULL) {
270 return NULL;
273 space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
274 - ((char *)pool_ctx->pool);
277 * Align size to 16 bytes
279 chunk_size = ((size + 15) & ~15);
281 if (space_left < chunk_size) {
282 return NULL;
285 result = (struct talloc_chunk *)pool_ctx->pool;
287 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
288 VALGRIND_MAKE_MEM_UNDEFINED(result, size);
289 #endif
291 pool_ctx->pool = (void *)((char *)result + chunk_size);
293 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
294 result->pool = pool_ctx;
296 *talloc_pool_objectcount(pool_ctx) += 1;
298 return result;
302 Allocate a bit of memory as a child of an existing pointer
304 static inline void *__talloc(const void *context, size_t size)
306 struct talloc_chunk *tc = NULL;
308 if (unlikely(context == NULL)) {
309 context = null_context;
312 if (unlikely(size >= MAX_TALLOC_SIZE)) {
313 return NULL;
316 if (context != NULL) {
317 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
318 TC_HDR_SIZE+size);
321 if (tc == NULL) {
322 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
323 if (unlikely(tc == NULL)) return NULL;
324 tc->flags = TALLOC_MAGIC;
325 tc->pool = NULL;
328 tc->size = size;
329 tc->destructor = NULL;
330 tc->child = NULL;
331 tc->name = NULL;
332 tc->refs = NULL;
334 if (likely(context)) {
335 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
337 if (parent->child) {
338 parent->child->parent = NULL;
339 tc->next = parent->child;
340 tc->next->prev = tc;
341 } else {
342 tc->next = NULL;
344 tc->parent = parent;
345 tc->prev = NULL;
346 parent->child = tc;
347 } else {
348 tc->next = tc->prev = tc->parent = NULL;
351 return TC_PTR_FROM_CHUNK(tc);
355 * Create a talloc pool
358 void *talloc_pool(const void *context, size_t size)
360 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
361 struct talloc_chunk *tc;
363 if (unlikely(result == NULL)) {
364 return NULL;
367 tc = talloc_chunk_from_ptr(result);
369 tc->flags |= TALLOC_FLAG_POOL;
370 tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
372 *talloc_pool_objectcount(tc) = 1;
374 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
375 VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
376 #endif
378 return result;
382 setup a destructor to be called on free of a pointer
383 the destructor should return 0 on success, or -1 on failure.
384 if the destructor fails then the free is failed, and the memory can
385 be continued to be used
387 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
389 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
390 tc->destructor = destructor;
394 increase the reference count on a piece of memory.
396 int talloc_increase_ref_count(const void *ptr)
398 if (unlikely(!talloc_reference(null_context, ptr))) {
399 return -1;
401 return 0;
405 helper for talloc_reference()
407 this is referenced by a function pointer and should not be inline
409 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
411 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
412 _TLIST_REMOVE(ptr_tc->refs, handle);
413 return 0;
417 more efficient way to add a name to a pointer - the name must point to a
418 true string constant
420 static inline void _talloc_set_name_const(const void *ptr, const char *name)
422 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
423 tc->name = name;
427 internal talloc_named_const()
429 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
431 void *ptr;
433 ptr = __talloc(context, size);
434 if (unlikely(ptr == NULL)) {
435 return NULL;
438 _talloc_set_name_const(ptr, name);
440 return ptr;
444 make a secondary reference to a pointer, hanging off the given context.
445 the pointer remains valid until both the original caller and this given
446 context are freed.
448 the major use for this is when two different structures need to reference the
449 same underlying data, and you want to be able to free the two instances separately,
450 and in either order
452 void *_talloc_reference(const void *context, const void *ptr)
454 struct talloc_chunk *tc;
455 struct talloc_reference_handle *handle;
456 if (unlikely(ptr == NULL)) return NULL;
458 tc = talloc_chunk_from_ptr(ptr);
459 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
460 sizeof(struct talloc_reference_handle),
461 TALLOC_MAGIC_REFERENCE);
462 if (unlikely(handle == NULL)) return NULL;
464 /* note that we hang the destructor off the handle, not the
465 main context as that allows the caller to still setup their
466 own destructor on the context if they want to */
467 talloc_set_destructor(handle, talloc_reference_destructor);
468 handle->ptr = discard_const_p(void, ptr);
469 _TLIST_ADD(tc->refs, handle);
470 return handle->ptr;
475 internal talloc_free call
477 static inline int _talloc_free(void *ptr)
479 struct talloc_chunk *tc;
481 if (unlikely(ptr == NULL)) {
482 return -1;
485 tc = talloc_chunk_from_ptr(ptr);
487 if (unlikely(tc->refs)) {
488 int is_child;
489 /* check this is a reference from a child or grantchild
490 * back to it's parent or grantparent
492 * in that case we need to remove the reference and
493 * call another instance of talloc_free() on the current
494 * pointer.
496 is_child = talloc_is_parent(tc->refs, ptr);
497 _talloc_free(tc->refs);
498 if (is_child) {
499 return _talloc_free(ptr);
501 return -1;
504 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
505 /* we have a free loop - stop looping */
506 return 0;
509 if (unlikely(tc->destructor)) {
510 talloc_destructor_t d = tc->destructor;
511 if (d == (talloc_destructor_t)-1) {
512 return -1;
514 tc->destructor = (talloc_destructor_t)-1;
515 if (d(ptr) == -1) {
516 tc->destructor = d;
517 return -1;
519 tc->destructor = NULL;
522 if (tc->parent) {
523 _TLIST_REMOVE(tc->parent->child, tc);
524 if (tc->parent->child) {
525 tc->parent->child->parent = tc->parent;
527 } else {
528 if (tc->prev) tc->prev->next = tc->next;
529 if (tc->next) tc->next->prev = tc->prev;
532 tc->flags |= TALLOC_FLAG_LOOP;
534 while (tc->child) {
535 /* we need to work out who will own an abandoned child
536 if it cannot be freed. In priority order, the first
537 choice is owner of any remaining reference to this
538 pointer, the second choice is our parent, and the
539 final choice is the null context. */
540 void *child = TC_PTR_FROM_CHUNK(tc->child);
541 const void *new_parent = null_context;
542 if (unlikely(tc->child->refs)) {
543 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
544 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
546 if (unlikely(_talloc_free(child) == -1)) {
547 if (new_parent == null_context) {
548 struct talloc_chunk *p = talloc_parent_chunk(ptr);
549 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
551 talloc_steal(new_parent, child);
555 tc->flags |= TALLOC_FLAG_FREE;
557 if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
558 struct talloc_chunk *pool;
559 unsigned int *pool_object_count;
561 pool = (tc->flags & TALLOC_FLAG_POOL)
562 ? tc : (struct talloc_chunk *)tc->pool;
564 pool_object_count = talloc_pool_objectcount(pool);
566 if (*pool_object_count == 0) {
567 TALLOC_ABORT("Pool object count zero!");
570 *pool_object_count -= 1;
572 if (*pool_object_count == 0) {
573 free(pool);
576 else {
577 free(tc);
579 return 0;
583 move a lump of memory from one talloc context to another return the
584 ptr on success, or NULL if it could not be transferred.
585 passing NULL as ptr will always return NULL with no side effects.
587 void *_talloc_steal(const void *new_ctx, const void *ptr)
589 struct talloc_chunk *tc, *new_tc;
591 if (unlikely(!ptr)) {
592 return NULL;
595 if (unlikely(new_ctx == NULL)) {
596 new_ctx = null_context;
599 tc = talloc_chunk_from_ptr(ptr);
601 if (unlikely(new_ctx == NULL)) {
602 if (tc->parent) {
603 _TLIST_REMOVE(tc->parent->child, tc);
604 if (tc->parent->child) {
605 tc->parent->child->parent = tc->parent;
607 } else {
608 if (tc->prev) tc->prev->next = tc->next;
609 if (tc->next) tc->next->prev = tc->prev;
612 tc->parent = tc->next = tc->prev = NULL;
613 return discard_const_p(void, ptr);
616 new_tc = talloc_chunk_from_ptr(new_ctx);
618 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
619 return discard_const_p(void, ptr);
622 if (tc->parent) {
623 _TLIST_REMOVE(tc->parent->child, tc);
624 if (tc->parent->child) {
625 tc->parent->child->parent = tc->parent;
627 } else {
628 if (tc->prev) tc->prev->next = tc->next;
629 if (tc->next) tc->next->prev = tc->prev;
632 tc->parent = new_tc;
633 if (new_tc->child) new_tc->child->parent = NULL;
634 _TLIST_ADD(new_tc->child, tc);
636 return discard_const_p(void, ptr);
642 remove a secondary reference to a pointer. This undo's what
643 talloc_reference() has done. The context and pointer arguments
644 must match those given to a talloc_reference()
646 static inline int talloc_unreference(const void *context, const void *ptr)
648 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
649 struct talloc_reference_handle *h;
651 if (unlikely(context == NULL)) {
652 context = null_context;
655 for (h=tc->refs;h;h=h->next) {
656 struct talloc_chunk *p = talloc_parent_chunk(h);
657 if (p == NULL) {
658 if (context == NULL) break;
659 } else if (TC_PTR_FROM_CHUNK(p) == context) {
660 break;
663 if (h == NULL) {
664 return -1;
667 return _talloc_free(h);
671 remove a specific parent context from a pointer. This is a more
672 controlled varient of talloc_free()
674 int talloc_unlink(const void *context, void *ptr)
676 struct talloc_chunk *tc_p, *new_p;
677 void *new_parent;
679 if (ptr == NULL) {
680 return -1;
683 if (context == NULL) {
684 context = null_context;
687 if (talloc_unreference(context, ptr) == 0) {
688 return 0;
691 if (context == NULL) {
692 if (talloc_parent_chunk(ptr) != NULL) {
693 return -1;
695 } else {
696 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
697 return -1;
701 tc_p = talloc_chunk_from_ptr(ptr);
703 if (tc_p->refs == NULL) {
704 return _talloc_free(ptr);
707 new_p = talloc_parent_chunk(tc_p->refs);
708 if (new_p) {
709 new_parent = TC_PTR_FROM_CHUNK(new_p);
710 } else {
711 new_parent = NULL;
714 if (talloc_unreference(new_parent, ptr) != 0) {
715 return -1;
718 talloc_steal(new_parent, ptr);
720 return 0;
724 add a name to an existing pointer - va_list version
726 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
728 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
730 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
731 tc->name = talloc_vasprintf(ptr, fmt, ap);
732 if (likely(tc->name)) {
733 _talloc_set_name_const(tc->name, ".name");
735 return tc->name;
739 add a name to an existing pointer
741 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
743 const char *name;
744 va_list ap;
745 va_start(ap, fmt);
746 name = talloc_set_name_v(ptr, fmt, ap);
747 va_end(ap);
748 return name;
753 create a named talloc pointer. Any talloc pointer can be named, and
754 talloc_named() operates just like talloc() except that it allows you
755 to name the pointer.
757 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
759 va_list ap;
760 void *ptr;
761 const char *name;
763 ptr = __talloc(context, size);
764 if (unlikely(ptr == NULL)) return NULL;
766 va_start(ap, fmt);
767 name = talloc_set_name_v(ptr, fmt, ap);
768 va_end(ap);
770 if (unlikely(name == NULL)) {
771 _talloc_free(ptr);
772 return NULL;
775 return ptr;
779 return the name of a talloc ptr, or "UNNAMED"
781 const char *talloc_get_name(const void *ptr)
783 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
784 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
785 return ".reference";
787 if (likely(tc->name)) {
788 return tc->name;
790 return "UNNAMED";
795 check if a pointer has the given name. If it does, return the pointer,
796 otherwise return NULL
798 void *talloc_check_name(const void *ptr, const char *name)
800 const char *pname;
801 if (unlikely(ptr == NULL)) return NULL;
802 pname = talloc_get_name(ptr);
803 if (likely(pname == name || strcmp(pname, name) == 0)) {
804 return discard_const_p(void, ptr);
806 return NULL;
811 this is for compatibility with older versions of talloc
813 void *talloc_init(const char *fmt, ...)
815 va_list ap;
816 void *ptr;
817 const char *name;
820 * samba3 expects talloc_report_depth_cb(NULL, ...)
821 * reports all talloc'ed memory, so we need to enable
822 * null_tracking
824 talloc_enable_null_tracking();
826 ptr = __talloc(NULL, 0);
827 if (unlikely(ptr == NULL)) return NULL;
829 va_start(ap, fmt);
830 name = talloc_set_name_v(ptr, fmt, ap);
831 va_end(ap);
833 if (unlikely(name == NULL)) {
834 _talloc_free(ptr);
835 return NULL;
838 return ptr;
842 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
843 should probably not be used in new code. It's in here to keep the talloc
844 code consistent across Samba 3 and 4.
846 void talloc_free_children(void *ptr)
848 struct talloc_chunk *tc;
850 if (unlikely(ptr == NULL)) {
851 return;
854 tc = talloc_chunk_from_ptr(ptr);
856 while (tc->child) {
857 /* we need to work out who will own an abandoned child
858 if it cannot be freed. In priority order, the first
859 choice is owner of any remaining reference to this
860 pointer, the second choice is our parent, and the
861 final choice is the null context. */
862 void *child = TC_PTR_FROM_CHUNK(tc->child);
863 const void *new_parent = null_context;
864 if (unlikely(tc->child->refs)) {
865 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
866 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
868 if (unlikely(_talloc_free(child) == -1)) {
869 if (new_parent == null_context) {
870 struct talloc_chunk *p = talloc_parent_chunk(ptr);
871 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
873 talloc_steal(new_parent, child);
877 if ((tc->flags & TALLOC_FLAG_POOL)
878 && (*talloc_pool_objectcount(tc) == 1)) {
879 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
880 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
881 VALGRIND_MAKE_MEM_NOACCESS(
882 tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
883 #endif
888 Allocate a bit of memory as a child of an existing pointer
890 void *_talloc(const void *context, size_t size)
892 return __talloc(context, size);
896 externally callable talloc_set_name_const()
898 void talloc_set_name_const(const void *ptr, const char *name)
900 _talloc_set_name_const(ptr, name);
904 create a named talloc pointer. Any talloc pointer can be named, and
905 talloc_named() operates just like talloc() except that it allows you
906 to name the pointer.
908 void *talloc_named_const(const void *context, size_t size, const char *name)
910 return _talloc_named_const(context, size, name);
914 free a talloc pointer. This also frees all child pointers of this
915 pointer recursively
917 return 0 if the memory is actually freed, otherwise -1. The memory
918 will not be freed if the ref_count is > 1 or the destructor (if
919 any) returns non-zero
921 int talloc_free(void *ptr)
923 return _talloc_free(ptr);
929 A talloc version of realloc. The context argument is only used if
930 ptr is NULL
932 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
934 struct talloc_chunk *tc;
935 void *new_ptr;
936 bool malloced = false;
938 /* size zero is equivalent to free() */
939 if (unlikely(size == 0)) {
940 _talloc_free(ptr);
941 return NULL;
944 if (unlikely(size >= MAX_TALLOC_SIZE)) {
945 return NULL;
948 /* realloc(NULL) is equivalent to malloc() */
949 if (ptr == NULL) {
950 return _talloc_named_const(context, size, name);
953 tc = talloc_chunk_from_ptr(ptr);
955 /* don't allow realloc on referenced pointers */
956 if (unlikely(tc->refs)) {
957 return NULL;
960 /* don't shrink if we have less than 1k to gain */
961 if ((size < tc->size) && ((tc->size - size) < 1024)) {
962 tc->size = size;
963 return ptr;
966 /* by resetting magic we catch users of the old memory */
967 tc->flags |= TALLOC_FLAG_FREE;
969 #if ALWAYS_REALLOC
970 new_ptr = malloc(size + TC_HDR_SIZE);
971 if (new_ptr) {
972 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
973 free(tc);
975 #else
976 if (tc->flags & TALLOC_FLAG_POOLMEM) {
978 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
979 *talloc_pool_objectcount((struct talloc_chunk *)
980 (tc->pool)) -= 1;
982 if (new_ptr == NULL) {
983 new_ptr = malloc(TC_HDR_SIZE+size);
984 malloced = true;
987 if (new_ptr) {
988 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
991 else {
992 new_ptr = realloc(tc, size + TC_HDR_SIZE);
994 #endif
995 if (unlikely(!new_ptr)) {
996 tc->flags &= ~TALLOC_FLAG_FREE;
997 return NULL;
1000 tc = (struct talloc_chunk *)new_ptr;
1001 tc->flags &= ~TALLOC_FLAG_FREE;
1002 if (malloced) {
1003 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1005 if (tc->parent) {
1006 tc->parent->child = tc;
1008 if (tc->child) {
1009 tc->child->parent = tc;
1012 if (tc->prev) {
1013 tc->prev->next = tc;
1015 if (tc->next) {
1016 tc->next->prev = tc;
1019 tc->size = size;
1020 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1022 return TC_PTR_FROM_CHUNK(tc);
1026 a wrapper around talloc_steal() for situations where you are moving a pointer
1027 between two structures, and want the old pointer to be set to NULL
1029 void *_talloc_move(const void *new_ctx, const void *_pptr)
1031 const void **pptr = discard_const_p(const void *,_pptr);
1032 void *ret = _talloc_steal(new_ctx, *pptr);
1033 (*pptr) = NULL;
1034 return ret;
1038 return the total size of a talloc pool (subtree)
1040 size_t talloc_total_size(const void *ptr)
1042 size_t total = 0;
1043 struct talloc_chunk *c, *tc;
1045 if (ptr == NULL) {
1046 ptr = null_context;
1048 if (ptr == NULL) {
1049 return 0;
1052 tc = talloc_chunk_from_ptr(ptr);
1054 if (tc->flags & TALLOC_FLAG_LOOP) {
1055 return 0;
1058 tc->flags |= TALLOC_FLAG_LOOP;
1060 total = tc->size;
1061 for (c=tc->child;c;c=c->next) {
1062 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1065 tc->flags &= ~TALLOC_FLAG_LOOP;
1067 return total;
1071 return the total number of blocks in a talloc pool (subtree)
1073 size_t talloc_total_blocks(const void *ptr)
1075 size_t total = 0;
1076 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1078 if (tc->flags & TALLOC_FLAG_LOOP) {
1079 return 0;
1082 tc->flags |= TALLOC_FLAG_LOOP;
1084 total++;
1085 for (c=tc->child;c;c=c->next) {
1086 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1089 tc->flags &= ~TALLOC_FLAG_LOOP;
1091 return total;
1095 return the number of external references to a pointer
1097 size_t talloc_reference_count(const void *ptr)
1099 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1100 struct talloc_reference_handle *h;
1101 size_t ret = 0;
1103 for (h=tc->refs;h;h=h->next) {
1104 ret++;
1106 return ret;
1110 report on memory usage by all children of a pointer, giving a full tree view
1112 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1113 void (*callback)(const void *ptr,
1114 int depth, int max_depth,
1115 int is_ref,
1116 void *private_data),
1117 void *private_data)
1119 struct talloc_chunk *c, *tc;
1121 if (ptr == NULL) {
1122 ptr = null_context;
1124 if (ptr == NULL) return;
1126 tc = talloc_chunk_from_ptr(ptr);
1128 if (tc->flags & TALLOC_FLAG_LOOP) {
1129 return;
1132 callback(ptr, depth, max_depth, 0, private_data);
1134 if (max_depth >= 0 && depth >= max_depth) {
1135 return;
1138 tc->flags |= TALLOC_FLAG_LOOP;
1139 for (c=tc->child;c;c=c->next) {
1140 if (c->name == TALLOC_MAGIC_REFERENCE) {
1141 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1142 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1143 } else {
1144 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1147 tc->flags &= ~TALLOC_FLAG_LOOP;
1150 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1152 const char *name = talloc_get_name(ptr);
1153 FILE *f = (FILE *)_f;
1155 if (is_ref) {
1156 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1157 return;
1160 if (depth == 0) {
1161 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1162 (max_depth < 0 ? "full " :""), name,
1163 (unsigned long)talloc_total_size(ptr),
1164 (unsigned long)talloc_total_blocks(ptr));
1165 return;
1168 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1169 depth*4, "",
1170 name,
1171 (unsigned long)talloc_total_size(ptr),
1172 (unsigned long)talloc_total_blocks(ptr),
1173 (int)talloc_reference_count(ptr), ptr);
1175 #if 0
1176 fprintf(f, "content: ");
1177 if (talloc_total_size(ptr)) {
1178 int tot = talloc_total_size(ptr);
1179 int i;
1181 for (i = 0; i < tot; i++) {
1182 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1183 fprintf(f, "%c", ((char *)ptr)[i]);
1184 } else {
1185 fprintf(f, "~%02x", ((char *)ptr)[i]);
1189 fprintf(f, "\n");
1190 #endif
1194 report on memory usage by all children of a pointer, giving a full tree view
1196 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1198 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1199 fflush(f);
1203 report on memory usage by all children of a pointer, giving a full tree view
1205 void talloc_report_full(const void *ptr, FILE *f)
1207 talloc_report_depth_file(ptr, 0, -1, f);
1211 report on memory usage by all children of a pointer
1213 void talloc_report(const void *ptr, FILE *f)
1215 talloc_report_depth_file(ptr, 0, 1, f);
1219 report on any memory hanging off the null context
1221 static void talloc_report_null(void)
1223 if (talloc_total_size(null_context) != 0) {
1224 talloc_report(null_context, stderr);
1229 report on any memory hanging off the null context
1231 static void talloc_report_null_full(void)
1233 if (talloc_total_size(null_context) != 0) {
1234 talloc_report_full(null_context, stderr);
1239 enable tracking of the NULL context
1241 void talloc_enable_null_tracking(void)
1243 if (null_context == NULL) {
1244 null_context = _talloc_named_const(NULL, 0, "null_context");
1249 disable tracking of the NULL context
1251 void talloc_disable_null_tracking(void)
1253 _talloc_free(null_context);
1254 null_context = NULL;
1258 enable leak reporting on exit
1260 void talloc_enable_leak_report(void)
1262 talloc_enable_null_tracking();
1263 atexit(talloc_report_null);
1267 enable full leak reporting on exit
1269 void talloc_enable_leak_report_full(void)
1271 talloc_enable_null_tracking();
1272 atexit(talloc_report_null_full);
1276 talloc and zero memory.
1278 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1280 void *p = _talloc_named_const(ctx, size, name);
1282 if (p) {
1283 memset(p, '\0', size);
1286 return p;
1290 memdup with a talloc.
1292 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1294 void *newp = _talloc_named_const(t, size, name);
1296 if (likely(newp)) {
1297 memcpy(newp, p, size);
1300 return newp;
1303 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1305 char *ret;
1307 ret = (char *)__talloc(t, len + 1);
1308 if (unlikely(!ret)) return NULL;
1310 memcpy(ret, p, len);
1311 ret[len] = 0;
1313 _talloc_set_name_const(ret, ret);
1314 return ret;
1318 strdup with a talloc
1320 char *talloc_strdup(const void *t, const char *p)
1322 if (unlikely(!p)) return NULL;
1323 return __talloc_strlendup(t, p, strlen(p));
1327 strndup with a talloc
1329 char *talloc_strndup(const void *t, const char *p, size_t n)
1331 if (unlikely(!p)) return NULL;
1332 return __talloc_strlendup(t, p, strnlen(p, n));
1335 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1336 const char *a, size_t alen)
1338 char *ret;
1340 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1341 if (unlikely(!ret)) return NULL;
1343 /* append the string and the trailing \0 */
1344 memcpy(&ret[slen], a, alen);
1345 ret[slen+alen] = 0;
1347 _talloc_set_name_const(ret, ret);
1348 return ret;
1352 * Appends at the end of the string.
1354 char *talloc_strdup_append(char *s, const char *a)
1356 if (unlikely(!s)) {
1357 return talloc_strdup(NULL, a);
1360 if (unlikely(!a)) {
1361 return s;
1364 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1368 * Appends at the end of the talloc'ed buffer,
1369 * not the end of the string.
1371 char *talloc_strdup_append_buffer(char *s, const char *a)
1373 size_t slen;
1375 if (unlikely(!s)) {
1376 return talloc_strdup(NULL, a);
1379 if (unlikely(!a)) {
1380 return s;
1383 slen = talloc_get_size(s);
1384 if (likely(slen > 0)) {
1385 slen--;
1388 return __talloc_strlendup_append(s, slen, a, strlen(a));
1392 * Appends at the end of the string.
1394 char *talloc_strndup_append(char *s, const char *a, size_t n)
1396 if (unlikely(!s)) {
1397 return talloc_strdup(NULL, a);
1400 if (unlikely(!a)) {
1401 return s;
1404 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1408 * Appends at the end of the talloc'ed buffer,
1409 * not the end of the string.
1411 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1413 size_t slen;
1415 if (unlikely(!s)) {
1416 return talloc_strdup(NULL, a);
1419 if (unlikely(!a)) {
1420 return s;
1423 slen = talloc_get_size(s);
1424 if (likely(slen > 0)) {
1425 slen--;
1428 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1431 #ifndef HAVE_VA_COPY
1432 #ifdef HAVE___VA_COPY
1433 #define va_copy(dest, src) __va_copy(dest, src)
1434 #else
1435 #define va_copy(dest, src) (dest) = (src)
1436 #endif
1437 #endif
1439 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1441 int len;
1442 char *ret;
1443 va_list ap2;
1444 char c;
1446 /* this call looks strange, but it makes it work on older solaris boxes */
1447 va_copy(ap2, ap);
1448 len = vsnprintf(&c, 1, fmt, ap2);
1449 va_end(ap2);
1450 if (unlikely(len < 0)) {
1451 return NULL;
1454 ret = (char *)__talloc(t, len+1);
1455 if (unlikely(!ret)) return NULL;
1457 va_copy(ap2, ap);
1458 vsnprintf(ret, len+1, fmt, ap2);
1459 va_end(ap2);
1461 _talloc_set_name_const(ret, ret);
1462 return ret;
1467 Perform string formatting, and return a pointer to newly allocated
1468 memory holding the result, inside a memory pool.
1470 char *talloc_asprintf(const void *t, const char *fmt, ...)
1472 va_list ap;
1473 char *ret;
1475 va_start(ap, fmt);
1476 ret = talloc_vasprintf(t, fmt, ap);
1477 va_end(ap);
1478 return ret;
1481 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1482 const char *fmt, va_list ap)
1483 PRINTF_ATTRIBUTE(3,0);
1485 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1486 const char *fmt, va_list ap)
1488 ssize_t alen;
1489 va_list ap2;
1490 char c;
1492 va_copy(ap2, ap);
1493 alen = vsnprintf(&c, 1, fmt, ap2);
1494 va_end(ap2);
1496 if (alen <= 0) {
1497 /* Either the vsnprintf failed or the format resulted in
1498 * no characters being formatted. In the former case, we
1499 * ought to return NULL, in the latter we ought to return
1500 * the original string. Most current callers of this
1501 * function expect it to never return NULL.
1503 return s;
1506 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1507 if (!s) return NULL;
1509 va_copy(ap2, ap);
1510 vsnprintf(s + slen, alen + 1, fmt, ap2);
1511 va_end(ap2);
1513 _talloc_set_name_const(s, s);
1514 return s;
1518 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1519 * and return @p s, which may have moved. Good for gradually
1520 * accumulating output into a string buffer. Appends at the end
1521 * of the string.
1523 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1525 if (unlikely(!s)) {
1526 return talloc_vasprintf(NULL, fmt, ap);
1529 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1533 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1534 * and return @p s, which may have moved. Always appends at the
1535 * end of the talloc'ed buffer, not the end of the string.
1537 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1539 size_t slen;
1541 if (unlikely(!s)) {
1542 return talloc_vasprintf(NULL, fmt, ap);
1545 slen = talloc_get_size(s);
1546 if (likely(slen > 0)) {
1547 slen--;
1550 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1554 Realloc @p s to append the formatted result of @p fmt and return @p
1555 s, which may have moved. Good for gradually accumulating output
1556 into a string buffer.
1558 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1560 va_list ap;
1562 va_start(ap, fmt);
1563 s = talloc_vasprintf_append(s, fmt, ap);
1564 va_end(ap);
1565 return s;
1569 Realloc @p s to append the formatted result of @p fmt and return @p
1570 s, which may have moved. Good for gradually accumulating output
1571 into a buffer.
1573 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1575 va_list ap;
1577 va_start(ap, fmt);
1578 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1579 va_end(ap);
1580 return s;
1584 alloc an array, checking for integer overflow in the array size
1586 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1588 if (count >= MAX_TALLOC_SIZE/el_size) {
1589 return NULL;
1591 return _talloc_named_const(ctx, el_size * count, name);
1595 alloc an zero array, checking for integer overflow in the array size
1597 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1599 if (count >= MAX_TALLOC_SIZE/el_size) {
1600 return NULL;
1602 return _talloc_zero(ctx, el_size * count, name);
1606 realloc an array, checking for integer overflow in the array size
1608 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1610 if (count >= MAX_TALLOC_SIZE/el_size) {
1611 return NULL;
1613 return _talloc_realloc(ctx, ptr, el_size * count, name);
1617 a function version of talloc_realloc(), so it can be passed as a function pointer
1618 to libraries that want a realloc function (a realloc function encapsulates
1619 all the basic capabilities of an allocation library, which is why this is useful)
1621 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1623 return _talloc_realloc(context, ptr, size, NULL);
1627 static int talloc_autofree_destructor(void *ptr)
1629 autofree_context = NULL;
1630 return 0;
1633 static void talloc_autofree(void)
1635 _talloc_free(autofree_context);
1639 return a context which will be auto-freed on exit
1640 this is useful for reducing the noise in leak reports
1642 void *talloc_autofree_context(void)
1644 if (autofree_context == NULL) {
1645 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1646 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1647 atexit(talloc_autofree);
1649 return autofree_context;
1652 size_t talloc_get_size(const void *context)
1654 struct talloc_chunk *tc;
1656 if (context == NULL)
1657 return 0;
1659 tc = talloc_chunk_from_ptr(context);
1661 return tc->size;
1665 find a parent of this context that has the given name, if any
1667 void *talloc_find_parent_byname(const void *context, const char *name)
1669 struct talloc_chunk *tc;
1671 if (context == NULL) {
1672 return NULL;
1675 tc = talloc_chunk_from_ptr(context);
1676 while (tc) {
1677 if (tc->name && strcmp(tc->name, name) == 0) {
1678 return TC_PTR_FROM_CHUNK(tc);
1680 while (tc && tc->prev) tc = tc->prev;
1681 if (tc) {
1682 tc = tc->parent;
1685 return NULL;
1689 show the parentage of a context
1691 void talloc_show_parents(const void *context, FILE *file)
1693 struct talloc_chunk *tc;
1695 if (context == NULL) {
1696 fprintf(file, "talloc no parents for NULL\n");
1697 return;
1700 tc = talloc_chunk_from_ptr(context);
1701 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1702 while (tc) {
1703 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1704 while (tc && tc->prev) tc = tc->prev;
1705 if (tc) {
1706 tc = tc->parent;
1709 fflush(file);
1713 return 1 if ptr is a parent of context
1715 int talloc_is_parent(const void *context, const void *ptr)
1717 struct talloc_chunk *tc;
1719 if (context == NULL) {
1720 return 0;
1723 tc = talloc_chunk_from_ptr(context);
1724 while (tc) {
1725 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1726 while (tc && tc->prev) tc = tc->prev;
1727 if (tc) {
1728 tc = tc->parent;
1731 return 0;