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
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/
35 #if (SAMBA_VERSION_MAJOR<4)
37 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
38 * we trust ourselves... */
45 #define _TALLOC_SAMBA3
46 #endif /* (SAMBA_VERSION_MAJOR<4) */
47 #endif /* _SAMBA_BUILD_ */
49 #ifndef _TALLOC_SAMBA3
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() */
70 #define TALLOC_ABORT(reason) abort()
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)))
77 # define discard_const_p(type, ptr) ((type *)(ptr))
81 /* these macros gain us a few percent of speed on gcc */
83 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
84 as its first argument */
86 #define likely(x) __builtin_expect(!!(x), 1)
89 #define unlikely(x) __builtin_expect(!!(x), 0)
96 #define unlikely(x) (x)
100 /* this null_context is only used if talloc_enable_leak_report() or
101 talloc_enable_leak_report_full() is called, otherwise it remains
104 static void *null_context
;
105 static void *autofree_context
;
107 struct talloc_reference_handle
{
108 struct talloc_reference_handle
*next
, *prev
;
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
;
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
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();
160 talloc_abort_unknown_value();
166 /* hook into the front of the list */
167 #define _TLIST_ADD(list, p) \
171 (p)->next = (p)->prev = NULL; \
173 (list)->prev = (p); \
174 (p)->next = (list); \
180 /* remove an element from a list - element doesn't have to be in list. */
181 #define _TLIST_REMOVE(list, p) \
183 if ((p) == (list)) { \
184 (list) = (p)->next; \
185 if (list) (list)->prev = NULL; \
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; \
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
)) {
205 tc
= talloc_chunk_from_ptr(ptr
);
206 while (tc
->prev
) tc
=tc
->prev
;
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
;
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
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
));
250 static struct talloc_chunk
*talloc_alloc_pool(struct talloc_chunk
*parent
,
253 struct talloc_chunk
*pool_ctx
= NULL
;
255 struct talloc_chunk
*result
;
258 if (parent
== NULL
) {
262 if (parent
->flags
& TALLOC_FLAG_POOL
) {
265 else if (parent
->flags
& TALLOC_FLAG_POOLMEM
) {
266 pool_ctx
= (struct talloc_chunk
*)parent
->pool
;
269 if (pool_ctx
== 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
) {
285 result
= (struct talloc_chunk
*)pool_ctx
->pool
;
287 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
288 VALGRIND_MAKE_MEM_UNDEFINED(result
, size
);
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;
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
)) {
316 if (context
!= NULL
) {
317 tc
= talloc_alloc_pool(talloc_chunk_from_ptr(context
),
322 tc
= (struct talloc_chunk
*)malloc(TC_HDR_SIZE
+size
);
323 if (unlikely(tc
== NULL
)) return NULL
;
324 tc
->flags
= TALLOC_MAGIC
;
329 tc
->destructor
= NULL
;
334 if (likely(context
)) {
335 struct talloc_chunk
*parent
= talloc_chunk_from_ptr(context
);
338 parent
->child
->parent
= NULL
;
339 tc
->next
= parent
->child
;
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
)) {
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
);
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
))) {
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
);
417 more efficient way to add a name to a pointer - the name must point to a
420 static inline void _talloc_set_name_const(const void *ptr
, const char *name
)
422 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
427 internal talloc_named_const()
429 static inline void *_talloc_named_const(const void *context
, size_t size
, const char *name
)
433 ptr
= __talloc(context
, size
);
434 if (unlikely(ptr
== NULL
)) {
438 _talloc_set_name_const(ptr
, name
);
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
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,
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
);
475 internal talloc_free call
477 static inline int _talloc_free(void *ptr
)
479 struct talloc_chunk
*tc
;
481 if (unlikely(ptr
== NULL
)) {
485 tc
= talloc_chunk_from_ptr(ptr
);
487 if (unlikely(tc
->refs
)) {
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
496 is_child
= talloc_is_parent(tc
->refs
, ptr
);
497 _talloc_free(tc
->refs
);
499 return _talloc_free(ptr
);
504 if (unlikely(tc
->flags
& TALLOC_FLAG_LOOP
)) {
505 /* we have a free loop - stop looping */
509 if (unlikely(tc
->destructor
)) {
510 talloc_destructor_t d
= tc
->destructor
;
511 if (d
== (talloc_destructor_t
)-1) {
514 tc
->destructor
= (talloc_destructor_t
)-1;
519 tc
->destructor
= NULL
;
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
->flags
|= TALLOC_FLAG_LOOP
;
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) {
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
)) {
595 if (unlikely(new_ctx
== NULL
)) {
596 new_ctx
= null_context
;
599 tc
= talloc_chunk_from_ptr(ptr
);
601 if (unlikely(new_ctx
== NULL
)) {
603 _TLIST_REMOVE(tc
->parent
->child
, tc
);
604 if (tc
->parent
->child
) {
605 tc
->parent
->child
->parent
= tc
->parent
;
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
);
623 _TLIST_REMOVE(tc
->parent
->child
, tc
);
624 if (tc
->parent
->child
) {
625 tc
->parent
->child
->parent
= tc
->parent
;
628 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
629 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
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
);
658 if (context
== NULL
) break;
659 } else if (TC_PTR_FROM_CHUNK(p
) == context
) {
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
;
683 if (context
== NULL
) {
684 context
= null_context
;
687 if (talloc_unreference(context
, ptr
) == 0) {
691 if (context
== NULL
) {
692 if (talloc_parent_chunk(ptr
) != NULL
) {
696 if (talloc_chunk_from_ptr(context
) != talloc_parent_chunk(ptr
)) {
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
);
709 new_parent
= TC_PTR_FROM_CHUNK(new_p
);
714 if (talloc_unreference(new_parent
, ptr
) != 0) {
718 talloc_steal(new_parent
, ptr
);
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");
739 add a name to an existing pointer
741 const char *talloc_set_name(const void *ptr
, const char *fmt
, ...)
746 name
= talloc_set_name_v(ptr
, fmt
, ap
);
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
757 void *talloc_named(const void *context
, size_t size
, const char *fmt
, ...)
763 ptr
= __talloc(context
, size
);
764 if (unlikely(ptr
== NULL
)) return NULL
;
767 name
= talloc_set_name_v(ptr
, fmt
, ap
);
770 if (unlikely(name
== NULL
)) {
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
)) {
787 if (likely(tc
->name
)) {
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
)
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
);
811 this is for compatibility with older versions of talloc
813 void *talloc_init(const char *fmt
, ...)
820 * samba3 expects talloc_report_depth_cb(NULL, ...)
821 * reports all talloc'ed memory, so we need to enable
824 talloc_enable_null_tracking();
826 ptr
= __talloc(NULL
, 0);
827 if (unlikely(ptr
== NULL
)) return NULL
;
830 name
= talloc_set_name_v(ptr
, fmt
, ap
);
833 if (unlikely(name
== NULL
)) {
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
)) {
854 tc
= talloc_chunk_from_ptr(ptr
);
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
);
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
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
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
932 void *_talloc_realloc(const void *context
, void *ptr
, size_t size
, const char *name
)
934 struct talloc_chunk
*tc
;
936 bool malloced
= false;
938 /* size zero is equivalent to free() */
939 if (unlikely(size
== 0)) {
944 if (unlikely(size
>= MAX_TALLOC_SIZE
)) {
948 /* realloc(NULL) is equivalent to malloc() */
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
)) {
960 /* don't shrink if we have less than 1k to gain */
961 if ((size
< tc
->size
) && ((tc
->size
- size
) < 1024)) {
966 /* by resetting magic we catch users of the old memory */
967 tc
->flags
|= TALLOC_FLAG_FREE
;
970 new_ptr
= malloc(size
+ TC_HDR_SIZE
);
972 memcpy(new_ptr
, tc
, tc
->size
+ TC_HDR_SIZE
);
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
*)
982 if (new_ptr
== NULL
) {
983 new_ptr
= malloc(TC_HDR_SIZE
+size
);
988 memcpy(new_ptr
, tc
, MIN(tc
->size
,size
) + TC_HDR_SIZE
);
992 new_ptr
= realloc(tc
, size
+ TC_HDR_SIZE
);
995 if (unlikely(!new_ptr
)) {
996 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1000 tc
= (struct talloc_chunk
*)new_ptr
;
1001 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1003 tc
->flags
&= ~TALLOC_FLAG_POOLMEM
;
1006 tc
->parent
->child
= tc
;
1009 tc
->child
->parent
= tc
;
1013 tc
->prev
->next
= tc
;
1016 tc
->next
->prev
= tc
;
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
);
1038 return the total size of a talloc pool (subtree)
1040 size_t talloc_total_size(const void *ptr
)
1043 struct talloc_chunk
*c
, *tc
;
1052 tc
= talloc_chunk_from_ptr(ptr
);
1054 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1058 tc
->flags
|= TALLOC_FLAG_LOOP
;
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
;
1071 return the total number of blocks in a talloc pool (subtree)
1073 size_t talloc_total_blocks(const void *ptr
)
1076 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
1078 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1082 tc
->flags
|= TALLOC_FLAG_LOOP
;
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
;
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
;
1103 for (h
=tc
->refs
;h
;h
=h
->next
) {
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
,
1116 void *private_data
),
1119 struct talloc_chunk
*c
, *tc
;
1124 if (ptr
== NULL
) return;
1126 tc
= talloc_chunk_from_ptr(ptr
);
1128 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1132 callback(ptr
, depth
, max_depth
, 0, private_data
);
1134 if (max_depth
>= 0 && depth
>= max_depth
) {
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
);
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
;
1156 fprintf(f
, "%*sreference to: %s\n", depth
*4, "", name
);
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
));
1168 fprintf(f
, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1171 (unsigned long)talloc_total_size(ptr
),
1172 (unsigned long)talloc_total_blocks(ptr
),
1173 (int)talloc_reference_count(ptr
), ptr
);
1176 fprintf(f
, "content: ");
1177 if (talloc_total_size(ptr
)) {
1178 int tot
= talloc_total_size(ptr
);
1181 for (i
= 0; i
< tot
; i
++) {
1182 if ((((char *)ptr
)[i
] > 31) && (((char *)ptr
)[i
] < 126)) {
1183 fprintf(f
, "%c", ((char *)ptr
)[i
]);
1185 fprintf(f
, "~%02x", ((char *)ptr
)[i
]);
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
);
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
);
1283 memset(p
, '\0', size
);
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
);
1297 memcpy(newp
, p
, size
);
1303 static inline char *__talloc_strlendup(const void *t
, const char *p
, size_t len
)
1307 ret
= (char *)__talloc(t
, len
+ 1);
1308 if (unlikely(!ret
)) return NULL
;
1310 memcpy(ret
, p
, len
);
1313 _talloc_set_name_const(ret
, 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
)
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
);
1347 _talloc_set_name_const(ret
, ret
);
1352 * Appends at the end of the string.
1354 char *talloc_strdup_append(char *s
, const char *a
)
1357 return talloc_strdup(NULL
, a
);
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
)
1376 return talloc_strdup(NULL
, a
);
1383 slen
= talloc_get_size(s
);
1384 if (likely(slen
> 0)) {
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
)
1397 return talloc_strdup(NULL
, a
);
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
)
1416 return talloc_strdup(NULL
, a
);
1423 slen
= talloc_get_size(s
);
1424 if (likely(slen
> 0)) {
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)
1435 #define va_copy(dest, src) (dest) = (src)
1439 char *talloc_vasprintf(const void *t
, const char *fmt
, va_list ap
)
1446 /* this call looks strange, but it makes it work on older solaris boxes */
1448 len
= vsnprintf(&c
, 1, fmt
, ap2
);
1450 if (unlikely(len
< 0)) {
1454 ret
= (char *)__talloc(t
, len
+1);
1455 if (unlikely(!ret
)) return NULL
;
1458 vsnprintf(ret
, len
+1, fmt
, ap2
);
1461 _talloc_set_name_const(ret
, 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
, ...)
1476 ret
= talloc_vasprintf(t
, fmt
, ap
);
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
)
1493 alen
= vsnprintf(&c
, 1, fmt
, ap2
);
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.
1506 s
= talloc_realloc(NULL
, s
, char, slen
+ alen
+ 1);
1507 if (!s
) return NULL
;
1510 vsnprintf(s
+ slen
, alen
+ 1, fmt
, ap2
);
1513 _talloc_set_name_const(s
, 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
1523 char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
)
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
)
1542 return talloc_vasprintf(NULL
, fmt
, ap
);
1545 slen
= talloc_get_size(s
);
1546 if (likely(slen
> 0)) {
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
, ...)
1563 s
= talloc_vasprintf_append(s
, fmt
, ap
);
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
1573 char *talloc_asprintf_append_buffer(char *s
, const char *fmt
, ...)
1578 s
= talloc_vasprintf_append_buffer(s
, fmt
, ap
);
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
) {
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
) {
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
) {
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
;
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
)
1659 tc
= talloc_chunk_from_ptr(context
);
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
) {
1675 tc
= talloc_chunk_from_ptr(context
);
1677 if (tc
->name
&& strcmp(tc
->name
, name
) == 0) {
1678 return TC_PTR_FROM_CHUNK(tc
);
1680 while (tc
&& tc
->prev
) tc
= tc
->prev
;
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");
1700 tc
= talloc_chunk_from_ptr(context
);
1701 fprintf(file
, "talloc parents of '%s'\n", talloc_get_name(context
));
1703 fprintf(file
, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc
)));
1704 while (tc
&& tc
->prev
) tc
= tc
->prev
;
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
) {
1723 tc
= talloc_chunk_from_ptr(context
);
1725 if (TC_PTR_FROM_CHUNK(tc
) == ptr
) return 1;
1726 while (tc
&& tc
->prev
) tc
= tc
->prev
;