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/
33
// Hardcode these for MPlayer assuming a working system.
34
// Original used autoconf detection with workarounds for broken systems.
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)
48
for (len = 0; len < max; len++) {
60
#if (SAMBA_VERSION_MAJOR<4)
62
/* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
63
* we trust ourselves... */
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"
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() */
96
#define TALLOC_ABORT(reason) abort()
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)))
103
# define discard_const_p(type, ptr) ((type *)(ptr))
107
/* these macros gain us a few percent of speed on gcc */
109
/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
110
as its first argument */
112
#define likely(x) __builtin_expect(!!(x), 1)
115
#define unlikely(x) __builtin_expect(!!(x), 0)
119
#define likely(x) (x)
122
#define unlikely(x) (x)
126
/* this null_context is only used if talloc_enable_leak_report() or
127
talloc_enable_leak_report_full() is called, otherwise it remains
130
static void *null_context;
131
static void *autofree_context;
133
struct talloc_reference_handle {
134
struct talloc_reference_handle *next, *prev;
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;
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
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();
186
talloc_abort_unknown_value();
192
/* hook into the front of the list */
193
#define _TLIST_ADD(list, p) \
197
(p)->next = (p)->prev = NULL; \
199
(list)->prev = (p); \
200
(p)->next = (list); \
206
/* remove an element from a list - element doesn't have to be in list. */
207
#define _TLIST_REMOVE(list, p) \
209
if ((p) == (list)) { \
210
(list) = (p)->next; \
211
if (list) (list)->prev = NULL; \
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; \
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)) {
231
tc = talloc_chunk_from_ptr(ptr);
232
while (tc->prev) tc=tc->prev;
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;
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
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));
276
static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
279
struct talloc_chunk *pool_ctx = NULL;
281
struct talloc_chunk *result;
284
if (parent == NULL) {
288
if (parent->flags & TALLOC_FLAG_POOL) {
291
else if (parent->flags & TALLOC_FLAG_POOLMEM) {
292
pool_ctx = (struct talloc_chunk *)parent->pool;
295
if (pool_ctx == 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) {
311
result = (struct talloc_chunk *)pool_ctx->pool;
313
#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
314
VALGRIND_MAKE_MEM_UNDEFINED(result, size);
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;
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),
348
tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
349
if (unlikely(tc == NULL)) abort(); // return NULL;
350
tc->flags = TALLOC_MAGIC;
355
tc->destructor = NULL;
360
if (likely(context)) {
361
struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
364
parent->child->parent = NULL;
365
tc->next = parent->child;
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)) {
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);
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))) {
431
helper for talloc_reference()
433
this is referenced by a function pointer and should not be inline
435
static int talloc_reference_destructor(void *ptr)
437
struct talloc_reference_handle *handle = ptr;
438
struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
439
_TLIST_REMOVE(ptr_tc->refs, handle);
444
more efficient way to add a name to a pointer - the name must point to a
447
static inline void _talloc_set_name_const(const void *ptr, const char *name)
449
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
454
internal talloc_named_const()
456
static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
460
ptr = __talloc(context, size);
461
if (unlikely(ptr == NULL)) {
465
_talloc_set_name_const(ptr, name);
471
make a secondary reference to a pointer, hanging off the given context.
472
the pointer remains valid until both the original caller and this given
475
the major use for this is when two different structures need to reference the
476
same underlying data, and you want to be able to free the two instances separately,
479
void *_talloc_reference(const void *context, const void *ptr)
481
struct talloc_chunk *tc;
482
struct talloc_reference_handle *handle;
483
if (unlikely(ptr == NULL)) return NULL;
485
tc = talloc_chunk_from_ptr(ptr);
486
handle = (struct talloc_reference_handle *)_talloc_named_const(context,
487
sizeof(struct talloc_reference_handle),
488
TALLOC_MAGIC_REFERENCE);
489
if (unlikely(handle == NULL)) return NULL;
491
/* note that we hang the destructor off the handle, not the
492
main context as that allows the caller to still setup their
493
own destructor on the context if they want to */
494
talloc_set_destructor(handle, talloc_reference_destructor);
495
handle->ptr = discard_const_p(void, ptr);
496
_TLIST_ADD(tc->refs, handle);
502
internal talloc_free call
504
static inline int _talloc_free(void *ptr)
506
struct talloc_chunk *tc;
508
if (unlikely(ptr == NULL)) {
512
tc = talloc_chunk_from_ptr(ptr);
514
if (unlikely(tc->refs)) {
516
/* check this is a reference from a child or grantchild
517
* back to it's parent or grantparent
519
* in that case we need to remove the reference and
520
* call another instance of talloc_free() on the current
523
is_child = talloc_is_parent(tc->refs, ptr);
524
_talloc_free(tc->refs);
526
return _talloc_free(ptr);
531
if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
532
/* we have a free loop - stop looping */
536
if (unlikely(tc->destructor)) {
537
talloc_destructor_t d = tc->destructor;
538
if (d == (talloc_destructor_t)-1) {
541
tc->destructor = (talloc_destructor_t)-1;
546
tc->destructor = NULL;
550
_TLIST_REMOVE(tc->parent->child, tc);
551
if (tc->parent->child) {
552
tc->parent->child->parent = tc->parent;
555
if (tc->prev) tc->prev->next = tc->next;
556
if (tc->next) tc->next->prev = tc->prev;
559
tc->flags |= TALLOC_FLAG_LOOP;
562
/* we need to work out who will own an abandoned child
563
if it cannot be freed. In priority order, the first
564
choice is owner of any remaining reference to this
565
pointer, the second choice is our parent, and the
566
final choice is the null context. */
567
void *child = TC_PTR_FROM_CHUNK(tc->child);
568
const void *new_parent = null_context;
569
if (unlikely(tc->child->refs)) {
570
struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
571
if (p) new_parent = TC_PTR_FROM_CHUNK(p);
573
if (unlikely(_talloc_free(child) == -1)) {
574
if (new_parent == null_context) {
575
struct talloc_chunk *p = talloc_parent_chunk(ptr);
576
if (p) new_parent = TC_PTR_FROM_CHUNK(p);
578
talloc_steal(new_parent, child);
582
tc->flags |= TALLOC_FLAG_FREE;
584
if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
585
struct talloc_chunk *pool;
586
unsigned int *pool_object_count;
588
pool = (tc->flags & TALLOC_FLAG_POOL)
589
? tc : (struct talloc_chunk *)tc->pool;
591
pool_object_count = talloc_pool_objectcount(pool);
593
if (*pool_object_count == 0) {
594
TALLOC_ABORT("Pool object count zero!");
597
*pool_object_count -= 1;
599
if (*pool_object_count == 0) {
610
move a lump of memory from one talloc context to another return the
611
ptr on success, or NULL if it could not be transferred.
612
passing NULL as ptr will always return NULL with no side effects.
614
void *_talloc_steal(const void *new_ctx, const void *ptr)
616
struct talloc_chunk *tc, *new_tc;
618
if (unlikely(!ptr)) {
622
if (unlikely(new_ctx == NULL)) {
623
new_ctx = null_context;
626
tc = talloc_chunk_from_ptr(ptr);
628
if (unlikely(new_ctx == NULL)) {
630
_TLIST_REMOVE(tc->parent->child, tc);
631
if (tc->parent->child) {
632
tc->parent->child->parent = tc->parent;
635
if (tc->prev) tc->prev->next = tc->next;
636
if (tc->next) tc->next->prev = tc->prev;
639
tc->parent = tc->next = tc->prev = NULL;
640
return discard_const_p(void, ptr);
643
new_tc = talloc_chunk_from_ptr(new_ctx);
645
if (unlikely(tc == new_tc || tc->parent == new_tc)) {
646
return discard_const_p(void, ptr);
650
_TLIST_REMOVE(tc->parent->child, tc);
651
if (tc->parent->child) {
652
tc->parent->child->parent = tc->parent;
655
if (tc->prev) tc->prev->next = tc->next;
656
if (tc->next) tc->next->prev = tc->prev;
660
if (new_tc->child) new_tc->child->parent = NULL;
661
_TLIST_ADD(new_tc->child, tc);
663
return discard_const_p(void, ptr);
669
remove a secondary reference to a pointer. This undo's what
670
talloc_reference() has done. The context and pointer arguments
671
must match those given to a talloc_reference()
673
static inline int talloc_unreference(const void *context, const void *ptr)
675
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
676
struct talloc_reference_handle *h;
678
if (unlikely(context == NULL)) {
679
context = null_context;
682
for (h=tc->refs;h;h=h->next) {
683
struct talloc_chunk *p = talloc_parent_chunk(h);
685
if (context == NULL) break;
686
} else if (TC_PTR_FROM_CHUNK(p) == context) {
694
return _talloc_free(h);
698
remove a specific parent context from a pointer. This is a more
699
controlled varient of talloc_free()
701
int talloc_unlink(const void *context, void *ptr)
703
struct talloc_chunk *tc_p, *new_p;
710
if (context == NULL) {
711
context = null_context;
714
if (talloc_unreference(context, ptr) == 0) {
718
if (context == NULL) {
719
if (talloc_parent_chunk(ptr) != NULL) {
723
if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
728
tc_p = talloc_chunk_from_ptr(ptr);
730
if (tc_p->refs == NULL) {
731
return _talloc_free(ptr);
734
new_p = talloc_parent_chunk(tc_p->refs);
736
new_parent = TC_PTR_FROM_CHUNK(new_p);
741
if (talloc_unreference(new_parent, ptr) != 0) {
745
talloc_steal(new_parent, ptr);
751
add a name to an existing pointer - va_list version
753
static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
755
static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
757
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
758
tc->name = talloc_vasprintf(ptr, fmt, ap);
759
if (likely(tc->name)) {
760
_talloc_set_name_const(tc->name, ".name");
766
add a name to an existing pointer
768
const char *talloc_set_name(const void *ptr, const char *fmt, ...)
773
name = talloc_set_name_v(ptr, fmt, ap);
780
create a named talloc pointer. Any talloc pointer can be named, and
781
talloc_named() operates just like talloc() except that it allows you
784
void *talloc_named(const void *context, size_t size, const char *fmt, ...)
790
ptr = __talloc(context, size);
791
if (unlikely(ptr == NULL)) return NULL;
794
name = talloc_set_name_v(ptr, fmt, ap);
797
if (unlikely(name == NULL)) {
806
return the name of a talloc ptr, or "UNNAMED"
808
const char *talloc_get_name(const void *ptr)
810
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
811
if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
814
if (likely(tc->name)) {
822
check if a pointer has the given name. If it does, return the pointer,
823
otherwise return NULL
825
void *talloc_check_name(const void *ptr, const char *name)
828
if (unlikely(ptr == NULL)) return NULL;
829
pname = talloc_get_name(ptr);
830
if (likely(pname == name || strcmp(pname, name) == 0)) {
831
return discard_const_p(void, ptr);
838
this is for compatibility with older versions of talloc
840
void *talloc_init(const char *fmt, ...)
847
* samba3 expects talloc_report_depth_cb(NULL, ...)
848
* reports all talloc'ed memory, so we need to enable
851
talloc_enable_null_tracking();
853
ptr = __talloc(NULL, 0);
854
if (unlikely(ptr == NULL)) return NULL;
857
name = talloc_set_name_v(ptr, fmt, ap);
860
if (unlikely(name == NULL)) {
869
this is a replacement for the Samba3 talloc_destroy_pool functionality. It
870
should probably not be used in new code. It's in here to keep the talloc
871
code consistent across Samba 3 and 4.
873
void talloc_free_children(void *ptr)
875
struct talloc_chunk *tc;
877
if (unlikely(ptr == NULL)) {
881
tc = talloc_chunk_from_ptr(ptr);
884
/* we need to work out who will own an abandoned child
885
if it cannot be freed. In priority order, the first
886
choice is owner of any remaining reference to this
887
pointer, the second choice is our parent, and the
888
final choice is the null context. */
889
void *child = TC_PTR_FROM_CHUNK(tc->child);
890
const void *new_parent = null_context;
891
if (unlikely(tc->child->refs)) {
892
struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
893
if (p) new_parent = TC_PTR_FROM_CHUNK(p);
895
if (unlikely(_talloc_free(child) == -1)) {
896
if (new_parent == null_context) {
897
struct talloc_chunk *p = talloc_parent_chunk(ptr);
898
if (p) new_parent = TC_PTR_FROM_CHUNK(p);
900
talloc_steal(new_parent, child);
904
if ((tc->flags & TALLOC_FLAG_POOL)
905
&& (*talloc_pool_objectcount(tc) == 1)) {
906
tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
907
#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
908
VALGRIND_MAKE_MEM_NOACCESS(
909
tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
915
Allocate a bit of memory as a child of an existing pointer
917
void *_talloc(const void *context, size_t size)
919
return __talloc(context, size);
923
externally callable talloc_set_name_const()
925
void talloc_set_name_const(const void *ptr, const char *name)
927
_talloc_set_name_const(ptr, name);
931
create a named talloc pointer. Any talloc pointer can be named, and
932
talloc_named() operates just like talloc() except that it allows you
935
void *talloc_named_const(const void *context, size_t size, const char *name)
937
return _talloc_named_const(context, size, name);
941
free a talloc pointer. This also frees all child pointers of this
944
return 0 if the memory is actually freed, otherwise -1. The memory
945
will not be freed if the ref_count is > 1 or the destructor (if
946
any) returns non-zero
948
int talloc_free(void *ptr)
950
return _talloc_free(ptr);
956
A talloc version of realloc. The context argument is only used if
959
void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
961
struct talloc_chunk *tc;
963
bool malloced = false;
965
/* size zero is equivalent to free() */
966
if (unlikely(size == 0)) {
971
if (unlikely(size >= MAX_TALLOC_SIZE)) {
972
abort(); // return NULL;
975
/* realloc(NULL) is equivalent to malloc() */
977
return _talloc_named_const(context, size, name);
980
tc = talloc_chunk_from_ptr(ptr);
982
/* don't allow realloc on referenced pointers */
983
if (unlikely(tc->refs)) {
984
abort(); // return NULL;
987
/* don't shrink if we have less than 1k to gain */
988
if ((size < tc->size) && ((tc->size - size) < 1024)) {
993
/* by resetting magic we catch users of the old memory */
994
tc->flags |= TALLOC_FLAG_FREE;
997
new_ptr = malloc(size + TC_HDR_SIZE);
999
memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
1003
if (tc->flags & TALLOC_FLAG_POOLMEM) {
1005
new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1006
*talloc_pool_objectcount((struct talloc_chunk *)
1009
if (new_ptr == NULL) {
1010
new_ptr = malloc(TC_HDR_SIZE+size);
1015
memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1019
new_ptr = realloc(tc, size + TC_HDR_SIZE);
1022
if (unlikely(!new_ptr)) {
1023
tc->flags &= ~TALLOC_FLAG_FREE;
1024
abort(); // return NULL;
1027
tc = (struct talloc_chunk *)new_ptr;
1028
tc->flags &= ~TALLOC_FLAG_FREE;
1030
tc->flags &= ~TALLOC_FLAG_POOLMEM;
1033
tc->parent->child = tc;
1036
tc->child->parent = tc;
1040
tc->prev->next = tc;
1043
tc->next->prev = tc;
1047
_talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1049
return TC_PTR_FROM_CHUNK(tc);
1053
a wrapper around talloc_steal() for situations where you are moving a pointer
1054
between two structures, and want the old pointer to be set to NULL
1056
void *_talloc_move(const void *new_ctx, const void *_pptr)
1058
const void **pptr = discard_const_p(const void *,_pptr);
1059
void *ret = _talloc_steal(new_ctx, *pptr);
1065
return the total size of a talloc pool (subtree)
1067
size_t talloc_total_size(const void *ptr)
1070
struct talloc_chunk *c, *tc;
1079
tc = talloc_chunk_from_ptr(ptr);
1081
if (tc->flags & TALLOC_FLAG_LOOP) {
1085
tc->flags |= TALLOC_FLAG_LOOP;
1088
for (c=tc->child;c;c=c->next) {
1089
total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1092
tc->flags &= ~TALLOC_FLAG_LOOP;
1098
return the total number of blocks in a talloc pool (subtree)
1100
size_t talloc_total_blocks(const void *ptr)
1103
struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1105
if (tc->flags & TALLOC_FLAG_LOOP) {
1109
tc->flags |= TALLOC_FLAG_LOOP;
1112
for (c=tc->child;c;c=c->next) {
1113
total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1116
tc->flags &= ~TALLOC_FLAG_LOOP;
1122
return the number of external references to a pointer
1124
size_t talloc_reference_count(const void *ptr)
1126
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1127
struct talloc_reference_handle *h;
1130
for (h=tc->refs;h;h=h->next) {
1137
report on memory usage by all children of a pointer, giving a full tree view
1139
void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1140
void (*callback)(const void *ptr,
1141
int depth, int max_depth,
1143
void *private_data),
1146
struct talloc_chunk *c, *tc;
1151
if (ptr == NULL) return;
1153
tc = talloc_chunk_from_ptr(ptr);
1155
if (tc->flags & TALLOC_FLAG_LOOP) {
1159
callback(ptr, depth, max_depth, 0, private_data);
1161
if (max_depth >= 0 && depth >= max_depth) {
1165
tc->flags |= TALLOC_FLAG_LOOP;
1166
for (c=tc->child;c;c=c->next) {
1167
if (c->name == TALLOC_MAGIC_REFERENCE) {
1168
struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1169
callback(h->ptr, depth + 1, max_depth, 1, private_data);
1171
talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1174
tc->flags &= ~TALLOC_FLAG_LOOP;
1177
static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1179
const char *name = talloc_get_name(ptr);
1180
FILE *f = (FILE *)_f;
1183
fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1188
fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1189
(max_depth < 0 ? "full " :""), name,
1190
(unsigned long)talloc_total_size(ptr),
1191
(unsigned long)talloc_total_blocks(ptr));
1195
fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1198
(unsigned long)talloc_total_size(ptr),
1199
(unsigned long)talloc_total_blocks(ptr),
1200
(int)talloc_reference_count(ptr), ptr);
1203
fprintf(f, "content: ");
1204
if (talloc_total_size(ptr)) {
1205
int tot = talloc_total_size(ptr);
1208
for (i = 0; i < tot; i++) {
1209
if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1210
fprintf(f, "%c", ((char *)ptr)[i]);
1212
fprintf(f, "~%02x", ((char *)ptr)[i]);
1221
report on memory usage by all children of a pointer, giving a full tree view
1223
void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1225
talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1230
report on memory usage by all children of a pointer, giving a full tree view
1232
void talloc_report_full(const void *ptr, FILE *f)
1234
talloc_report_depth_file(ptr, 0, -1, f);
1238
report on memory usage by all children of a pointer
1240
void talloc_report(const void *ptr, FILE *f)
1242
talloc_report_depth_file(ptr, 0, 1, f);
1246
report on any memory hanging off the null context
1248
static void talloc_report_null(void)
1250
if (talloc_total_size(null_context) != 0) {
1251
talloc_report(null_context, stderr);
1256
report on any memory hanging off the null context
1258
static void talloc_report_null_full(void)
1260
if (talloc_total_size(null_context) != 0) {
1261
talloc_report_full(null_context, stderr);
1266
enable tracking of the NULL context
1268
void talloc_enable_null_tracking(void)
1270
if (null_context == NULL) {
1271
null_context = _talloc_named_const(NULL, 0, "null_context");
1276
disable tracking of the NULL context
1278
void talloc_disable_null_tracking(void)
1280
_talloc_free(null_context);
1281
null_context = NULL;
1285
enable leak reporting on exit
1287
void talloc_enable_leak_report(void)
1289
talloc_enable_null_tracking();
1290
atexit(talloc_report_null);
1294
enable full leak reporting on exit
1296
void talloc_enable_leak_report_full(void)
1298
talloc_enable_null_tracking();
1299
atexit(talloc_report_null_full);
1303
talloc and zero memory.
1305
void *_talloc_zero(const void *ctx, size_t size, const char *name)
1307
void *p = _talloc_named_const(ctx, size, name);
1310
memset(p, '\0', size);
1317
memdup with a talloc.
1319
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1321
void *newp = _talloc_named_const(t, size, name);
1324
memcpy(newp, p, size);
1330
static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1334
ret = (char *)__talloc(t, len + 1);
1335
if (unlikely(!ret)) return NULL;
1337
memcpy(ret, p, len);
1340
_talloc_set_name_const(ret, ret);
1345
strdup with a talloc
1347
char *talloc_strdup(const void *t, const char *p)
1349
if (unlikely(!p)) return NULL;
1350
return __talloc_strlendup(t, p, strlen(p));
1354
strndup with a talloc
1356
char *talloc_strndup(const void *t, const char *p, size_t n)
1358
if (unlikely(!p)) return NULL;
1359
return __talloc_strlendup(t, p, strnlen(p, n));
1362
static inline char *__talloc_strlendup_append(char *s, size_t slen,
1363
const char *a, size_t alen)
1367
ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1368
if (unlikely(!ret)) return NULL;
1370
/* append the string and the trailing \0 */
1371
memcpy(&ret[slen], a, alen);
1374
_talloc_set_name_const(ret, ret);
1379
* Appends at the end of the string.
1381
char *talloc_strdup_append(char *s, const char *a)
1384
return talloc_strdup(NULL, a);
1391
return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1395
* Appends at the end of the talloc'ed buffer,
1396
* not the end of the string.
1398
char *talloc_strdup_append_buffer(char *s, const char *a)
1403
return talloc_strdup(NULL, a);
1410
slen = talloc_get_size(s);
1411
if (likely(slen > 0)) {
1415
return __talloc_strlendup_append(s, slen, a, strlen(a));
1419
* Appends at the end of the string.
1421
char *talloc_strndup_append(char *s, const char *a, size_t n)
1424
return talloc_strndup(NULL, a, n);
1431
return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1435
* Appends at the end of the talloc'ed buffer,
1436
* not the end of the string.
1438
char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1443
return talloc_strndup(NULL, a, n);
1450
slen = talloc_get_size(s);
1451
if (likely(slen > 0)) {
1455
return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1458
#ifndef HAVE_VA_COPY
1459
#ifdef HAVE___VA_COPY
1460
#define va_copy(dest, src) __va_copy(dest, src)
1462
#define va_copy(dest, src) (dest) = (src)
1466
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1473
/* this call looks strange, but it makes it work on older solaris boxes */
1475
len = vsnprintf(&c, 1, fmt, ap2);
1477
if (unlikely(len < 0)) {
1478
abort(); // return NULL;
1481
ret = (char *)__talloc(t, len+1);
1482
if (unlikely(!ret)) return NULL;
1485
vsnprintf(ret, len+1, fmt, ap2);
1488
_talloc_set_name_const(ret, ret);
1494
Perform string formatting, and return a pointer to newly allocated
1495
memory holding the result, inside a memory pool.
1497
char *talloc_asprintf(const void *t, const char *fmt, ...)
1503
ret = talloc_vasprintf(t, fmt, ap);
1508
static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1509
const char *fmt, va_list ap)
1510
PRINTF_ATTRIBUTE(3,0);
1512
static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1513
const char *fmt, va_list ap)
1520
alen = vsnprintf(&c, 1, fmt, ap2);
1524
/* Either the vsnprintf failed or the format resulted in
1525
* no characters being formatted. In the former case, we
1526
* ought to return NULL, in the latter we ought to return
1527
* the original string. Most current callers of this
1528
* function expect it to never return NULL.
1533
s = talloc_realloc(NULL, s, char, slen + alen + 1);
1534
if (!s) return NULL;
1537
vsnprintf(s + slen, alen + 1, fmt, ap2);
1540
_talloc_set_name_const(s, s);
1545
* Realloc @p s to append the formatted result of @p fmt and @p ap,
1546
* and return @p s, which may have moved. Good for gradually
1547
* accumulating output into a string buffer. Appends at the end
1550
char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1553
return talloc_vasprintf(NULL, fmt, ap);
1556
return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1560
* Realloc @p s to append the formatted result of @p fmt and @p ap,
1561
* and return @p s, which may have moved. Always appends at the
1562
* end of the talloc'ed buffer, not the end of the string.
1564
char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1569
return talloc_vasprintf(NULL, fmt, ap);
1572
slen = talloc_get_size(s);
1573
if (likely(slen > 0)) {
1577
return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1581
Realloc @p s to append the formatted result of @p fmt and return @p
1582
s, which may have moved. Good for gradually accumulating output
1583
into a string buffer.
1585
char *talloc_asprintf_append(char *s, const char *fmt, ...)
1590
s = talloc_vasprintf_append(s, fmt, ap);
1596
Realloc @p s to append the formatted result of @p fmt and return @p
1597
s, which may have moved. Good for gradually accumulating output
1600
char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1605
s = talloc_vasprintf_append_buffer(s, fmt, ap);
1611
alloc an array, checking for integer overflow in the array size
1613
void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1615
if (count >= MAX_TALLOC_SIZE/el_size) {
1616
abort(); // return NULL;
1618
return _talloc_named_const(ctx, el_size * count, name);
1622
alloc an zero array, checking for integer overflow in the array size
1624
void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1626
if (count >= MAX_TALLOC_SIZE/el_size) {
1627
abort(); // return NULL;
1629
return _talloc_zero(ctx, el_size * count, name);
1633
realloc an array, checking for integer overflow in the array size
1635
void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1637
if (count >= MAX_TALLOC_SIZE/el_size) {
1638
abort(); // return NULL;
1640
return _talloc_realloc(ctx, ptr, el_size * count, name);
1644
a function version of talloc_realloc(), so it can be passed as a function pointer
1645
to libraries that want a realloc function (a realloc function encapsulates
1646
all the basic capabilities of an allocation library, which is why this is useful)
1648
void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1650
return _talloc_realloc(context, ptr, size, NULL);
1654
static int talloc_autofree_destructor(void *ptr)
1656
autofree_context = NULL;
1660
static void talloc_autofree(void)
1662
_talloc_free(autofree_context);
1666
return a context which will be auto-freed on exit
1667
this is useful for reducing the noise in leak reports
1669
void *talloc_autofree_context(void)
1671
if (autofree_context == NULL) {
1672
autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1673
talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1674
atexit(talloc_autofree);
1676
return autofree_context;
1679
size_t talloc_get_size(const void *context)
1681
struct talloc_chunk *tc;
1683
if (context == NULL)
1686
tc = talloc_chunk_from_ptr(context);
1692
find a parent of this context that has the given name, if any
1694
void *talloc_find_parent_byname(const void *context, const char *name)
1696
struct talloc_chunk *tc;
1698
if (context == NULL) {
1702
tc = talloc_chunk_from_ptr(context);
1704
if (tc->name && strcmp(tc->name, name) == 0) {
1705
return TC_PTR_FROM_CHUNK(tc);
1707
while (tc && tc->prev) tc = tc->prev;
1716
show the parentage of a context
1718
void talloc_show_parents(const void *context, FILE *file)
1720
struct talloc_chunk *tc;
1722
if (context == NULL) {
1723
fprintf(file, "talloc no parents for NULL\n");
1727
tc = talloc_chunk_from_ptr(context);
1728
fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1730
fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1731
while (tc && tc->prev) tc = tc->prev;
1740
return 1 if ptr is a parent of context
1742
int talloc_is_parent(const void *context, const void *ptr)
1744
struct talloc_chunk *tc;
1746
if (context == NULL) {
1750
tc = talloc_chunk_from_ptr(context);
1752
if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1753
while (tc && tc->prev) tc = tc->prev;