talloc: Put pool-specific data before the chunk
[Samba.git] / lib / talloc / talloc.c
bloba553050e6eb48a3669f6beddc4759a564022a892
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 #include "replace.h"
34 #include "talloc.h"
36 #ifdef TALLOC_BUILD_VERSION_MAJOR
37 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
38 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
39 #endif
40 #endif
42 #ifdef TALLOC_BUILD_VERSION_MINOR
43 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
44 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
45 #endif
46 #endif
48 /* Special macros that are no-ops except when run under Valgrind on
49 * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */
50 #ifdef HAVE_VALGRIND_MEMCHECK_H
51 /* memcheck.h includes valgrind.h */
52 #include <valgrind/memcheck.h>
53 #elif defined(HAVE_VALGRIND_H)
54 #include <valgrind.h>
55 #endif
57 /* use this to force every realloc to change the pointer, to stress test
58 code that might not cope */
59 #define ALWAYS_REALLOC 0
62 #define MAX_TALLOC_SIZE 0x10000000
63 #define TALLOC_MAGIC_BASE 0xe814ec70
64 #define TALLOC_MAGIC ( \
65 TALLOC_MAGIC_BASE + \
66 (TALLOC_VERSION_MAJOR << 12) + \
67 (TALLOC_VERSION_MINOR << 4) \
70 #define TALLOC_FLAG_FREE 0x01
71 #define TALLOC_FLAG_LOOP 0x02
72 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
73 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
75 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
77 /* by default we abort when given a bad pointer (such as when talloc_free() is called
78 on a pointer that came from malloc() */
79 #ifndef TALLOC_ABORT
80 #define TALLOC_ABORT(reason) abort()
81 #endif
83 #ifndef discard_const_p
84 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
85 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
86 #else
87 # define discard_const_p(type, ptr) ((type *)(ptr))
88 #endif
89 #endif
91 /* these macros gain us a few percent of speed on gcc */
92 #if (__GNUC__ >= 3)
93 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
94 as its first argument */
95 #ifndef likely
96 #define likely(x) __builtin_expect(!!(x), 1)
97 #endif
98 #ifndef unlikely
99 #define unlikely(x) __builtin_expect(!!(x), 0)
100 #endif
101 #else
102 #ifndef likely
103 #define likely(x) (x)
104 #endif
105 #ifndef unlikely
106 #define unlikely(x) (x)
107 #endif
108 #endif
110 /* this null_context is only used if talloc_enable_leak_report() or
111 talloc_enable_leak_report_full() is called, otherwise it remains
112 NULL
114 static void *null_context;
115 static void *autofree_context;
117 /* used to enable fill of memory on free, which can be useful for
118 * catching use after free errors when valgrind is too slow
120 static struct {
121 bool initialised;
122 bool enabled;
123 uint8_t fill_value;
124 } talloc_fill;
126 #define TALLOC_FILL_ENV "TALLOC_FREE_FILL"
129 * do not wipe the header, to allow the
130 * double-free logic to still work
132 #define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \
133 if (unlikely(talloc_fill.enabled)) { \
134 size_t _flen = (_tc)->size; \
135 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
136 memset(_fptr, talloc_fill.fill_value, _flen); \
138 } while (0)
140 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
141 /* Mark the whole chunk as not accessable */
142 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \
143 size_t _flen = TC_HDR_SIZE + (_tc)->size; \
144 char *_fptr = (char *)(_tc); \
145 VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
146 } while(0)
147 #else
148 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0)
149 #endif
151 #define TC_INVALIDATE_FULL_CHUNK(_tc) do { \
152 TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \
153 TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \
154 } while (0)
156 #define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
157 if (unlikely(talloc_fill.enabled)) { \
158 size_t _flen = (_tc)->size - (_new_size); \
159 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
160 _fptr += (_new_size); \
161 memset(_fptr, talloc_fill.fill_value, _flen); \
163 } while (0)
165 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
166 /* Mark the unused bytes not accessable */
167 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
168 size_t _flen = (_tc)->size - (_new_size); \
169 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
170 _fptr += (_new_size); \
171 VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
172 } while (0)
173 #else
174 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
175 #endif
177 #define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \
178 TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \
179 TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
180 } while (0)
182 #define TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
183 if (unlikely(talloc_fill.enabled)) { \
184 size_t _flen = (_tc)->size - (_new_size); \
185 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
186 _fptr += (_new_size); \
187 memset(_fptr, talloc_fill.fill_value, _flen); \
189 } while (0)
191 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
192 /* Mark the unused bytes as undefined */
193 #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
194 size_t _flen = (_tc)->size - (_new_size); \
195 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
196 _fptr += (_new_size); \
197 VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
198 } while (0)
199 #else
200 #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
201 #endif
203 #define TC_UNDEFINE_SHRINK_CHUNK(_tc, _new_size) do { \
204 TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size); \
205 TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
206 } while (0)
208 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
209 /* Mark the new bytes as undefined */
210 #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { \
211 size_t _old_used = TC_HDR_SIZE + (_tc)->size; \
212 size_t _new_used = TC_HDR_SIZE + (_new_size); \
213 size_t _flen = _new_used - _old_used; \
214 char *_fptr = _old_used + (char *)(_tc); \
215 VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
216 } while (0)
217 #else
218 #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
219 #endif
221 #define TC_UNDEFINE_GROW_CHUNK(_tc, _new_size) do { \
222 TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \
223 } while (0)
225 struct talloc_reference_handle {
226 struct talloc_reference_handle *next, *prev;
227 void *ptr;
228 const char *location;
231 struct talloc_memlimit {
232 struct talloc_chunk *parent;
233 struct talloc_memlimit *upper;
234 size_t max_size;
235 size_t cur_size;
238 static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size);
239 static void talloc_memlimit_grow(struct talloc_memlimit *limit,
240 size_t size);
241 static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
242 size_t size);
243 static void talloc_memlimit_update_on_free(struct talloc_chunk *tc);
245 typedef int (*talloc_destructor_t)(void *);
247 struct talloc_pool_hdr;
249 struct talloc_chunk {
250 struct talloc_chunk *next, *prev;
251 struct talloc_chunk *parent, *child;
252 struct talloc_reference_handle *refs;
253 talloc_destructor_t destructor;
254 const char *name;
255 size_t size;
256 unsigned flags;
259 * limit semantics:
260 * if 'limit' is set it means all *new* children of the context will
261 * be limited to a total aggregate size ox max_size for memory
262 * allocations.
263 * cur_size is used to keep track of the current use
265 struct talloc_memlimit *limit;
268 * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
269 * is a pointer to the struct talloc_chunk of the pool that it was
270 * allocated from. This way children can quickly find the pool to chew
271 * from.
273 struct talloc_pool_hdr *pool;
276 /* 16 byte alignment seems to keep everyone happy */
277 #define TC_ALIGN16(s) (((s)+15)&~15)
278 #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
279 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
281 _PUBLIC_ int talloc_version_major(void)
283 return TALLOC_VERSION_MAJOR;
286 _PUBLIC_ int talloc_version_minor(void)
288 return TALLOC_VERSION_MINOR;
291 static void (*talloc_log_fn)(const char *message);
293 _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
295 talloc_log_fn = log_fn;
298 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
299 static void talloc_log(const char *fmt, ...)
301 va_list ap;
302 char *message;
304 if (!talloc_log_fn) {
305 return;
308 va_start(ap, fmt);
309 message = talloc_vasprintf(NULL, fmt, ap);
310 va_end(ap);
312 talloc_log_fn(message);
313 talloc_free(message);
316 static void talloc_log_stderr(const char *message)
318 fprintf(stderr, "%s", message);
321 _PUBLIC_ void talloc_set_log_stderr(void)
323 talloc_set_log_fn(talloc_log_stderr);
326 static void (*talloc_abort_fn)(const char *reason);
328 _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
330 talloc_abort_fn = abort_fn;
333 static void talloc_abort(const char *reason)
335 talloc_log("%s\n", reason);
337 if (!talloc_abort_fn) {
338 TALLOC_ABORT(reason);
341 talloc_abort_fn(reason);
344 static void talloc_abort_magic(unsigned magic)
346 unsigned striped = magic - TALLOC_MAGIC_BASE;
347 unsigned major = (striped & 0xFFFFF000) >> 12;
348 unsigned minor = (striped & 0x00000FF0) >> 4;
349 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
350 magic, major, minor,
351 TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
352 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
355 static void talloc_abort_access_after_free(void)
357 talloc_abort("Bad talloc magic value - access after free");
360 static void talloc_abort_unknown_value(void)
362 talloc_abort("Bad talloc magic value - unknown value");
365 /* panic if we get a bad magic value */
366 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
368 const char *pp = (const char *)ptr;
369 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
370 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
371 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
372 talloc_abort_magic(tc->flags & (~0xF));
373 return NULL;
376 if (tc->flags & TALLOC_FLAG_FREE) {
377 talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
378 talloc_abort_access_after_free();
379 return NULL;
380 } else {
381 talloc_abort_unknown_value();
382 return NULL;
385 return tc;
388 /* hook into the front of the list */
389 #define _TLIST_ADD(list, p) \
390 do { \
391 if (!(list)) { \
392 (list) = (p); \
393 (p)->next = (p)->prev = NULL; \
394 } else { \
395 (list)->prev = (p); \
396 (p)->next = (list); \
397 (p)->prev = NULL; \
398 (list) = (p); \
400 } while (0)
402 /* remove an element from a list - element doesn't have to be in list. */
403 #define _TLIST_REMOVE(list, p) \
404 do { \
405 if ((p) == (list)) { \
406 (list) = (p)->next; \
407 if (list) (list)->prev = NULL; \
408 } else { \
409 if ((p)->prev) (p)->prev->next = (p)->next; \
410 if ((p)->next) (p)->next->prev = (p)->prev; \
412 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
413 } while (0)
417 return the parent chunk of a pointer
419 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
421 struct talloc_chunk *tc;
423 if (unlikely(ptr == NULL)) {
424 return NULL;
427 tc = talloc_chunk_from_ptr(ptr);
428 while (tc->prev) tc=tc->prev;
430 return tc->parent;
433 _PUBLIC_ void *talloc_parent(const void *ptr)
435 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
436 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
440 find parents name
442 _PUBLIC_ const char *talloc_parent_name(const void *ptr)
444 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
445 return tc? tc->name : NULL;
449 A pool carries an in-pool object count count in the first 16 bytes.
450 bytes. This is done to support talloc_steal() to a parent outside of the
451 pool. The count includes the pool itself, so a talloc_free() on a pool will
452 only destroy the pool if the count has dropped to zero. A talloc_free() of a
453 pool member will reduce the count, and eventually also call free(3) on the
454 pool memory.
456 The object count is not put into "struct talloc_chunk" because it is only
457 relevant for talloc pools and the alignment to 16 bytes would increase the
458 memory footprint of each talloc chunk by those 16 bytes.
461 struct talloc_pool_hdr {
462 void *end;
463 unsigned int object_count;
466 #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr))
468 static struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c)
470 return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE);
473 static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h)
475 return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE);
478 static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr)
480 struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
481 return (char *)tc + TC_HDR_SIZE + tc->size;
484 static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr)
486 return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end;
489 static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr)
491 return TC_PTR_FROM_CHUNK(talloc_chunk_from_pool(pool_hdr));
494 /* If tc is inside a pool, this gives the next neighbour. */
495 static void *tc_next_chunk(struct talloc_chunk *tc)
497 return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size);
500 /* Mark the whole remaining pool as not accessable */
501 static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr)
503 size_t flen = tc_pool_space_left(pool_hdr);
505 if (unlikely(talloc_fill.enabled)) {
506 memset(pool_hdr->end, talloc_fill.fill_value, flen);
509 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
510 VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen);
511 #endif
515 Allocate from a pool
518 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
519 size_t size, size_t prefix_len)
521 struct talloc_pool_hdr *pool_hdr = NULL;
522 size_t space_left;
523 struct talloc_chunk *result;
524 size_t chunk_size;
526 if (parent == NULL) {
527 return NULL;
530 if (parent->flags & TALLOC_FLAG_POOL) {
531 pool_hdr = talloc_pool_from_chunk(parent);
533 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
534 pool_hdr = parent->pool;
537 if (pool_hdr == NULL) {
538 return NULL;
541 space_left = tc_pool_space_left(pool_hdr);
544 * Align size to 16 bytes
546 chunk_size = TC_ALIGN16(size + prefix_len);
548 if (space_left < chunk_size) {
549 return NULL;
552 result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len);
554 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
555 VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size);
556 #endif
558 pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size);
560 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
561 result->pool = pool_hdr;
563 pool_hdr->object_count++;
565 return result;
569 Allocate a bit of memory as a child of an existing pointer
571 static inline void *__talloc_with_prefix(const void *context, size_t size,
572 size_t prefix_len)
574 struct talloc_chunk *tc = NULL;
575 struct talloc_memlimit *limit = NULL;
576 size_t total_len = TC_HDR_SIZE + size + prefix_len;
578 if (unlikely(context == NULL)) {
579 context = null_context;
582 if (unlikely(size >= MAX_TALLOC_SIZE)) {
583 return NULL;
586 if (unlikely(total_len < TC_HDR_SIZE)) {
587 return NULL;
590 if (context != NULL) {
591 struct talloc_chunk *ptc = talloc_chunk_from_ptr(context);
593 if (ptc->limit != NULL) {
594 limit = ptc->limit;
597 tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len);
600 if (tc == NULL) {
601 char *ptr;
604 * Only do the memlimit check/update on actual allocation.
606 if (!talloc_memlimit_check(limit, total_len)) {
607 errno = ENOMEM;
608 return NULL;
611 ptr = malloc(total_len);
612 if (unlikely(ptr == NULL)) {
613 return NULL;
615 tc = (struct talloc_chunk *)(ptr + prefix_len);
616 tc->flags = TALLOC_MAGIC;
617 tc->pool = NULL;
619 talloc_memlimit_grow(limit, total_len);
622 tc->limit = limit;
623 tc->size = size;
624 tc->destructor = NULL;
625 tc->child = NULL;
626 tc->name = NULL;
627 tc->refs = NULL;
629 if (likely(context)) {
630 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
632 if (parent->child) {
633 parent->child->parent = NULL;
634 tc->next = parent->child;
635 tc->next->prev = tc;
636 } else {
637 tc->next = NULL;
639 tc->parent = parent;
640 tc->prev = NULL;
641 parent->child = tc;
642 } else {
643 tc->next = tc->prev = tc->parent = NULL;
646 return TC_PTR_FROM_CHUNK(tc);
649 static inline void *__talloc(const void *context, size_t size)
651 return __talloc_with_prefix(context, size, 0);
655 * Create a talloc pool
658 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
660 struct talloc_chunk *tc;
661 struct talloc_pool_hdr *pool_hdr;
662 void *result;
664 result = __talloc_with_prefix(context, size, TP_HDR_SIZE);
666 if (unlikely(result == NULL)) {
667 return NULL;
670 tc = talloc_chunk_from_ptr(result);
671 pool_hdr = talloc_pool_from_chunk(tc);
673 if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
674 /* We don't handle this correctly, so fail. */
675 talloc_log("talloc: cannot allocate pool off another pool %s\n",
676 talloc_get_name(context));
677 talloc_free(result);
678 return NULL;
680 tc->flags |= TALLOC_FLAG_POOL;
682 pool_hdr->object_count = 1;
683 pool_hdr->end = result;
685 tc_invalidate_pool(pool_hdr);
687 return result;
691 setup a destructor to be called on free of a pointer
692 the destructor should return 0 on success, or -1 on failure.
693 if the destructor fails then the free is failed, and the memory can
694 be continued to be used
696 _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
698 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
699 tc->destructor = destructor;
703 increase the reference count on a piece of memory.
705 _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
707 if (unlikely(!talloc_reference(null_context, ptr))) {
708 return -1;
710 return 0;
714 helper for talloc_reference()
716 this is referenced by a function pointer and should not be inline
718 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
720 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
721 _TLIST_REMOVE(ptr_tc->refs, handle);
722 return 0;
726 more efficient way to add a name to a pointer - the name must point to a
727 true string constant
729 static inline void _talloc_set_name_const(const void *ptr, const char *name)
731 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
732 tc->name = name;
736 internal talloc_named_const()
738 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
740 void *ptr;
742 ptr = __talloc(context, size);
743 if (unlikely(ptr == NULL)) {
744 return NULL;
747 _talloc_set_name_const(ptr, name);
749 return ptr;
753 make a secondary reference to a pointer, hanging off the given context.
754 the pointer remains valid until both the original caller and this given
755 context are freed.
757 the major use for this is when two different structures need to reference the
758 same underlying data, and you want to be able to free the two instances separately,
759 and in either order
761 _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
763 struct talloc_chunk *tc;
764 struct talloc_reference_handle *handle;
765 if (unlikely(ptr == NULL)) return NULL;
767 tc = talloc_chunk_from_ptr(ptr);
768 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
769 sizeof(struct talloc_reference_handle),
770 TALLOC_MAGIC_REFERENCE);
771 if (unlikely(handle == NULL)) return NULL;
773 /* note that we hang the destructor off the handle, not the
774 main context as that allows the caller to still setup their
775 own destructor on the context if they want to */
776 talloc_set_destructor(handle, talloc_reference_destructor);
777 handle->ptr = discard_const_p(void, ptr);
778 handle->location = location;
779 _TLIST_ADD(tc->refs, handle);
780 return handle->ptr;
783 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
785 static inline void _talloc_free_poolmem(struct talloc_chunk *tc,
786 const char *location)
788 struct talloc_pool_hdr *pool;
789 struct talloc_chunk *pool_tc;
790 void *next_tc;
792 pool = tc->pool;
793 pool_tc = talloc_chunk_from_pool(pool);
794 next_tc = tc_next_chunk(tc);
796 tc->flags |= TALLOC_FLAG_FREE;
798 /* we mark the freed memory with where we called the free
799 * from. This means on a double free error we can report where
800 * the first free came from
802 tc->name = location;
804 TC_INVALIDATE_FULL_CHUNK(tc);
806 if (unlikely(pool->object_count == 0)) {
807 talloc_abort("Pool object count zero!");
808 return;
811 pool->object_count--;
813 if (unlikely(pool->object_count == 1
814 && !(pool_tc->flags & TALLOC_FLAG_FREE))) {
816 * if there is just one object left in the pool
817 * and pool->flags does not have TALLOC_FLAG_FREE,
818 * it means this is the pool itself and
819 * the rest is available for new objects
820 * again.
822 pool->end = tc_pool_first_chunk(pool);
823 tc_invalidate_pool(pool);
824 return;
827 if (unlikely(pool->object_count == 0)) {
829 * we mark the freed memory with where we called the free
830 * from. This means on a double free error we can report where
831 * the first free came from
833 pool_tc->name = location;
835 talloc_memlimit_update_on_free(pool_tc);
837 TC_INVALIDATE_FULL_CHUNK(pool_tc);
838 free(pool);
839 return;
842 if (pool->end == next_tc) {
844 * if pool->pool still points to end of
845 * 'tc' (which is stored in the 'next_tc' variable),
846 * we can reclaim the memory of 'tc'.
848 pool->end = tc;
849 return;
853 * Do nothing. The memory is just "wasted", waiting for the pool
854 * itself to be freed.
858 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
859 void *ptr,
860 const char *location);
863 internal talloc_free call
865 static inline int _talloc_free_internal(void *ptr, const char *location)
867 struct talloc_chunk *tc;
869 if (unlikely(ptr == NULL)) {
870 return -1;
873 /* possibly initialised the talloc fill value */
874 if (unlikely(!talloc_fill.initialised)) {
875 const char *fill = getenv(TALLOC_FILL_ENV);
876 if (fill != NULL) {
877 talloc_fill.enabled = true;
878 talloc_fill.fill_value = strtoul(fill, NULL, 0);
880 talloc_fill.initialised = true;
883 tc = talloc_chunk_from_ptr(ptr);
885 if (unlikely(tc->refs)) {
886 int is_child;
887 /* check if this is a reference from a child or
888 * grandchild back to it's parent or grandparent
890 * in that case we need to remove the reference and
891 * call another instance of talloc_free() on the current
892 * pointer.
894 is_child = talloc_is_parent(tc->refs, ptr);
895 _talloc_free_internal(tc->refs, location);
896 if (is_child) {
897 return _talloc_free_internal(ptr, location);
899 return -1;
902 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
903 /* we have a free loop - stop looping */
904 return 0;
907 if (unlikely(tc->destructor)) {
908 talloc_destructor_t d = tc->destructor;
909 if (d == (talloc_destructor_t)-1) {
910 return -1;
912 tc->destructor = (talloc_destructor_t)-1;
913 if (d(ptr) == -1) {
914 tc->destructor = d;
915 return -1;
917 tc->destructor = NULL;
920 if (tc->parent) {
921 _TLIST_REMOVE(tc->parent->child, tc);
922 if (tc->parent->child) {
923 tc->parent->child->parent = tc->parent;
925 } else {
926 if (tc->prev) tc->prev->next = tc->next;
927 if (tc->next) tc->next->prev = tc->prev;
928 tc->prev = tc->next = NULL;
931 tc->flags |= TALLOC_FLAG_LOOP;
933 _talloc_free_children_internal(tc, ptr, location);
935 tc->flags |= TALLOC_FLAG_FREE;
937 /* we mark the freed memory with where we called the free
938 * from. This means on a double free error we can report where
939 * the first free came from
941 tc->name = location;
943 if (tc->flags & TALLOC_FLAG_POOL) {
944 struct talloc_pool_hdr *pool;
946 pool = talloc_pool_from_chunk(tc);
948 if (unlikely(pool->object_count == 0)) {
949 talloc_abort("Pool object count zero!");
950 return 0;
953 pool->object_count--;
955 if (likely(pool->object_count != 0)) {
956 return 0;
960 * This call takes into account the
961 * prefix TP_HDR_SIZE allocated before
962 * the pool talloc_chunk.
964 talloc_memlimit_update_on_free(tc);
966 TC_INVALIDATE_FULL_CHUNK(tc);
967 free(pool);
968 return 0;
971 if (tc->flags & TALLOC_FLAG_POOLMEM) {
972 _talloc_free_poolmem(tc, location);
973 return 0;
976 talloc_memlimit_update_on_free(tc);
978 TC_INVALIDATE_FULL_CHUNK(tc);
979 free(tc);
980 return 0;
983 static size_t _talloc_total_limit_size(const void *ptr,
984 struct talloc_memlimit *old_limit,
985 struct talloc_memlimit *new_limit);
988 move a lump of memory from one talloc context to another return the
989 ptr on success, or NULL if it could not be transferred.
990 passing NULL as ptr will always return NULL with no side effects.
992 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
994 struct talloc_chunk *tc, *new_tc;
995 size_t ctx_size = 0;
997 if (unlikely(!ptr)) {
998 return NULL;
1001 if (unlikely(new_ctx == NULL)) {
1002 new_ctx = null_context;
1005 tc = talloc_chunk_from_ptr(ptr);
1007 if (tc->limit != NULL) {
1009 ctx_size = _talloc_total_limit_size(ptr, NULL, NULL);
1011 /* Decrement the memory limit from the source .. */
1012 talloc_memlimit_shrink(tc->limit->upper, ctx_size);
1014 if (tc->limit->parent == tc) {
1015 tc->limit->upper = NULL;
1016 } else {
1017 tc->limit = NULL;
1021 if (unlikely(new_ctx == NULL)) {
1022 if (tc->parent) {
1023 _TLIST_REMOVE(tc->parent->child, tc);
1024 if (tc->parent->child) {
1025 tc->parent->child->parent = tc->parent;
1027 } else {
1028 if (tc->prev) tc->prev->next = tc->next;
1029 if (tc->next) tc->next->prev = tc->prev;
1032 tc->parent = tc->next = tc->prev = NULL;
1033 return discard_const_p(void, ptr);
1036 new_tc = talloc_chunk_from_ptr(new_ctx);
1038 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
1039 return discard_const_p(void, ptr);
1042 if (tc->parent) {
1043 _TLIST_REMOVE(tc->parent->child, tc);
1044 if (tc->parent->child) {
1045 tc->parent->child->parent = tc->parent;
1047 } else {
1048 if (tc->prev) tc->prev->next = tc->next;
1049 if (tc->next) tc->next->prev = tc->prev;
1050 tc->prev = tc->next = NULL;
1053 tc->parent = new_tc;
1054 if (new_tc->child) new_tc->child->parent = NULL;
1055 _TLIST_ADD(new_tc->child, tc);
1057 if (tc->limit || new_tc->limit) {
1058 ctx_size = _talloc_total_limit_size(ptr, tc->limit,
1059 new_tc->limit);
1060 /* .. and increment it in the destination. */
1061 if (new_tc->limit) {
1062 talloc_memlimit_grow(new_tc->limit, ctx_size);
1066 return discard_const_p(void, ptr);
1070 move a lump of memory from one talloc context to another return the
1071 ptr on success, or NULL if it could not be transferred.
1072 passing NULL as ptr will always return NULL with no side effects.
1074 _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
1076 struct talloc_chunk *tc;
1078 if (unlikely(ptr == NULL)) {
1079 return NULL;
1082 tc = talloc_chunk_from_ptr(ptr);
1084 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
1085 struct talloc_reference_handle *h;
1087 talloc_log("WARNING: talloc_steal with references at %s\n",
1088 location);
1090 for (h=tc->refs; h; h=h->next) {
1091 talloc_log("\treference at %s\n",
1092 h->location);
1096 #if 0
1097 /* this test is probably too expensive to have on in the
1098 normal build, but it useful for debugging */
1099 if (talloc_is_parent(new_ctx, ptr)) {
1100 talloc_log("WARNING: stealing into talloc child at %s\n", location);
1102 #endif
1104 return _talloc_steal_internal(new_ctx, ptr);
1108 this is like a talloc_steal(), but you must supply the old
1109 parent. This resolves the ambiguity in a talloc_steal() which is
1110 called on a context that has more than one parent (via references)
1112 The old parent can be either a reference or a parent
1114 _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
1116 struct talloc_chunk *tc;
1117 struct talloc_reference_handle *h;
1119 if (unlikely(ptr == NULL)) {
1120 return NULL;
1123 if (old_parent == talloc_parent(ptr)) {
1124 return _talloc_steal_internal(new_parent, ptr);
1127 tc = talloc_chunk_from_ptr(ptr);
1128 for (h=tc->refs;h;h=h->next) {
1129 if (talloc_parent(h) == old_parent) {
1130 if (_talloc_steal_internal(new_parent, h) != h) {
1131 return NULL;
1133 return discard_const_p(void, ptr);
1137 /* it wasn't a parent */
1138 return NULL;
1142 remove a secondary reference to a pointer. This undo's what
1143 talloc_reference() has done. The context and pointer arguments
1144 must match those given to a talloc_reference()
1146 static inline int talloc_unreference(const void *context, const void *ptr)
1148 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1149 struct talloc_reference_handle *h;
1151 if (unlikely(context == NULL)) {
1152 context = null_context;
1155 for (h=tc->refs;h;h=h->next) {
1156 struct talloc_chunk *p = talloc_parent_chunk(h);
1157 if (p == NULL) {
1158 if (context == NULL) break;
1159 } else if (TC_PTR_FROM_CHUNK(p) == context) {
1160 break;
1163 if (h == NULL) {
1164 return -1;
1167 return _talloc_free_internal(h, __location__);
1171 remove a specific parent context from a pointer. This is a more
1172 controlled variant of talloc_free()
1174 _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
1176 struct talloc_chunk *tc_p, *new_p, *tc_c;
1177 void *new_parent;
1179 if (ptr == NULL) {
1180 return -1;
1183 if (context == NULL) {
1184 context = null_context;
1187 if (talloc_unreference(context, ptr) == 0) {
1188 return 0;
1191 if (context != NULL) {
1192 tc_c = talloc_chunk_from_ptr(context);
1193 } else {
1194 tc_c = NULL;
1196 if (tc_c != talloc_parent_chunk(ptr)) {
1197 return -1;
1200 tc_p = talloc_chunk_from_ptr(ptr);
1202 if (tc_p->refs == NULL) {
1203 return _talloc_free_internal(ptr, __location__);
1206 new_p = talloc_parent_chunk(tc_p->refs);
1207 if (new_p) {
1208 new_parent = TC_PTR_FROM_CHUNK(new_p);
1209 } else {
1210 new_parent = NULL;
1213 if (talloc_unreference(new_parent, ptr) != 0) {
1214 return -1;
1217 _talloc_steal_internal(new_parent, ptr);
1219 return 0;
1223 add a name to an existing pointer - va_list version
1225 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
1227 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
1229 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1230 tc->name = talloc_vasprintf(ptr, fmt, ap);
1231 if (likely(tc->name)) {
1232 _talloc_set_name_const(tc->name, ".name");
1234 return tc->name;
1238 add a name to an existing pointer
1240 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
1242 const char *name;
1243 va_list ap;
1244 va_start(ap, fmt);
1245 name = talloc_set_name_v(ptr, fmt, ap);
1246 va_end(ap);
1247 return name;
1252 create a named talloc pointer. Any talloc pointer can be named, and
1253 talloc_named() operates just like talloc() except that it allows you
1254 to name the pointer.
1256 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
1258 va_list ap;
1259 void *ptr;
1260 const char *name;
1262 ptr = __talloc(context, size);
1263 if (unlikely(ptr == NULL)) return NULL;
1265 va_start(ap, fmt);
1266 name = talloc_set_name_v(ptr, fmt, ap);
1267 va_end(ap);
1269 if (unlikely(name == NULL)) {
1270 _talloc_free_internal(ptr, __location__);
1271 return NULL;
1274 return ptr;
1278 return the name of a talloc ptr, or "UNNAMED"
1280 _PUBLIC_ const char *talloc_get_name(const void *ptr)
1282 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1283 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
1284 return ".reference";
1286 if (likely(tc->name)) {
1287 return tc->name;
1289 return "UNNAMED";
1294 check if a pointer has the given name. If it does, return the pointer,
1295 otherwise return NULL
1297 _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1299 const char *pname;
1300 if (unlikely(ptr == NULL)) return NULL;
1301 pname = talloc_get_name(ptr);
1302 if (likely(pname == name || strcmp(pname, name) == 0)) {
1303 return discard_const_p(void, ptr);
1305 return NULL;
1308 static void talloc_abort_type_mismatch(const char *location,
1309 const char *name,
1310 const char *expected)
1312 const char *reason;
1314 reason = talloc_asprintf(NULL,
1315 "%s: Type mismatch: name[%s] expected[%s]",
1316 location,
1317 name?name:"NULL",
1318 expected);
1319 if (!reason) {
1320 reason = "Type mismatch";
1323 talloc_abort(reason);
1326 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1328 const char *pname;
1330 if (unlikely(ptr == NULL)) {
1331 talloc_abort_type_mismatch(location, NULL, name);
1332 return NULL;
1335 pname = talloc_get_name(ptr);
1336 if (likely(pname == name || strcmp(pname, name) == 0)) {
1337 return discard_const_p(void, ptr);
1340 talloc_abort_type_mismatch(location, pname, name);
1341 return NULL;
1345 this is for compatibility with older versions of talloc
1347 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1349 va_list ap;
1350 void *ptr;
1351 const char *name;
1353 ptr = __talloc(NULL, 0);
1354 if (unlikely(ptr == NULL)) return NULL;
1356 va_start(ap, fmt);
1357 name = talloc_set_name_v(ptr, fmt, ap);
1358 va_end(ap);
1360 if (unlikely(name == NULL)) {
1361 _talloc_free_internal(ptr, __location__);
1362 return NULL;
1365 return ptr;
1368 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
1369 void *ptr,
1370 const char *location)
1372 while (tc->child) {
1373 /* we need to work out who will own an abandoned child
1374 if it cannot be freed. In priority order, the first
1375 choice is owner of any remaining reference to this
1376 pointer, the second choice is our parent, and the
1377 final choice is the null context. */
1378 void *child = TC_PTR_FROM_CHUNK(tc->child);
1379 const void *new_parent = null_context;
1380 if (unlikely(tc->child->refs)) {
1381 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1382 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1384 if (unlikely(_talloc_free_internal(child, location) == -1)) {
1385 if (new_parent == null_context) {
1386 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1387 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1389 _talloc_steal_internal(new_parent, child);
1395 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1396 should probably not be used in new code. It's in here to keep the talloc
1397 code consistent across Samba 3 and 4.
1399 _PUBLIC_ void talloc_free_children(void *ptr)
1401 struct talloc_chunk *tc_name = NULL;
1402 struct talloc_chunk *tc;
1404 if (unlikely(ptr == NULL)) {
1405 return;
1408 tc = talloc_chunk_from_ptr(ptr);
1410 /* we do not want to free the context name if it is a child .. */
1411 if (likely(tc->child)) {
1412 for (tc_name = tc->child; tc_name; tc_name = tc_name->next) {
1413 if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break;
1415 if (tc_name) {
1416 _TLIST_REMOVE(tc->child, tc_name);
1417 if (tc->child) {
1418 tc->child->parent = tc;
1423 _talloc_free_children_internal(tc, ptr, __location__);
1425 /* .. so we put it back after all other children have been freed */
1426 if (tc_name) {
1427 if (tc->child) {
1428 tc->child->parent = NULL;
1430 tc_name->parent = tc;
1431 _TLIST_ADD(tc->child, tc_name);
1436 Allocate a bit of memory as a child of an existing pointer
1438 _PUBLIC_ void *_talloc(const void *context, size_t size)
1440 return __talloc(context, size);
1444 externally callable talloc_set_name_const()
1446 _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1448 _talloc_set_name_const(ptr, name);
1452 create a named talloc pointer. Any talloc pointer can be named, and
1453 talloc_named() operates just like talloc() except that it allows you
1454 to name the pointer.
1456 _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1458 return _talloc_named_const(context, size, name);
1462 free a talloc pointer. This also frees all child pointers of this
1463 pointer recursively
1465 return 0 if the memory is actually freed, otherwise -1. The memory
1466 will not be freed if the ref_count is > 1 or the destructor (if
1467 any) returns non-zero
1469 _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1471 struct talloc_chunk *tc;
1473 if (unlikely(ptr == NULL)) {
1474 return -1;
1477 tc = talloc_chunk_from_ptr(ptr);
1479 if (unlikely(tc->refs != NULL)) {
1480 struct talloc_reference_handle *h;
1482 if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1483 /* in this case we do know which parent should
1484 get this pointer, as there is really only
1485 one parent */
1486 return talloc_unlink(null_context, ptr);
1489 talloc_log("ERROR: talloc_free with references at %s\n",
1490 location);
1492 for (h=tc->refs; h; h=h->next) {
1493 talloc_log("\treference at %s\n",
1494 h->location);
1496 return -1;
1499 return _talloc_free_internal(ptr, location);
1505 A talloc version of realloc. The context argument is only used if
1506 ptr is NULL
1508 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1510 struct talloc_chunk *tc;
1511 void *new_ptr;
1512 bool malloced = false;
1513 struct talloc_pool_hdr *pool_hdr = NULL;
1514 size_t old_size = 0;
1515 size_t new_size = 0;
1517 /* size zero is equivalent to free() */
1518 if (unlikely(size == 0)) {
1519 talloc_unlink(context, ptr);
1520 return NULL;
1523 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1524 return NULL;
1527 /* realloc(NULL) is equivalent to malloc() */
1528 if (ptr == NULL) {
1529 return _talloc_named_const(context, size, name);
1532 tc = talloc_chunk_from_ptr(ptr);
1534 /* don't allow realloc on referenced pointers */
1535 if (unlikely(tc->refs)) {
1536 return NULL;
1539 /* don't let anybody try to realloc a talloc_pool */
1540 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1541 return NULL;
1544 if (tc->limit && (size > tc->size)) {
1545 if (!talloc_memlimit_check(tc->limit, (size - tc->size))) {
1546 errno = ENOMEM;
1547 return NULL;
1551 /* handle realloc inside a talloc_pool */
1552 if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
1553 pool_hdr = tc->pool;
1556 #if (ALWAYS_REALLOC == 0)
1557 /* don't shrink if we have less than 1k to gain */
1558 if (size < tc->size && tc->limit == NULL) {
1559 if (pool_hdr) {
1560 void *next_tc = tc_next_chunk(tc);
1561 TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1562 tc->size = size;
1563 if (next_tc == pool_hdr->end) {
1564 /* note: tc->size has changed, so this works */
1565 pool_hdr->end = tc_next_chunk(tc);
1567 return ptr;
1568 } else if ((tc->size - size) < 1024) {
1570 * if we call TC_INVALIDATE_SHRINK_CHUNK() here
1571 * we would need to call TC_UNDEFINE_GROW_CHUNK()
1572 * after each realloc call, which slows down
1573 * testing a lot :-(.
1575 * That is why we only mark memory as undefined here.
1577 TC_UNDEFINE_SHRINK_CHUNK(tc, size);
1579 /* do not shrink if we have less than 1k to gain */
1580 tc->size = size;
1581 return ptr;
1583 } else if (tc->size == size) {
1585 * do not change the pointer if it is exactly
1586 * the same size.
1588 return ptr;
1590 #endif
1592 /* by resetting magic we catch users of the old memory */
1593 tc->flags |= TALLOC_FLAG_FREE;
1595 #if ALWAYS_REALLOC
1596 if (pool_hdr) {
1597 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1598 pool_hdr->object_count--;
1600 if (new_ptr == NULL) {
1601 new_ptr = malloc(TC_HDR_SIZE+size);
1602 malloced = true;
1603 new_size = size;
1606 if (new_ptr) {
1607 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1608 TC_INVALIDATE_FULL_CHUNK(tc);
1610 } else {
1611 /* We're doing malloc then free here, so record the difference. */
1612 old_size = tc->size;
1613 new_size = size;
1614 new_ptr = malloc(size + TC_HDR_SIZE);
1615 if (new_ptr) {
1616 memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1617 free(tc);
1620 #else
1621 if (pool_hdr) {
1622 struct talloc_chunk *pool_tc;
1623 void *next_tc = tc_next_chunk(tc);
1624 size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size);
1625 size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
1626 size_t space_needed;
1627 size_t space_left;
1628 unsigned int chunk_count = pool_hdr->object_count;
1630 pool_tc = talloc_chunk_from_pool(pool_hdr);
1631 if (!(pool_tc->flags & TALLOC_FLAG_FREE)) {
1632 chunk_count -= 1;
1635 if (chunk_count == 1) {
1637 * optimize for the case where 'tc' is the only
1638 * chunk in the pool.
1640 char *start = tc_pool_first_chunk(pool_hdr);
1641 space_needed = new_chunk_size;
1642 space_left = (char *)tc_pool_end(pool_hdr) - start;
1644 if (space_left >= space_needed) {
1645 size_t old_used = TC_HDR_SIZE + tc->size;
1646 size_t new_used = TC_HDR_SIZE + size;
1647 new_ptr = start;
1649 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
1652 * The area from
1653 * start -> tc may have
1654 * been freed and thus been marked as
1655 * VALGRIND_MEM_NOACCESS. Set it to
1656 * VALGRIND_MEM_UNDEFINED so we can
1657 * copy into it without valgrind errors.
1658 * We can't just mark
1659 * new_ptr -> new_ptr + old_used
1660 * as this may overlap on top of tc,
1661 * (which is why we use memmove, not
1662 * memcpy below) hence the MIN.
1664 size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used);
1665 VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len);
1667 #endif
1669 memmove(new_ptr, tc, old_used);
1671 tc = (struct talloc_chunk *)new_ptr;
1672 TC_UNDEFINE_GROW_CHUNK(tc, size);
1675 * first we do not align the pool pointer
1676 * because we want to invalidate the padding
1677 * too.
1679 pool_hdr->end = new_used + (char *)new_ptr;
1680 tc_invalidate_pool(pool_hdr);
1682 /* now the aligned pointer */
1683 pool_hdr->end = new_chunk_size + (char *)new_ptr;
1684 goto got_new_ptr;
1687 next_tc = NULL;
1690 if (new_chunk_size == old_chunk_size) {
1691 TC_UNDEFINE_GROW_CHUNK(tc, size);
1692 tc->flags &= ~TALLOC_FLAG_FREE;
1693 tc->size = size;
1694 return ptr;
1697 if (next_tc == pool_hdr->end) {
1699 * optimize for the case where 'tc' is the last
1700 * chunk in the pool.
1702 space_needed = new_chunk_size - old_chunk_size;
1703 space_left = tc_pool_space_left(pool_hdr);
1705 if (space_left >= space_needed) {
1706 TC_UNDEFINE_GROW_CHUNK(tc, size);
1707 tc->flags &= ~TALLOC_FLAG_FREE;
1708 tc->size = size;
1709 pool_hdr->end = tc_next_chunk(tc);
1710 return ptr;
1714 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1716 if (new_ptr == NULL) {
1717 new_ptr = malloc(TC_HDR_SIZE+size);
1718 malloced = true;
1719 new_size = size;
1722 if (new_ptr) {
1723 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1725 _talloc_free_poolmem(tc, __location__ "_talloc_realloc");
1728 else {
1729 /* We're doing realloc here, so record the difference. */
1730 old_size = tc->size;
1731 new_size = size;
1732 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1734 got_new_ptr:
1735 #endif
1736 if (unlikely(!new_ptr)) {
1737 tc->flags &= ~TALLOC_FLAG_FREE;
1738 return NULL;
1741 tc = (struct talloc_chunk *)new_ptr;
1742 tc->flags &= ~TALLOC_FLAG_FREE;
1743 if (malloced) {
1744 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1746 if (tc->parent) {
1747 tc->parent->child = tc;
1749 if (tc->child) {
1750 tc->child->parent = tc;
1753 if (tc->prev) {
1754 tc->prev->next = tc;
1756 if (tc->next) {
1757 tc->next->prev = tc;
1760 if (new_size > old_size) {
1761 talloc_memlimit_grow(tc->limit, new_size - old_size);
1762 } else if (new_size < old_size) {
1763 talloc_memlimit_shrink(tc->limit, old_size - new_size);
1766 tc->size = size;
1767 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1769 return TC_PTR_FROM_CHUNK(tc);
1773 a wrapper around talloc_steal() for situations where you are moving a pointer
1774 between two structures, and want the old pointer to be set to NULL
1776 _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
1778 const void **pptr = discard_const_p(const void *,_pptr);
1779 void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1780 (*pptr) = NULL;
1781 return ret;
1784 enum talloc_mem_count_type {
1785 TOTAL_MEM_SIZE,
1786 TOTAL_MEM_BLOCKS,
1787 TOTAL_MEM_LIMIT,
1790 static size_t _talloc_total_mem_internal(const void *ptr,
1791 enum talloc_mem_count_type type,
1792 struct talloc_memlimit *old_limit,
1793 struct talloc_memlimit *new_limit)
1795 size_t total = 0;
1796 struct talloc_chunk *c, *tc;
1798 if (ptr == NULL) {
1799 ptr = null_context;
1801 if (ptr == NULL) {
1802 return 0;
1805 tc = talloc_chunk_from_ptr(ptr);
1807 if (old_limit || new_limit) {
1808 if (tc->limit && tc->limit->upper == old_limit) {
1809 tc->limit->upper = new_limit;
1813 /* optimize in the memlimits case */
1814 if (type == TOTAL_MEM_LIMIT &&
1815 tc->limit != NULL &&
1816 tc->limit != old_limit &&
1817 tc->limit->parent == tc) {
1818 return tc->limit->cur_size;
1821 if (tc->flags & TALLOC_FLAG_LOOP) {
1822 return 0;
1825 tc->flags |= TALLOC_FLAG_LOOP;
1827 if (old_limit || new_limit) {
1828 if (old_limit == tc->limit) {
1829 tc->limit = new_limit;
1833 switch (type) {
1834 case TOTAL_MEM_SIZE:
1835 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1836 total = tc->size;
1838 break;
1839 case TOTAL_MEM_BLOCKS:
1840 total++;
1841 break;
1842 case TOTAL_MEM_LIMIT:
1843 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1845 * Don't count memory allocated from a pool
1846 * when calculating limits. Only count the
1847 * pool itself.
1849 if (!(tc->flags & TALLOC_FLAG_POOLMEM)) {
1850 total = tc->size + TC_HDR_SIZE;
1852 * If this is a pool, remember to
1853 * add the prefix length.
1855 if (tc->flags & TALLOC_FLAG_POOL) {
1856 total += TP_HDR_SIZE;
1860 break;
1862 for (c = tc->child; c; c = c->next) {
1863 total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type,
1864 old_limit, new_limit);
1867 tc->flags &= ~TALLOC_FLAG_LOOP;
1869 return total;
1873 return the total size of a talloc pool (subtree)
1875 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1877 return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL);
1881 return the total number of blocks in a talloc pool (subtree)
1883 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1885 return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL);
1889 return the number of external references to a pointer
1891 _PUBLIC_ size_t talloc_reference_count(const void *ptr)
1893 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1894 struct talloc_reference_handle *h;
1895 size_t ret = 0;
1897 for (h=tc->refs;h;h=h->next) {
1898 ret++;
1900 return ret;
1904 report on memory usage by all children of a pointer, giving a full tree view
1906 _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1907 void (*callback)(const void *ptr,
1908 int depth, int max_depth,
1909 int is_ref,
1910 void *private_data),
1911 void *private_data)
1913 struct talloc_chunk *c, *tc;
1915 if (ptr == NULL) {
1916 ptr = null_context;
1918 if (ptr == NULL) return;
1920 tc = talloc_chunk_from_ptr(ptr);
1922 if (tc->flags & TALLOC_FLAG_LOOP) {
1923 return;
1926 callback(ptr, depth, max_depth, 0, private_data);
1928 if (max_depth >= 0 && depth >= max_depth) {
1929 return;
1932 tc->flags |= TALLOC_FLAG_LOOP;
1933 for (c=tc->child;c;c=c->next) {
1934 if (c->name == TALLOC_MAGIC_REFERENCE) {
1935 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1936 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1937 } else {
1938 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1941 tc->flags &= ~TALLOC_FLAG_LOOP;
1944 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1946 const char *name = talloc_get_name(ptr);
1947 struct talloc_chunk *tc;
1948 FILE *f = (FILE *)_f;
1950 if (is_ref) {
1951 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1952 return;
1955 tc = talloc_chunk_from_ptr(ptr);
1956 if (tc->limit && tc->limit->parent == tc) {
1957 fprintf(f, "%*s%-30s is a memlimit context"
1958 " (max_size = %lu bytes, cur_size = %lu bytes)\n",
1959 depth*4, "",
1960 name,
1961 (unsigned long)tc->limit->max_size,
1962 (unsigned long)tc->limit->cur_size);
1965 if (depth == 0) {
1966 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1967 (max_depth < 0 ? "full " :""), name,
1968 (unsigned long)talloc_total_size(ptr),
1969 (unsigned long)talloc_total_blocks(ptr));
1970 return;
1973 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1974 depth*4, "",
1975 name,
1976 (unsigned long)talloc_total_size(ptr),
1977 (unsigned long)talloc_total_blocks(ptr),
1978 (int)talloc_reference_count(ptr), ptr);
1980 #if 0
1981 fprintf(f, "content: ");
1982 if (talloc_total_size(ptr)) {
1983 int tot = talloc_total_size(ptr);
1984 int i;
1986 for (i = 0; i < tot; i++) {
1987 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1988 fprintf(f, "%c", ((char *)ptr)[i]);
1989 } else {
1990 fprintf(f, "~%02x", ((char *)ptr)[i]);
1994 fprintf(f, "\n");
1995 #endif
1999 report on memory usage by all children of a pointer, giving a full tree view
2001 _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
2003 if (f) {
2004 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
2005 fflush(f);
2010 report on memory usage by all children of a pointer, giving a full tree view
2012 _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
2014 talloc_report_depth_file(ptr, 0, -1, f);
2018 report on memory usage by all children of a pointer
2020 _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
2022 talloc_report_depth_file(ptr, 0, 1, f);
2026 report on any memory hanging off the null context
2028 static void talloc_report_null(void)
2030 if (talloc_total_size(null_context) != 0) {
2031 talloc_report(null_context, stderr);
2036 report on any memory hanging off the null context
2038 static void talloc_report_null_full(void)
2040 if (talloc_total_size(null_context) != 0) {
2041 talloc_report_full(null_context, stderr);
2046 enable tracking of the NULL context
2048 _PUBLIC_ void talloc_enable_null_tracking(void)
2050 if (null_context == NULL) {
2051 null_context = _talloc_named_const(NULL, 0, "null_context");
2052 if (autofree_context != NULL) {
2053 talloc_reparent(NULL, null_context, autofree_context);
2059 enable tracking of the NULL context, not moving the autofree context
2060 into the NULL context. This is needed for the talloc testsuite
2062 _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
2064 if (null_context == NULL) {
2065 null_context = _talloc_named_const(NULL, 0, "null_context");
2070 disable tracking of the NULL context
2072 _PUBLIC_ void talloc_disable_null_tracking(void)
2074 if (null_context != NULL) {
2075 /* we have to move any children onto the real NULL
2076 context */
2077 struct talloc_chunk *tc, *tc2;
2078 tc = talloc_chunk_from_ptr(null_context);
2079 for (tc2 = tc->child; tc2; tc2=tc2->next) {
2080 if (tc2->parent == tc) tc2->parent = NULL;
2081 if (tc2->prev == tc) tc2->prev = NULL;
2083 for (tc2 = tc->next; tc2; tc2=tc2->next) {
2084 if (tc2->parent == tc) tc2->parent = NULL;
2085 if (tc2->prev == tc) tc2->prev = NULL;
2087 tc->child = NULL;
2088 tc->next = NULL;
2090 talloc_free(null_context);
2091 null_context = NULL;
2095 enable leak reporting on exit
2097 _PUBLIC_ void talloc_enable_leak_report(void)
2099 talloc_enable_null_tracking();
2100 atexit(talloc_report_null);
2104 enable full leak reporting on exit
2106 _PUBLIC_ void talloc_enable_leak_report_full(void)
2108 talloc_enable_null_tracking();
2109 atexit(talloc_report_null_full);
2113 talloc and zero memory.
2115 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
2117 void *p = _talloc_named_const(ctx, size, name);
2119 if (p) {
2120 memset(p, '\0', size);
2123 return p;
2127 memdup with a talloc.
2129 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
2131 void *newp = _talloc_named_const(t, size, name);
2133 if (likely(newp)) {
2134 memcpy(newp, p, size);
2137 return newp;
2140 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
2142 char *ret;
2144 ret = (char *)__talloc(t, len + 1);
2145 if (unlikely(!ret)) return NULL;
2147 memcpy(ret, p, len);
2148 ret[len] = 0;
2150 _talloc_set_name_const(ret, ret);
2151 return ret;
2155 strdup with a talloc
2157 _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
2159 if (unlikely(!p)) return NULL;
2160 return __talloc_strlendup(t, p, strlen(p));
2164 strndup with a talloc
2166 _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
2168 if (unlikely(!p)) return NULL;
2169 return __talloc_strlendup(t, p, strnlen(p, n));
2172 static inline char *__talloc_strlendup_append(char *s, size_t slen,
2173 const char *a, size_t alen)
2175 char *ret;
2177 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
2178 if (unlikely(!ret)) return NULL;
2180 /* append the string and the trailing \0 */
2181 memcpy(&ret[slen], a, alen);
2182 ret[slen+alen] = 0;
2184 _talloc_set_name_const(ret, ret);
2185 return ret;
2189 * Appends at the end of the string.
2191 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
2193 if (unlikely(!s)) {
2194 return talloc_strdup(NULL, a);
2197 if (unlikely(!a)) {
2198 return s;
2201 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
2205 * Appends at the end of the talloc'ed buffer,
2206 * not the end of the string.
2208 _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
2210 size_t slen;
2212 if (unlikely(!s)) {
2213 return talloc_strdup(NULL, a);
2216 if (unlikely(!a)) {
2217 return s;
2220 slen = talloc_get_size(s);
2221 if (likely(slen > 0)) {
2222 slen--;
2225 return __talloc_strlendup_append(s, slen, a, strlen(a));
2229 * Appends at the end of the string.
2231 _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
2233 if (unlikely(!s)) {
2234 return talloc_strndup(NULL, a, n);
2237 if (unlikely(!a)) {
2238 return s;
2241 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
2245 * Appends at the end of the talloc'ed buffer,
2246 * not the end of the string.
2248 _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
2250 size_t slen;
2252 if (unlikely(!s)) {
2253 return talloc_strndup(NULL, a, n);
2256 if (unlikely(!a)) {
2257 return s;
2260 slen = talloc_get_size(s);
2261 if (likely(slen > 0)) {
2262 slen--;
2265 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
2268 #ifndef HAVE_VA_COPY
2269 #ifdef HAVE___VA_COPY
2270 #define va_copy(dest, src) __va_copy(dest, src)
2271 #else
2272 #define va_copy(dest, src) (dest) = (src)
2273 #endif
2274 #endif
2276 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
2278 int len;
2279 char *ret;
2280 va_list ap2;
2281 char c;
2283 /* this call looks strange, but it makes it work on older solaris boxes */
2284 va_copy(ap2, ap);
2285 len = vsnprintf(&c, 1, fmt, ap2);
2286 va_end(ap2);
2287 if (unlikely(len < 0)) {
2288 return NULL;
2291 ret = (char *)__talloc(t, len+1);
2292 if (unlikely(!ret)) return NULL;
2294 va_copy(ap2, ap);
2295 vsnprintf(ret, len+1, fmt, ap2);
2296 va_end(ap2);
2298 _talloc_set_name_const(ret, ret);
2299 return ret;
2304 Perform string formatting, and return a pointer to newly allocated
2305 memory holding the result, inside a memory pool.
2307 _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
2309 va_list ap;
2310 char *ret;
2312 va_start(ap, fmt);
2313 ret = talloc_vasprintf(t, fmt, ap);
2314 va_end(ap);
2315 return ret;
2318 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2319 const char *fmt, va_list ap)
2320 PRINTF_ATTRIBUTE(3,0);
2322 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2323 const char *fmt, va_list ap)
2325 ssize_t alen;
2326 va_list ap2;
2327 char c;
2329 va_copy(ap2, ap);
2330 alen = vsnprintf(&c, 1, fmt, ap2);
2331 va_end(ap2);
2333 if (alen <= 0) {
2334 /* Either the vsnprintf failed or the format resulted in
2335 * no characters being formatted. In the former case, we
2336 * ought to return NULL, in the latter we ought to return
2337 * the original string. Most current callers of this
2338 * function expect it to never return NULL.
2340 return s;
2343 s = talloc_realloc(NULL, s, char, slen + alen + 1);
2344 if (!s) return NULL;
2346 va_copy(ap2, ap);
2347 vsnprintf(s + slen, alen + 1, fmt, ap2);
2348 va_end(ap2);
2350 _talloc_set_name_const(s, s);
2351 return s;
2355 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2356 * and return @p s, which may have moved. Good for gradually
2357 * accumulating output into a string buffer. Appends at the end
2358 * of the string.
2360 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
2362 if (unlikely(!s)) {
2363 return talloc_vasprintf(NULL, fmt, ap);
2366 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
2370 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2371 * and return @p s, which may have moved. Always appends at the
2372 * end of the talloc'ed buffer, not the end of the string.
2374 _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
2376 size_t slen;
2378 if (unlikely(!s)) {
2379 return talloc_vasprintf(NULL, fmt, ap);
2382 slen = talloc_get_size(s);
2383 if (likely(slen > 0)) {
2384 slen--;
2387 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
2391 Realloc @p s to append the formatted result of @p fmt and return @p
2392 s, which may have moved. Good for gradually accumulating output
2393 into a string buffer.
2395 _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
2397 va_list ap;
2399 va_start(ap, fmt);
2400 s = talloc_vasprintf_append(s, fmt, ap);
2401 va_end(ap);
2402 return s;
2406 Realloc @p s to append the formatted result of @p fmt and return @p
2407 s, which may have moved. Good for gradually accumulating output
2408 into a buffer.
2410 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
2412 va_list ap;
2414 va_start(ap, fmt);
2415 s = talloc_vasprintf_append_buffer(s, fmt, ap);
2416 va_end(ap);
2417 return s;
2421 alloc an array, checking for integer overflow in the array size
2423 _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2425 if (count >= MAX_TALLOC_SIZE/el_size) {
2426 return NULL;
2428 return _talloc_named_const(ctx, el_size * count, name);
2432 alloc an zero array, checking for integer overflow in the array size
2434 _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2436 if (count >= MAX_TALLOC_SIZE/el_size) {
2437 return NULL;
2439 return _talloc_zero(ctx, el_size * count, name);
2443 realloc an array, checking for integer overflow in the array size
2445 _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
2447 if (count >= MAX_TALLOC_SIZE/el_size) {
2448 return NULL;
2450 return _talloc_realloc(ctx, ptr, el_size * count, name);
2454 a function version of talloc_realloc(), so it can be passed as a function pointer
2455 to libraries that want a realloc function (a realloc function encapsulates
2456 all the basic capabilities of an allocation library, which is why this is useful)
2458 _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
2460 return _talloc_realloc(context, ptr, size, NULL);
2464 static int talloc_autofree_destructor(void *ptr)
2466 autofree_context = NULL;
2467 return 0;
2470 static void talloc_autofree(void)
2472 talloc_free(autofree_context);
2476 return a context which will be auto-freed on exit
2477 this is useful for reducing the noise in leak reports
2479 _PUBLIC_ void *talloc_autofree_context(void)
2481 if (autofree_context == NULL) {
2482 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
2483 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
2484 atexit(talloc_autofree);
2486 return autofree_context;
2489 _PUBLIC_ size_t talloc_get_size(const void *context)
2491 struct talloc_chunk *tc;
2493 if (context == NULL) {
2494 context = null_context;
2496 if (context == NULL) {
2497 return 0;
2500 tc = talloc_chunk_from_ptr(context);
2502 return tc->size;
2506 find a parent of this context that has the given name, if any
2508 _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
2510 struct talloc_chunk *tc;
2512 if (context == NULL) {
2513 return NULL;
2516 tc = talloc_chunk_from_ptr(context);
2517 while (tc) {
2518 if (tc->name && strcmp(tc->name, name) == 0) {
2519 return TC_PTR_FROM_CHUNK(tc);
2521 while (tc && tc->prev) tc = tc->prev;
2522 if (tc) {
2523 tc = tc->parent;
2526 return NULL;
2530 show the parentage of a context
2532 _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2534 struct talloc_chunk *tc;
2536 if (context == NULL) {
2537 fprintf(file, "talloc no parents for NULL\n");
2538 return;
2541 tc = talloc_chunk_from_ptr(context);
2542 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
2543 while (tc) {
2544 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2545 while (tc && tc->prev) tc = tc->prev;
2546 if (tc) {
2547 tc = tc->parent;
2550 fflush(file);
2554 return 1 if ptr is a parent of context
2556 static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2558 struct talloc_chunk *tc;
2560 if (context == NULL) {
2561 return 0;
2564 tc = talloc_chunk_from_ptr(context);
2565 while (tc && depth > 0) {
2566 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2567 while (tc && tc->prev) tc = tc->prev;
2568 if (tc) {
2569 tc = tc->parent;
2570 depth--;
2573 return 0;
2577 return 1 if ptr is a parent of context
2579 _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2581 return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
2585 return the total size of memory used by this context and all children
2587 static size_t _talloc_total_limit_size(const void *ptr,
2588 struct talloc_memlimit *old_limit,
2589 struct talloc_memlimit *new_limit)
2591 return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT,
2592 old_limit, new_limit);
2595 static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size)
2597 struct talloc_memlimit *l;
2599 for (l = limit; l != NULL; l = l->upper) {
2600 if (l->max_size != 0 &&
2601 ((l->max_size <= l->cur_size) ||
2602 (l->max_size - l->cur_size < size))) {
2603 return false;
2607 return true;
2611 Update memory limits when freeing a talloc_chunk.
2613 static void talloc_memlimit_update_on_free(struct talloc_chunk *tc)
2615 size_t limit_shrink_size;
2617 if (!tc->limit) {
2618 return;
2622 * Pool entries don't count. Only the pools
2623 * themselves are counted as part of the memory
2624 * limits.
2626 if (tc->flags & TALLOC_FLAG_POOLMEM) {
2627 return;
2631 * If we are part of a memory limited context hierarchy
2632 * we need to subtract the memory used from the counters
2635 limit_shrink_size = tc->size+TC_HDR_SIZE;
2638 * If we're deallocating a pool, take into
2639 * account the prefix size added for the pool.
2642 if (tc->flags & TALLOC_FLAG_POOL) {
2643 limit_shrink_size += TP_HDR_SIZE;
2646 talloc_memlimit_shrink(tc->limit, limit_shrink_size);
2648 if (tc->limit->parent == tc) {
2649 free(tc->limit);
2652 tc->limit = NULL;
2656 Increase memory limit accounting after a malloc/realloc.
2658 static void talloc_memlimit_grow(struct talloc_memlimit *limit,
2659 size_t size)
2661 struct talloc_memlimit *l;
2663 for (l = limit; l != NULL; l = l->upper) {
2664 size_t new_cur_size = l->cur_size + size;
2665 if (new_cur_size < l->cur_size) {
2666 talloc_abort("logic error in talloc_memlimit_grow\n");
2667 return;
2669 l->cur_size = new_cur_size;
2674 Decrease memory limit accounting after a free/realloc.
2676 static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
2677 size_t size)
2679 struct talloc_memlimit *l;
2681 for (l = limit; l != NULL; l = l->upper) {
2682 if (l->cur_size < size) {
2683 talloc_abort("logic error in talloc_memlimit_shrink\n");
2684 return;
2686 l->cur_size = l->cur_size - size;
2690 _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
2692 struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);
2693 struct talloc_memlimit *orig_limit;
2694 struct talloc_memlimit *limit = NULL;
2696 if (tc->limit && tc->limit->parent == tc) {
2697 tc->limit->max_size = max_size;
2698 return 0;
2700 orig_limit = tc->limit;
2702 limit = malloc(sizeof(struct talloc_memlimit));
2703 if (limit == NULL) {
2704 return 1;
2706 limit->parent = tc;
2707 limit->max_size = max_size;
2708 limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit);
2710 if (orig_limit) {
2711 limit->upper = orig_limit;
2712 } else {
2713 limit->upper = NULL;
2716 return 0;