rpm: Remove MEncoder from rpm packaging
[mplayer/glamo.git] / talloc.c
blob63550cf4d41bbcf688cbac96d411be5c01ff98b3
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 // Hardcode these for MPlayer assuming a working system.
34 // Original used autoconf detection with workarounds for broken systems.
35 #define HAVE_VA_COPY
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39 #include <stdint.h>
40 #include <string.h>
41 #include <stdbool.h>
42 #define MIN(a,b) ((a)<(b)?(a):(b))
43 #define strnlen rep_strnlen
44 static size_t rep_strnlen(const char *s, size_t max)
46 size_t len;
48 for (len = 0; len < max; len++) {
49 if (s[len] == '\0') {
50 break;
53 return len;
58 #ifdef _SAMBA_BUILD_
59 #include "version.h"
60 #if (SAMBA_VERSION_MAJOR<4)
61 #include "includes.h"
62 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
63 * we trust ourselves... */
64 #ifdef malloc
65 #undef malloc
66 #endif
67 #ifdef realloc
68 #undef realloc
69 #endif
70 #define _TALLOC_SAMBA3
71 #endif /* (SAMBA_VERSION_MAJOR<4) */
72 #endif /* _SAMBA_BUILD_ */
74 #ifndef _TALLOC_SAMBA3
75 // Workarounds for missing standard features, not used in MPlayer
76 // #include "replace.h"
77 #include "talloc.h"
78 #endif /* not _TALLOC_SAMBA3 */
80 /* use this to force every realloc to change the pointer, to stress test
81 code that might not cope */
82 #define ALWAYS_REALLOC 0
85 #define MAX_TALLOC_SIZE 0x10000000
86 #define TALLOC_MAGIC 0xe814ec70
87 #define TALLOC_FLAG_FREE 0x01
88 #define TALLOC_FLAG_LOOP 0x02
89 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
90 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
91 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
93 /* by default we abort when given a bad pointer (such as when talloc_free() is called
94 on a pointer that came from malloc() */
95 #ifndef TALLOC_ABORT
96 #define TALLOC_ABORT(reason) abort()
97 #endif
99 #ifndef discard_const_p
100 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
101 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
102 #else
103 # define discard_const_p(type, ptr) ((type *)(ptr))
104 #endif
105 #endif
107 /* these macros gain us a few percent of speed on gcc */
108 #if (__GNUC__ >= 3)
109 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
110 as its first argument */
111 #ifndef likely
112 #define likely(x) __builtin_expect(!!(x), 1)
113 #endif
114 #ifndef unlikely
115 #define unlikely(x) __builtin_expect(!!(x), 0)
116 #endif
117 #else
118 #ifndef likely
119 #define likely(x) (x)
120 #endif
121 #ifndef unlikely
122 #define unlikely(x) (x)
123 #endif
124 #endif
126 /* this null_context is only used if talloc_enable_leak_report() or
127 talloc_enable_leak_report_full() is called, otherwise it remains
128 NULL
130 static void *null_context;
131 static void *autofree_context;
133 struct talloc_reference_handle {
134 struct talloc_reference_handle *next, *prev;
135 void *ptr;
138 typedef int (*talloc_destructor_t)(void *);
140 struct talloc_chunk {
141 struct talloc_chunk *next, *prev;
142 struct talloc_chunk *parent, *child;
143 struct talloc_reference_handle *refs;
144 talloc_destructor_t destructor;
145 const char *name;
146 size_t size;
147 unsigned flags;
150 * "pool" has dual use:
152 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
153 * marks the end of the currently allocated area.
155 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
156 * is a pointer to the struct talloc_chunk of the pool that it was
157 * allocated from. This way children can quickly find the pool to chew
158 * from.
160 void *pool;
163 /* 16 byte alignment seems to keep everyone happy */
164 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
165 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
167 static void talloc_abort_double_free(void)
169 TALLOC_ABORT("Bad talloc magic value - double free");
172 static void talloc_abort_unknown_value(void)
174 TALLOC_ABORT("Bad talloc magic value - unknown value");
177 /* panic if we get a bad magic value */
178 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
180 const char *pp = (const char *)ptr;
181 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
182 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
183 if (tc->flags & TALLOC_FLAG_FREE) {
184 talloc_abort_double_free();
185 } else {
186 talloc_abort_unknown_value();
189 return tc;
192 /* hook into the front of the list */
193 #define _TLIST_ADD(list, p) \
194 do { \
195 if (!(list)) { \
196 (list) = (p); \
197 (p)->next = (p)->prev = NULL; \
198 } else { \
199 (list)->prev = (p); \
200 (p)->next = (list); \
201 (p)->prev = NULL; \
202 (list) = (p); \
204 } while (0)
206 /* remove an element from a list - element doesn't have to be in list. */
207 #define _TLIST_REMOVE(list, p) \
208 do { \
209 if ((p) == (list)) { \
210 (list) = (p)->next; \
211 if (list) (list)->prev = NULL; \
212 } else { \
213 if ((p)->prev) (p)->prev->next = (p)->next; \
214 if ((p)->next) (p)->next->prev = (p)->prev; \
216 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
217 } while (0)
221 return the parent chunk of a pointer
223 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
225 struct talloc_chunk *tc;
227 if (unlikely(ptr == NULL)) {
228 return NULL;
231 tc = talloc_chunk_from_ptr(ptr);
232 while (tc->prev) tc=tc->prev;
234 return tc->parent;
237 void *talloc_parent(const void *ptr)
239 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
240 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
244 find parents name
246 const char *talloc_parent_name(const void *ptr)
248 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
249 return tc? tc->name : NULL;
253 A pool carries an in-pool object count count in the first 16 bytes.
254 bytes. This is done to support talloc_steal() to a parent outside of the
255 pool. The count includes the pool itself, so a talloc_free() on a pool will
256 only destroy the pool if the count has dropped to zero. A talloc_free() of a
257 pool member will reduce the count, and eventually also call free(3) on the
258 pool memory.
260 The object count is not put into "struct talloc_chunk" because it is only
261 relevant for talloc pools and the alignment to 16 bytes would increase the
262 memory footprint of each talloc chunk by those 16 bytes.
265 #define TALLOC_POOL_HDR_SIZE 16
267 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
269 return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
273 Allocate from a pool
276 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
277 size_t size)
279 struct talloc_chunk *pool_ctx = NULL;
280 size_t space_left;
281 struct talloc_chunk *result;
282 size_t chunk_size;
284 if (parent == NULL) {
285 return NULL;
288 if (parent->flags & TALLOC_FLAG_POOL) {
289 pool_ctx = parent;
291 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
292 pool_ctx = (struct talloc_chunk *)parent->pool;
295 if (pool_ctx == NULL) {
296 return NULL;
299 space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
300 - ((char *)pool_ctx->pool);
303 * Align size to 16 bytes
305 chunk_size = ((size + 15) & ~15);
307 if (space_left < chunk_size) {
308 return NULL;
311 result = (struct talloc_chunk *)pool_ctx->pool;
313 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
314 VALGRIND_MAKE_MEM_UNDEFINED(result, size);
315 #endif
317 pool_ctx->pool = (void *)((char *)result + chunk_size);
319 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
320 result->pool = pool_ctx;
322 *talloc_pool_objectcount(pool_ctx) += 1;
324 return result;
328 Allocate a bit of memory as a child of an existing pointer
330 static inline void *__talloc(const void *context, size_t size)
332 struct talloc_chunk *tc = NULL;
334 if (unlikely(context == NULL)) {
335 context = null_context;
338 if (unlikely(size >= MAX_TALLOC_SIZE)) {
339 abort(); // return NULL;
342 if (context != NULL) {
343 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
344 TC_HDR_SIZE+size);
347 if (tc == NULL) {
348 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
349 if (unlikely(tc == NULL)) abort(); // return NULL;
350 tc->flags = TALLOC_MAGIC;
351 tc->pool = NULL;
354 tc->size = size;
355 tc->destructor = NULL;
356 tc->child = NULL;
357 tc->name = NULL;
358 tc->refs = NULL;
360 if (likely(context)) {
361 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
363 if (parent->child) {
364 parent->child->parent = NULL;
365 tc->next = parent->child;
366 tc->next->prev = tc;
367 } else {
368 tc->next = NULL;
370 tc->parent = parent;
371 tc->prev = NULL;
372 parent->child = tc;
373 } else {
374 tc->next = tc->prev = tc->parent = NULL;
377 return TC_PTR_FROM_CHUNK(tc);
381 * Create a talloc pool
384 void *talloc_pool(const void *context, size_t size)
386 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
387 struct talloc_chunk *tc;
389 if (unlikely(result == NULL)) {
390 return NULL;
393 tc = talloc_chunk_from_ptr(result);
395 tc->flags |= TALLOC_FLAG_POOL;
396 tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
398 *talloc_pool_objectcount(tc) = 1;
400 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
401 VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
402 #endif
404 return result;
408 setup a destructor to be called on free of a pointer
409 the destructor should return 0 on success, or -1 on failure.
410 if the destructor fails then the free is failed, and the memory can
411 be continued to be used
413 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
415 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
416 tc->destructor = destructor;
420 increase the reference count on a piece of memory.
422 int talloc_increase_ref_count(const void *ptr)
424 if (unlikely(!talloc_reference(null_context, ptr))) {
425 return -1;
427 return 0;
431 helper for talloc_reference()
433 this is referenced by a function pointer and should not be inline
435 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
437 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
438 _TLIST_REMOVE(ptr_tc->refs, handle);
439 return 0;
443 more efficient way to add a name to a pointer - the name must point to a
444 true string constant
446 static inline void _talloc_set_name_const(const void *ptr, const char *name)
448 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
449 tc->name = name;
453 internal talloc_named_const()
455 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
457 void *ptr;
459 ptr = __talloc(context, size);
460 if (unlikely(ptr == NULL)) {
461 return NULL;
464 _talloc_set_name_const(ptr, name);
466 return ptr;
470 make a secondary reference to a pointer, hanging off the given context.
471 the pointer remains valid until both the original caller and this given
472 context are freed.
474 the major use for this is when two different structures need to reference the
475 same underlying data, and you want to be able to free the two instances separately,
476 and in either order
478 void *_talloc_reference(const void *context, const void *ptr)
480 struct talloc_chunk *tc;
481 struct talloc_reference_handle *handle;
482 if (unlikely(ptr == NULL)) return NULL;
484 tc = talloc_chunk_from_ptr(ptr);
485 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
486 sizeof(struct talloc_reference_handle),
487 TALLOC_MAGIC_REFERENCE);
488 if (unlikely(handle == NULL)) return NULL;
490 /* note that we hang the destructor off the handle, not the
491 main context as that allows the caller to still setup their
492 own destructor on the context if they want to */
493 talloc_set_destructor(handle, talloc_reference_destructor);
494 handle->ptr = discard_const_p(void, ptr);
495 _TLIST_ADD(tc->refs, handle);
496 return handle->ptr;
501 internal talloc_free call
503 static inline int _talloc_free(void *ptr)
505 struct talloc_chunk *tc;
507 if (unlikely(ptr == NULL)) {
508 return -1;
511 tc = talloc_chunk_from_ptr(ptr);
513 if (unlikely(tc->refs)) {
514 int is_child;
515 /* check this is a reference from a child or grantchild
516 * back to it's parent or grantparent
518 * in that case we need to remove the reference and
519 * call another instance of talloc_free() on the current
520 * pointer.
522 is_child = talloc_is_parent(tc->refs, ptr);
523 _talloc_free(tc->refs);
524 if (is_child) {
525 return _talloc_free(ptr);
527 return -1;
530 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
531 /* we have a free loop - stop looping */
532 return 0;
535 if (unlikely(tc->destructor)) {
536 talloc_destructor_t d = tc->destructor;
537 if (d == (talloc_destructor_t)-1) {
538 return -1;
540 tc->destructor = (talloc_destructor_t)-1;
541 if (d(ptr) == -1) {
542 tc->destructor = d;
543 return -1;
545 tc->destructor = NULL;
548 if (tc->parent) {
549 _TLIST_REMOVE(tc->parent->child, tc);
550 if (tc->parent->child) {
551 tc->parent->child->parent = tc->parent;
553 } else {
554 if (tc->prev) tc->prev->next = tc->next;
555 if (tc->next) tc->next->prev = tc->prev;
558 tc->flags |= TALLOC_FLAG_LOOP;
560 while (tc->child) {
561 /* we need to work out who will own an abandoned child
562 if it cannot be freed. In priority order, the first
563 choice is owner of any remaining reference to this
564 pointer, the second choice is our parent, and the
565 final choice is the null context. */
566 void *child = TC_PTR_FROM_CHUNK(tc->child);
567 const void *new_parent = null_context;
568 if (unlikely(tc->child->refs)) {
569 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
570 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
572 if (unlikely(_talloc_free(child) == -1)) {
573 if (new_parent == null_context) {
574 struct talloc_chunk *p = talloc_parent_chunk(ptr);
575 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
577 talloc_steal(new_parent, child);
581 tc->flags |= TALLOC_FLAG_FREE;
583 if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
584 struct talloc_chunk *pool;
585 unsigned int *pool_object_count;
587 pool = (tc->flags & TALLOC_FLAG_POOL)
588 ? tc : (struct talloc_chunk *)tc->pool;
590 pool_object_count = talloc_pool_objectcount(pool);
592 if (*pool_object_count == 0) {
593 TALLOC_ABORT("Pool object count zero!");
596 *pool_object_count -= 1;
598 if (*pool_object_count == 0) {
599 free(pool);
602 else {
603 free(tc);
605 return 0;
609 move a lump of memory from one talloc context to another return the
610 ptr on success, or NULL if it could not be transferred.
611 passing NULL as ptr will always return NULL with no side effects.
613 void *_talloc_steal(const void *new_ctx, const void *ptr)
615 struct talloc_chunk *tc, *new_tc;
617 if (unlikely(!ptr)) {
618 return NULL;
621 if (unlikely(new_ctx == NULL)) {
622 new_ctx = null_context;
625 tc = talloc_chunk_from_ptr(ptr);
627 if (unlikely(new_ctx == NULL)) {
628 if (tc->parent) {
629 _TLIST_REMOVE(tc->parent->child, tc);
630 if (tc->parent->child) {
631 tc->parent->child->parent = tc->parent;
633 } else {
634 if (tc->prev) tc->prev->next = tc->next;
635 if (tc->next) tc->next->prev = tc->prev;
638 tc->parent = tc->next = tc->prev = NULL;
639 return discard_const_p(void, ptr);
642 new_tc = talloc_chunk_from_ptr(new_ctx);
644 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
645 return discard_const_p(void, ptr);
648 if (tc->parent) {
649 _TLIST_REMOVE(tc->parent->child, tc);
650 if (tc->parent->child) {
651 tc->parent->child->parent = tc->parent;
653 } else {
654 if (tc->prev) tc->prev->next = tc->next;
655 if (tc->next) tc->next->prev = tc->prev;
658 tc->parent = new_tc;
659 if (new_tc->child) new_tc->child->parent = NULL;
660 _TLIST_ADD(new_tc->child, tc);
662 return discard_const_p(void, ptr);
668 remove a secondary reference to a pointer. This undo's what
669 talloc_reference() has done. The context and pointer arguments
670 must match those given to a talloc_reference()
672 static inline int talloc_unreference(const void *context, const void *ptr)
674 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
675 struct talloc_reference_handle *h;
677 if (unlikely(context == NULL)) {
678 context = null_context;
681 for (h=tc->refs;h;h=h->next) {
682 struct talloc_chunk *p = talloc_parent_chunk(h);
683 if (p == NULL) {
684 if (context == NULL) break;
685 } else if (TC_PTR_FROM_CHUNK(p) == context) {
686 break;
689 if (h == NULL) {
690 return -1;
693 return _talloc_free(h);
697 remove a specific parent context from a pointer. This is a more
698 controlled varient of talloc_free()
700 int talloc_unlink(const void *context, void *ptr)
702 struct talloc_chunk *tc_p, *new_p;
703 void *new_parent;
705 if (ptr == NULL) {
706 return -1;
709 if (context == NULL) {
710 context = null_context;
713 if (talloc_unreference(context, ptr) == 0) {
714 return 0;
717 if (context == NULL) {
718 if (talloc_parent_chunk(ptr) != NULL) {
719 return -1;
721 } else {
722 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
723 return -1;
727 tc_p = talloc_chunk_from_ptr(ptr);
729 if (tc_p->refs == NULL) {
730 return _talloc_free(ptr);
733 new_p = talloc_parent_chunk(tc_p->refs);
734 if (new_p) {
735 new_parent = TC_PTR_FROM_CHUNK(new_p);
736 } else {
737 new_parent = NULL;
740 if (talloc_unreference(new_parent, ptr) != 0) {
741 return -1;
744 talloc_steal(new_parent, ptr);
746 return 0;
750 add a name to an existing pointer - va_list version
752 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
754 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
756 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
757 tc->name = talloc_vasprintf(ptr, fmt, ap);
758 if (likely(tc->name)) {
759 _talloc_set_name_const(tc->name, ".name");
761 return tc->name;
765 add a name to an existing pointer
767 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
769 const char *name;
770 va_list ap;
771 va_start(ap, fmt);
772 name = talloc_set_name_v(ptr, fmt, ap);
773 va_end(ap);
774 return name;
779 create a named talloc pointer. Any talloc pointer can be named, and
780 talloc_named() operates just like talloc() except that it allows you
781 to name the pointer.
783 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
785 va_list ap;
786 void *ptr;
787 const char *name;
789 ptr = __talloc(context, size);
790 if (unlikely(ptr == NULL)) return NULL;
792 va_start(ap, fmt);
793 name = talloc_set_name_v(ptr, fmt, ap);
794 va_end(ap);
796 if (unlikely(name == NULL)) {
797 _talloc_free(ptr);
798 return NULL;
801 return ptr;
805 return the name of a talloc ptr, or "UNNAMED"
807 const char *talloc_get_name(const void *ptr)
809 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
810 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
811 return ".reference";
813 if (likely(tc->name)) {
814 return tc->name;
816 return "UNNAMED";
821 check if a pointer has the given name. If it does, return the pointer,
822 otherwise return NULL
824 void *talloc_check_name(const void *ptr, const char *name)
826 const char *pname;
827 if (unlikely(ptr == NULL)) return NULL;
828 pname = talloc_get_name(ptr);
829 if (likely(pname == name || strcmp(pname, name) == 0)) {
830 return discard_const_p(void, ptr);
832 return NULL;
837 this is for compatibility with older versions of talloc
839 void *talloc_init(const char *fmt, ...)
841 va_list ap;
842 void *ptr;
843 const char *name;
846 * samba3 expects talloc_report_depth_cb(NULL, ...)
847 * reports all talloc'ed memory, so we need to enable
848 * null_tracking
850 talloc_enable_null_tracking();
852 ptr = __talloc(NULL, 0);
853 if (unlikely(ptr == NULL)) return NULL;
855 va_start(ap, fmt);
856 name = talloc_set_name_v(ptr, fmt, ap);
857 va_end(ap);
859 if (unlikely(name == NULL)) {
860 _talloc_free(ptr);
861 return NULL;
864 return ptr;
868 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
869 should probably not be used in new code. It's in here to keep the talloc
870 code consistent across Samba 3 and 4.
872 void talloc_free_children(void *ptr)
874 struct talloc_chunk *tc;
876 if (unlikely(ptr == NULL)) {
877 return;
880 tc = talloc_chunk_from_ptr(ptr);
882 while (tc->child) {
883 /* we need to work out who will own an abandoned child
884 if it cannot be freed. In priority order, the first
885 choice is owner of any remaining reference to this
886 pointer, the second choice is our parent, and the
887 final choice is the null context. */
888 void *child = TC_PTR_FROM_CHUNK(tc->child);
889 const void *new_parent = null_context;
890 if (unlikely(tc->child->refs)) {
891 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
892 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
894 if (unlikely(_talloc_free(child) == -1)) {
895 if (new_parent == null_context) {
896 struct talloc_chunk *p = talloc_parent_chunk(ptr);
897 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
899 talloc_steal(new_parent, child);
903 if ((tc->flags & TALLOC_FLAG_POOL)
904 && (*talloc_pool_objectcount(tc) == 1)) {
905 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
906 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
907 VALGRIND_MAKE_MEM_NOACCESS(
908 tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
909 #endif
914 Allocate a bit of memory as a child of an existing pointer
916 void *_talloc(const void *context, size_t size)
918 return __talloc(context, size);
922 externally callable talloc_set_name_const()
924 void talloc_set_name_const(const void *ptr, const char *name)
926 _talloc_set_name_const(ptr, name);
930 create a named talloc pointer. Any talloc pointer can be named, and
931 talloc_named() operates just like talloc() except that it allows you
932 to name the pointer.
934 void *talloc_named_const(const void *context, size_t size, const char *name)
936 return _talloc_named_const(context, size, name);
940 free a talloc pointer. This also frees all child pointers of this
941 pointer recursively
943 return 0 if the memory is actually freed, otherwise -1. The memory
944 will not be freed if the ref_count is > 1 or the destructor (if
945 any) returns non-zero
947 int talloc_free(void *ptr)
949 return _talloc_free(ptr);
955 A talloc version of realloc. The context argument is only used if
956 ptr is NULL
958 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
960 struct talloc_chunk *tc;
961 void *new_ptr;
962 bool malloced = false;
964 /* size zero is equivalent to free() */
965 if (unlikely(size == 0)) {
966 _talloc_free(ptr);
967 return NULL;
970 if (unlikely(size >= MAX_TALLOC_SIZE)) {
971 abort(); // return NULL;
974 /* realloc(NULL) is equivalent to malloc() */
975 if (ptr == NULL) {
976 return _talloc_named_const(context, size, name);
979 tc = talloc_chunk_from_ptr(ptr);
981 /* don't allow realloc on referenced pointers */
982 if (unlikely(tc->refs)) {
983 abort(); // return NULL;
986 /* don't shrink if we have less than 1k to gain */
987 if ((size < tc->size) && ((tc->size - size) < 1024)) {
988 tc->size = size;
989 return ptr;
992 /* by resetting magic we catch users of the old memory */
993 tc->flags |= TALLOC_FLAG_FREE;
995 #if ALWAYS_REALLOC
996 new_ptr = malloc(size + TC_HDR_SIZE);
997 if (new_ptr) {
998 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
999 free(tc);
1001 #else
1002 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1004 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1005 *talloc_pool_objectcount((struct talloc_chunk *)
1006 (tc->pool)) -= 1;
1008 if (new_ptr == NULL) {
1009 new_ptr = malloc(TC_HDR_SIZE+size);
1010 malloced = true;
1013 if (new_ptr) {
1014 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1017 else {
1018 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1020 #endif
1021 if (unlikely(!new_ptr)) {
1022 tc->flags &= ~TALLOC_FLAG_FREE;
1023 abort(); // return NULL;
1026 tc = (struct talloc_chunk *)new_ptr;
1027 tc->flags &= ~TALLOC_FLAG_FREE;
1028 if (malloced) {
1029 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1031 if (tc->parent) {
1032 tc->parent->child = tc;
1034 if (tc->child) {
1035 tc->child->parent = tc;
1038 if (tc->prev) {
1039 tc->prev->next = tc;
1041 if (tc->next) {
1042 tc->next->prev = tc;
1045 tc->size = size;
1046 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1048 return TC_PTR_FROM_CHUNK(tc);
1052 a wrapper around talloc_steal() for situations where you are moving a pointer
1053 between two structures, and want the old pointer to be set to NULL
1055 void *_talloc_move(const void *new_ctx, const void *_pptr)
1057 const void **pptr = discard_const_p(const void *,_pptr);
1058 void *ret = _talloc_steal(new_ctx, *pptr);
1059 (*pptr) = NULL;
1060 return ret;
1064 return the total size of a talloc pool (subtree)
1066 size_t talloc_total_size(const void *ptr)
1068 size_t total = 0;
1069 struct talloc_chunk *c, *tc;
1071 if (ptr == NULL) {
1072 ptr = null_context;
1074 if (ptr == NULL) {
1075 return 0;
1078 tc = talloc_chunk_from_ptr(ptr);
1080 if (tc->flags & TALLOC_FLAG_LOOP) {
1081 return 0;
1084 tc->flags |= TALLOC_FLAG_LOOP;
1086 total = tc->size;
1087 for (c=tc->child;c;c=c->next) {
1088 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1091 tc->flags &= ~TALLOC_FLAG_LOOP;
1093 return total;
1097 return the total number of blocks in a talloc pool (subtree)
1099 size_t talloc_total_blocks(const void *ptr)
1101 size_t total = 0;
1102 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1104 if (tc->flags & TALLOC_FLAG_LOOP) {
1105 return 0;
1108 tc->flags |= TALLOC_FLAG_LOOP;
1110 total++;
1111 for (c=tc->child;c;c=c->next) {
1112 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1115 tc->flags &= ~TALLOC_FLAG_LOOP;
1117 return total;
1121 return the number of external references to a pointer
1123 size_t talloc_reference_count(const void *ptr)
1125 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1126 struct talloc_reference_handle *h;
1127 size_t ret = 0;
1129 for (h=tc->refs;h;h=h->next) {
1130 ret++;
1132 return ret;
1136 report on memory usage by all children of a pointer, giving a full tree view
1138 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1139 void (*callback)(const void *ptr,
1140 int depth, int max_depth,
1141 int is_ref,
1142 void *private_data),
1143 void *private_data)
1145 struct talloc_chunk *c, *tc;
1147 if (ptr == NULL) {
1148 ptr = null_context;
1150 if (ptr == NULL) return;
1152 tc = talloc_chunk_from_ptr(ptr);
1154 if (tc->flags & TALLOC_FLAG_LOOP) {
1155 return;
1158 callback(ptr, depth, max_depth, 0, private_data);
1160 if (max_depth >= 0 && depth >= max_depth) {
1161 return;
1164 tc->flags |= TALLOC_FLAG_LOOP;
1165 for (c=tc->child;c;c=c->next) {
1166 if (c->name == TALLOC_MAGIC_REFERENCE) {
1167 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1168 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1169 } else {
1170 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1173 tc->flags &= ~TALLOC_FLAG_LOOP;
1176 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1178 const char *name = talloc_get_name(ptr);
1179 FILE *f = (FILE *)_f;
1181 if (is_ref) {
1182 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1183 return;
1186 if (depth == 0) {
1187 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1188 (max_depth < 0 ? "full " :""), name,
1189 (unsigned long)talloc_total_size(ptr),
1190 (unsigned long)talloc_total_blocks(ptr));
1191 return;
1194 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1195 depth*4, "",
1196 name,
1197 (unsigned long)talloc_total_size(ptr),
1198 (unsigned long)talloc_total_blocks(ptr),
1199 (int)talloc_reference_count(ptr), ptr);
1201 #if 0
1202 fprintf(f, "content: ");
1203 if (talloc_total_size(ptr)) {
1204 int tot = talloc_total_size(ptr);
1205 int i;
1207 for (i = 0; i < tot; i++) {
1208 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1209 fprintf(f, "%c", ((char *)ptr)[i]);
1210 } else {
1211 fprintf(f, "~%02x", ((char *)ptr)[i]);
1215 fprintf(f, "\n");
1216 #endif
1220 report on memory usage by all children of a pointer, giving a full tree view
1222 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1224 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1225 fflush(f);
1229 report on memory usage by all children of a pointer, giving a full tree view
1231 void talloc_report_full(const void *ptr, FILE *f)
1233 talloc_report_depth_file(ptr, 0, -1, f);
1237 report on memory usage by all children of a pointer
1239 void talloc_report(const void *ptr, FILE *f)
1241 talloc_report_depth_file(ptr, 0, 1, f);
1245 report on any memory hanging off the null context
1247 static void talloc_report_null(void)
1249 if (talloc_total_size(null_context) != 0) {
1250 talloc_report(null_context, stderr);
1255 report on any memory hanging off the null context
1257 static void talloc_report_null_full(void)
1259 if (talloc_total_size(null_context) != 0) {
1260 talloc_report_full(null_context, stderr);
1265 enable tracking of the NULL context
1267 void talloc_enable_null_tracking(void)
1269 if (null_context == NULL) {
1270 null_context = _talloc_named_const(NULL, 0, "null_context");
1275 disable tracking of the NULL context
1277 void talloc_disable_null_tracking(void)
1279 _talloc_free(null_context);
1280 null_context = NULL;
1284 enable leak reporting on exit
1286 void talloc_enable_leak_report(void)
1288 talloc_enable_null_tracking();
1289 atexit(talloc_report_null);
1293 enable full leak reporting on exit
1295 void talloc_enable_leak_report_full(void)
1297 talloc_enable_null_tracking();
1298 atexit(talloc_report_null_full);
1302 talloc and zero memory.
1304 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1306 void *p = _talloc_named_const(ctx, size, name);
1308 if (p) {
1309 memset(p, '\0', size);
1312 return p;
1316 memdup with a talloc.
1318 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1320 void *newp = _talloc_named_const(t, size, name);
1322 if (likely(newp)) {
1323 memcpy(newp, p, size);
1326 return newp;
1329 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1331 char *ret;
1333 ret = (char *)__talloc(t, len + 1);
1334 if (unlikely(!ret)) return NULL;
1336 memcpy(ret, p, len);
1337 ret[len] = 0;
1339 _talloc_set_name_const(ret, ret);
1340 return ret;
1344 strdup with a talloc
1346 char *talloc_strdup(const void *t, const char *p)
1348 if (unlikely(!p)) return NULL;
1349 return __talloc_strlendup(t, p, strlen(p));
1353 strndup with a talloc
1355 char *talloc_strndup(const void *t, const char *p, size_t n)
1357 if (unlikely(!p)) return NULL;
1358 return __talloc_strlendup(t, p, strnlen(p, n));
1361 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1362 const char *a, size_t alen)
1364 char *ret;
1366 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1367 if (unlikely(!ret)) return NULL;
1369 /* append the string and the trailing \0 */
1370 memcpy(&ret[slen], a, alen);
1371 ret[slen+alen] = 0;
1373 _talloc_set_name_const(ret, ret);
1374 return ret;
1378 * Appends at the end of the string.
1380 char *talloc_strdup_append(char *s, const char *a)
1382 if (unlikely(!s)) {
1383 return talloc_strdup(NULL, a);
1386 if (unlikely(!a)) {
1387 return s;
1390 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1394 * Appends at the end of the talloc'ed buffer,
1395 * not the end of the string.
1397 char *talloc_strdup_append_buffer(char *s, const char *a)
1399 size_t slen;
1401 if (unlikely(!s)) {
1402 return talloc_strdup(NULL, a);
1405 if (unlikely(!a)) {
1406 return s;
1409 slen = talloc_get_size(s);
1410 if (likely(slen > 0)) {
1411 slen--;
1414 return __talloc_strlendup_append(s, slen, a, strlen(a));
1418 * Appends at the end of the string.
1420 char *talloc_strndup_append(char *s, const char *a, size_t n)
1422 if (unlikely(!s)) {
1423 return talloc_strdup(NULL, a);
1426 if (unlikely(!a)) {
1427 return s;
1430 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1434 * Appends at the end of the talloc'ed buffer,
1435 * not the end of the string.
1437 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1439 size_t slen;
1441 if (unlikely(!s)) {
1442 return talloc_strdup(NULL, a);
1445 if (unlikely(!a)) {
1446 return s;
1449 slen = talloc_get_size(s);
1450 if (likely(slen > 0)) {
1451 slen--;
1454 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1457 #ifndef HAVE_VA_COPY
1458 #ifdef HAVE___VA_COPY
1459 #define va_copy(dest, src) __va_copy(dest, src)
1460 #else
1461 #define va_copy(dest, src) (dest) = (src)
1462 #endif
1463 #endif
1465 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1467 int len;
1468 char *ret;
1469 va_list ap2;
1470 char c;
1472 /* this call looks strange, but it makes it work on older solaris boxes */
1473 va_copy(ap2, ap);
1474 len = vsnprintf(&c, 1, fmt, ap2);
1475 va_end(ap2);
1476 if (unlikely(len < 0)) {
1477 abort(); // return NULL;
1480 ret = (char *)__talloc(t, len+1);
1481 if (unlikely(!ret)) return NULL;
1483 va_copy(ap2, ap);
1484 vsnprintf(ret, len+1, fmt, ap2);
1485 va_end(ap2);
1487 _talloc_set_name_const(ret, ret);
1488 return ret;
1493 Perform string formatting, and return a pointer to newly allocated
1494 memory holding the result, inside a memory pool.
1496 char *talloc_asprintf(const void *t, const char *fmt, ...)
1498 va_list ap;
1499 char *ret;
1501 va_start(ap, fmt);
1502 ret = talloc_vasprintf(t, fmt, ap);
1503 va_end(ap);
1504 return ret;
1507 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1508 const char *fmt, va_list ap)
1509 PRINTF_ATTRIBUTE(3,0);
1511 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1512 const char *fmt, va_list ap)
1514 ssize_t alen;
1515 va_list ap2;
1516 char c;
1518 va_copy(ap2, ap);
1519 alen = vsnprintf(&c, 1, fmt, ap2);
1520 va_end(ap2);
1522 if (alen <= 0) {
1523 /* Either the vsnprintf failed or the format resulted in
1524 * no characters being formatted. In the former case, we
1525 * ought to return NULL, in the latter we ought to return
1526 * the original string. Most current callers of this
1527 * function expect it to never return NULL.
1529 return s;
1532 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1533 if (!s) return NULL;
1535 va_copy(ap2, ap);
1536 vsnprintf(s + slen, alen + 1, fmt, ap2);
1537 va_end(ap2);
1539 _talloc_set_name_const(s, s);
1540 return s;
1544 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1545 * and return @p s, which may have moved. Good for gradually
1546 * accumulating output into a string buffer. Appends at the end
1547 * of the string.
1549 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1551 if (unlikely(!s)) {
1552 return talloc_vasprintf(NULL, fmt, ap);
1555 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1559 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1560 * and return @p s, which may have moved. Always appends at the
1561 * end of the talloc'ed buffer, not the end of the string.
1563 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1565 size_t slen;
1567 if (unlikely(!s)) {
1568 return talloc_vasprintf(NULL, fmt, ap);
1571 slen = talloc_get_size(s);
1572 if (likely(slen > 0)) {
1573 slen--;
1576 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1580 Realloc @p s to append the formatted result of @p fmt and return @p
1581 s, which may have moved. Good for gradually accumulating output
1582 into a string buffer.
1584 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1586 va_list ap;
1588 va_start(ap, fmt);
1589 s = talloc_vasprintf_append(s, fmt, ap);
1590 va_end(ap);
1591 return s;
1595 Realloc @p s to append the formatted result of @p fmt and return @p
1596 s, which may have moved. Good for gradually accumulating output
1597 into a buffer.
1599 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1601 va_list ap;
1603 va_start(ap, fmt);
1604 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1605 va_end(ap);
1606 return s;
1610 alloc an array, checking for integer overflow in the array size
1612 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1614 if (count >= MAX_TALLOC_SIZE/el_size) {
1615 abort(); // return NULL;
1617 return _talloc_named_const(ctx, el_size * count, name);
1621 alloc an zero array, checking for integer overflow in the array size
1623 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1625 if (count >= MAX_TALLOC_SIZE/el_size) {
1626 abort(); // return NULL;
1628 return _talloc_zero(ctx, el_size * count, name);
1632 realloc an array, checking for integer overflow in the array size
1634 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1636 if (count >= MAX_TALLOC_SIZE/el_size) {
1637 abort(); // return NULL;
1639 return _talloc_realloc(ctx, ptr, el_size * count, name);
1643 a function version of talloc_realloc(), so it can be passed as a function pointer
1644 to libraries that want a realloc function (a realloc function encapsulates
1645 all the basic capabilities of an allocation library, which is why this is useful)
1647 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1649 return _talloc_realloc(context, ptr, size, NULL);
1653 static int talloc_autofree_destructor(void *ptr)
1655 autofree_context = NULL;
1656 return 0;
1659 static void talloc_autofree(void)
1661 _talloc_free(autofree_context);
1665 return a context which will be auto-freed on exit
1666 this is useful for reducing the noise in leak reports
1668 void *talloc_autofree_context(void)
1670 if (autofree_context == NULL) {
1671 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1672 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1673 atexit(talloc_autofree);
1675 return autofree_context;
1678 size_t talloc_get_size(const void *context)
1680 struct talloc_chunk *tc;
1682 if (context == NULL)
1683 return 0;
1685 tc = talloc_chunk_from_ptr(context);
1687 return tc->size;
1691 find a parent of this context that has the given name, if any
1693 void *talloc_find_parent_byname(const void *context, const char *name)
1695 struct talloc_chunk *tc;
1697 if (context == NULL) {
1698 return NULL;
1701 tc = talloc_chunk_from_ptr(context);
1702 while (tc) {
1703 if (tc->name && strcmp(tc->name, name) == 0) {
1704 return TC_PTR_FROM_CHUNK(tc);
1706 while (tc && tc->prev) tc = tc->prev;
1707 if (tc) {
1708 tc = tc->parent;
1711 return NULL;
1715 show the parentage of a context
1717 void talloc_show_parents(const void *context, FILE *file)
1719 struct talloc_chunk *tc;
1721 if (context == NULL) {
1722 fprintf(file, "talloc no parents for NULL\n");
1723 return;
1726 tc = talloc_chunk_from_ptr(context);
1727 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1728 while (tc) {
1729 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1730 while (tc && tc->prev) tc = tc->prev;
1731 if (tc) {
1732 tc = tc->parent;
1735 fflush(file);
1739 return 1 if ptr is a parent of context
1741 int talloc_is_parent(const void *context, const void *ptr)
1743 struct talloc_chunk *tc;
1745 if (context == NULL) {
1746 return 0;
1749 tc = talloc_chunk_from_ptr(context);
1750 while (tc) {
1751 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1752 while (tc && tc->prev) tc = tc->prev;
1753 if (tc) {
1754 tc = tc->parent;
1757 return 0;