s3: krb5: keytab - The done label can be jumped to with context == NULL.
[Samba.git] / lib / talloc / talloc.c
blobc10fd53db12b81766dc08f5604686caa6aa2952e
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 inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size);
239 static inline void talloc_memlimit_grow(struct talloc_memlimit *limit,
240 size_t size);
241 static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit,
242 size_t size);
243 static inline void talloc_memlimit_update_on_free(struct talloc_chunk *tc);
245 static inline void _talloc_set_name_const(const void *ptr, const char *name);
247 typedef int (*talloc_destructor_t)(void *);
249 struct talloc_pool_hdr;
251 struct talloc_chunk {
252 struct talloc_chunk *next, *prev;
253 struct talloc_chunk *parent, *child;
254 struct talloc_reference_handle *refs;
255 talloc_destructor_t destructor;
256 const char *name;
257 size_t size;
258 unsigned flags;
261 * limit semantics:
262 * if 'limit' is set it means all *new* children of the context will
263 * be limited to a total aggregate size ox max_size for memory
264 * allocations.
265 * cur_size is used to keep track of the current use
267 struct talloc_memlimit *limit;
270 * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
271 * is a pointer to the struct talloc_chunk of the pool that it was
272 * allocated from. This way children can quickly find the pool to chew
273 * from.
275 struct talloc_pool_hdr *pool;
278 /* 16 byte alignment seems to keep everyone happy */
279 #define TC_ALIGN16(s) (((s)+15)&~15)
280 #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
281 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
283 _PUBLIC_ int talloc_version_major(void)
285 return TALLOC_VERSION_MAJOR;
288 _PUBLIC_ int talloc_version_minor(void)
290 return TALLOC_VERSION_MINOR;
293 static void (*talloc_log_fn)(const char *message);
295 _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
297 talloc_log_fn = log_fn;
300 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
301 static void talloc_log(const char *fmt, ...)
303 va_list ap;
304 char *message;
306 if (!talloc_log_fn) {
307 return;
310 va_start(ap, fmt);
311 message = talloc_vasprintf(NULL, fmt, ap);
312 va_end(ap);
314 talloc_log_fn(message);
315 talloc_free(message);
318 static void talloc_log_stderr(const char *message)
320 fprintf(stderr, "%s", message);
323 _PUBLIC_ void talloc_set_log_stderr(void)
325 talloc_set_log_fn(talloc_log_stderr);
328 static void (*talloc_abort_fn)(const char *reason);
330 _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
332 talloc_abort_fn = abort_fn;
335 static void talloc_abort(const char *reason)
337 talloc_log("%s\n", reason);
339 if (!talloc_abort_fn) {
340 TALLOC_ABORT(reason);
343 talloc_abort_fn(reason);
346 static void talloc_abort_magic(unsigned magic)
348 unsigned striped = magic - TALLOC_MAGIC_BASE;
349 unsigned major = (striped & 0xFFFFF000) >> 12;
350 unsigned minor = (striped & 0x00000FF0) >> 4;
351 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
352 magic, major, minor,
353 TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
354 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
357 static void talloc_abort_access_after_free(void)
359 talloc_abort("Bad talloc magic value - access after free");
362 static void talloc_abort_unknown_value(void)
364 talloc_abort("Bad talloc magic value - unknown value");
367 /* panic if we get a bad magic value */
368 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
370 const char *pp = (const char *)ptr;
371 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
372 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
373 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
374 talloc_abort_magic(tc->flags & (~0xF));
375 return NULL;
378 if (tc->flags & TALLOC_FLAG_FREE) {
379 talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
380 talloc_abort_access_after_free();
381 return NULL;
382 } else {
383 talloc_abort_unknown_value();
384 return NULL;
387 return tc;
390 /* hook into the front of the list */
391 #define _TLIST_ADD(list, p) \
392 do { \
393 if (!(list)) { \
394 (list) = (p); \
395 (p)->next = (p)->prev = NULL; \
396 } else { \
397 (list)->prev = (p); \
398 (p)->next = (list); \
399 (p)->prev = NULL; \
400 (list) = (p); \
402 } while (0)
404 /* remove an element from a list - element doesn't have to be in list. */
405 #define _TLIST_REMOVE(list, p) \
406 do { \
407 if ((p) == (list)) { \
408 (list) = (p)->next; \
409 if (list) (list)->prev = NULL; \
410 } else { \
411 if ((p)->prev) (p)->prev->next = (p)->next; \
412 if ((p)->next) (p)->next->prev = (p)->prev; \
414 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
415 } while (0)
419 return the parent chunk of a pointer
421 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
423 struct talloc_chunk *tc;
425 if (unlikely(ptr == NULL)) {
426 return NULL;
429 tc = talloc_chunk_from_ptr(ptr);
430 while (tc->prev) tc=tc->prev;
432 return tc->parent;
435 _PUBLIC_ void *talloc_parent(const void *ptr)
437 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
438 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
442 find parents name
444 _PUBLIC_ const char *talloc_parent_name(const void *ptr)
446 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
447 return tc? tc->name : NULL;
451 A pool carries an in-pool object count count in the first 16 bytes.
452 bytes. This is done to support talloc_steal() to a parent outside of the
453 pool. The count includes the pool itself, so a talloc_free() on a pool will
454 only destroy the pool if the count has dropped to zero. A talloc_free() of a
455 pool member will reduce the count, and eventually also call free(3) on the
456 pool memory.
458 The object count is not put into "struct talloc_chunk" because it is only
459 relevant for talloc pools and the alignment to 16 bytes would increase the
460 memory footprint of each talloc chunk by those 16 bytes.
463 struct talloc_pool_hdr {
464 void *end;
465 unsigned int object_count;
466 size_t poolsize;
469 #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr))
471 static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c)
473 return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE);
476 static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h)
478 return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE);
481 static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr)
483 struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
484 return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize;
487 static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr)
489 return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end;
492 /* If tc is inside a pool, this gives the next neighbour. */
493 static inline void *tc_next_chunk(struct talloc_chunk *tc)
495 return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size);
498 static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr)
500 struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
501 return tc_next_chunk(tc);
504 /* Mark the whole remaining pool as not accessable */
505 static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr)
507 size_t flen = tc_pool_space_left(pool_hdr);
509 if (unlikely(talloc_fill.enabled)) {
510 memset(pool_hdr->end, talloc_fill.fill_value, flen);
513 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
514 VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen);
515 #endif
519 Allocate from a pool
522 static inline struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
523 size_t size, size_t prefix_len)
525 struct talloc_pool_hdr *pool_hdr = NULL;
526 size_t space_left;
527 struct talloc_chunk *result;
528 size_t chunk_size;
530 if (parent == NULL) {
531 return NULL;
534 if (parent->flags & TALLOC_FLAG_POOL) {
535 pool_hdr = talloc_pool_from_chunk(parent);
537 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
538 pool_hdr = parent->pool;
541 if (pool_hdr == NULL) {
542 return NULL;
545 space_left = tc_pool_space_left(pool_hdr);
548 * Align size to 16 bytes
550 chunk_size = TC_ALIGN16(size + prefix_len);
552 if (space_left < chunk_size) {
553 return NULL;
556 result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len);
558 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
559 VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size);
560 #endif
562 pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size);
564 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
565 result->pool = pool_hdr;
567 pool_hdr->object_count++;
569 return result;
573 Allocate a bit of memory as a child of an existing pointer
575 static inline void *__talloc_with_prefix(const void *context, size_t size,
576 size_t prefix_len)
578 struct talloc_chunk *tc = NULL;
579 struct talloc_memlimit *limit = NULL;
580 size_t total_len = TC_HDR_SIZE + size + prefix_len;
582 if (unlikely(context == NULL)) {
583 context = null_context;
586 if (unlikely(size >= MAX_TALLOC_SIZE)) {
587 return NULL;
590 if (unlikely(total_len < TC_HDR_SIZE)) {
591 return NULL;
594 if (context != NULL) {
595 struct talloc_chunk *ptc = talloc_chunk_from_ptr(context);
597 if (ptc->limit != NULL) {
598 limit = ptc->limit;
601 tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len);
604 if (tc == NULL) {
605 char *ptr;
608 * Only do the memlimit check/update on actual allocation.
610 if (!talloc_memlimit_check(limit, total_len)) {
611 errno = ENOMEM;
612 return NULL;
615 ptr = malloc(total_len);
616 if (unlikely(ptr == NULL)) {
617 return NULL;
619 tc = (struct talloc_chunk *)(ptr + prefix_len);
620 tc->flags = TALLOC_MAGIC;
621 tc->pool = NULL;
623 talloc_memlimit_grow(limit, total_len);
626 tc->limit = limit;
627 tc->size = size;
628 tc->destructor = NULL;
629 tc->child = NULL;
630 tc->name = NULL;
631 tc->refs = NULL;
633 if (likely(context)) {
634 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
636 if (parent->child) {
637 parent->child->parent = NULL;
638 tc->next = parent->child;
639 tc->next->prev = tc;
640 } else {
641 tc->next = NULL;
643 tc->parent = parent;
644 tc->prev = NULL;
645 parent->child = tc;
646 } else {
647 tc->next = tc->prev = tc->parent = NULL;
650 return TC_PTR_FROM_CHUNK(tc);
653 static inline void *__talloc(const void *context, size_t size)
655 return __talloc_with_prefix(context, size, 0);
659 * Create a talloc pool
662 static inline void *_talloc_pool(const void *context, size_t size)
664 struct talloc_chunk *tc;
665 struct talloc_pool_hdr *pool_hdr;
666 void *result;
668 result = __talloc_with_prefix(context, size, TP_HDR_SIZE);
670 if (unlikely(result == NULL)) {
671 return NULL;
674 tc = talloc_chunk_from_ptr(result);
675 pool_hdr = talloc_pool_from_chunk(tc);
677 tc->flags |= TALLOC_FLAG_POOL;
678 tc->size = 0;
680 pool_hdr->object_count = 1;
681 pool_hdr->end = result;
682 pool_hdr->poolsize = size;
684 tc_invalidate_pool(pool_hdr);
686 return result;
689 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
691 return _talloc_pool(context, size);
695 * Create a talloc pool correctly sized for a basic size plus
696 * a number of subobjects whose total size is given. Essentially
697 * a custom allocator for talloc to reduce fragmentation.
700 _PUBLIC_ void *_talloc_pooled_object(const void *ctx,
701 size_t type_size,
702 const char *type_name,
703 unsigned num_subobjects,
704 size_t total_subobjects_size)
706 size_t poolsize, subobjects_slack, tmp;
707 struct talloc_chunk *tc;
708 struct talloc_pool_hdr *pool_hdr;
709 void *ret;
711 poolsize = type_size + total_subobjects_size;
713 if ((poolsize < type_size) || (poolsize < total_subobjects_size)) {
714 goto overflow;
717 if (num_subobjects == UINT_MAX) {
718 goto overflow;
720 num_subobjects += 1; /* the object body itself */
723 * Alignment can increase the pool size by at most 15 bytes per object
724 * plus alignment for the object itself
726 subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects;
727 if (subobjects_slack < num_subobjects) {
728 goto overflow;
731 tmp = poolsize + subobjects_slack;
732 if ((tmp < poolsize) || (tmp < subobjects_slack)) {
733 goto overflow;
735 poolsize = tmp;
737 ret = _talloc_pool(ctx, poolsize);
738 if (ret == NULL) {
739 return NULL;
742 tc = talloc_chunk_from_ptr(ret);
743 tc->size = type_size;
745 pool_hdr = talloc_pool_from_chunk(tc);
747 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
748 VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size);
749 #endif
751 pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size));
753 _talloc_set_name_const(ret, type_name);
754 return ret;
756 overflow:
757 return NULL;
761 setup a destructor to be called on free of a pointer
762 the destructor should return 0 on success, or -1 on failure.
763 if the destructor fails then the free is failed, and the memory can
764 be continued to be used
766 _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
768 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
769 tc->destructor = destructor;
773 increase the reference count on a piece of memory.
775 _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
777 if (unlikely(!talloc_reference(null_context, ptr))) {
778 return -1;
780 return 0;
784 helper for talloc_reference()
786 this is referenced by a function pointer and should not be inline
788 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
790 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
791 _TLIST_REMOVE(ptr_tc->refs, handle);
792 return 0;
796 more efficient way to add a name to a pointer - the name must point to a
797 true string constant
799 static inline void _talloc_set_name_const(const void *ptr, const char *name)
801 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
802 tc->name = name;
806 internal talloc_named_const()
808 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
810 void *ptr;
812 ptr = __talloc(context, size);
813 if (unlikely(ptr == NULL)) {
814 return NULL;
817 _talloc_set_name_const(ptr, name);
819 return ptr;
823 make a secondary reference to a pointer, hanging off the given context.
824 the pointer remains valid until both the original caller and this given
825 context are freed.
827 the major use for this is when two different structures need to reference the
828 same underlying data, and you want to be able to free the two instances separately,
829 and in either order
831 _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
833 struct talloc_chunk *tc;
834 struct talloc_reference_handle *handle;
835 if (unlikely(ptr == NULL)) return NULL;
837 tc = talloc_chunk_from_ptr(ptr);
838 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
839 sizeof(struct talloc_reference_handle),
840 TALLOC_MAGIC_REFERENCE);
841 if (unlikely(handle == NULL)) return NULL;
843 /* note that we hang the destructor off the handle, not the
844 main context as that allows the caller to still setup their
845 own destructor on the context if they want to */
846 talloc_set_destructor(handle, talloc_reference_destructor);
847 handle->ptr = discard_const_p(void, ptr);
848 handle->location = location;
849 _TLIST_ADD(tc->refs, handle);
850 return handle->ptr;
853 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
855 static inline void _talloc_free_poolmem(struct talloc_chunk *tc,
856 const char *location)
858 struct talloc_pool_hdr *pool;
859 struct talloc_chunk *pool_tc;
860 void *next_tc;
862 pool = tc->pool;
863 pool_tc = talloc_chunk_from_pool(pool);
864 next_tc = tc_next_chunk(tc);
866 tc->flags |= TALLOC_FLAG_FREE;
868 /* we mark the freed memory with where we called the free
869 * from. This means on a double free error we can report where
870 * the first free came from
872 tc->name = location;
874 TC_INVALIDATE_FULL_CHUNK(tc);
876 if (unlikely(pool->object_count == 0)) {
877 talloc_abort("Pool object count zero!");
878 return;
881 pool->object_count--;
883 if (unlikely(pool->object_count == 1
884 && !(pool_tc->flags & TALLOC_FLAG_FREE))) {
886 * if there is just one object left in the pool
887 * and pool->flags does not have TALLOC_FLAG_FREE,
888 * it means this is the pool itself and
889 * the rest is available for new objects
890 * again.
892 pool->end = tc_pool_first_chunk(pool);
893 tc_invalidate_pool(pool);
894 return;
897 if (unlikely(pool->object_count == 0)) {
899 * we mark the freed memory with where we called the free
900 * from. This means on a double free error we can report where
901 * the first free came from
903 pool_tc->name = location;
905 if (pool_tc->flags & TALLOC_FLAG_POOLMEM) {
906 _talloc_free_poolmem(pool_tc, location);
907 } else {
909 * The talloc_memlimit_update_on_free()
910 * call takes into account the
911 * prefix TP_HDR_SIZE allocated before
912 * the pool talloc_chunk.
914 talloc_memlimit_update_on_free(pool_tc);
915 TC_INVALIDATE_FULL_CHUNK(pool_tc);
916 free(pool);
918 return;
921 if (pool->end == next_tc) {
923 * if pool->pool still points to end of
924 * 'tc' (which is stored in the 'next_tc' variable),
925 * we can reclaim the memory of 'tc'.
927 pool->end = tc;
928 return;
932 * Do nothing. The memory is just "wasted", waiting for the pool
933 * itself to be freed.
937 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
938 void *ptr,
939 const char *location);
942 internal talloc_free call
944 static inline int _talloc_free_internal(void *ptr, const char *location)
946 struct talloc_chunk *tc;
947 void *ptr_to_free;
949 if (unlikely(ptr == NULL)) {
950 return -1;
953 /* possibly initialised the talloc fill value */
954 if (unlikely(!talloc_fill.initialised)) {
955 const char *fill = getenv(TALLOC_FILL_ENV);
956 if (fill != NULL) {
957 talloc_fill.enabled = true;
958 talloc_fill.fill_value = strtoul(fill, NULL, 0);
960 talloc_fill.initialised = true;
963 tc = talloc_chunk_from_ptr(ptr);
965 if (unlikely(tc->refs)) {
966 int is_child;
967 /* check if this is a reference from a child or
968 * grandchild back to it's parent or grandparent
970 * in that case we need to remove the reference and
971 * call another instance of talloc_free() on the current
972 * pointer.
974 is_child = talloc_is_parent(tc->refs, ptr);
975 _talloc_free_internal(tc->refs, location);
976 if (is_child) {
977 return _talloc_free_internal(ptr, location);
979 return -1;
982 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
983 /* we have a free loop - stop looping */
984 return 0;
987 if (unlikely(tc->destructor)) {
988 talloc_destructor_t d = tc->destructor;
989 if (d == (talloc_destructor_t)-1) {
990 return -1;
992 tc->destructor = (talloc_destructor_t)-1;
993 if (d(ptr) == -1) {
995 * Only replace the destructor pointer if
996 * calling the destructor didn't modify it.
998 if (tc->destructor == (talloc_destructor_t)-1) {
999 tc->destructor = d;
1001 return -1;
1003 tc->destructor = NULL;
1006 if (tc->parent) {
1007 _TLIST_REMOVE(tc->parent->child, tc);
1008 if (tc->parent->child) {
1009 tc->parent->child->parent = tc->parent;
1011 } else {
1012 if (tc->prev) tc->prev->next = tc->next;
1013 if (tc->next) tc->next->prev = tc->prev;
1014 tc->prev = tc->next = NULL;
1017 tc->flags |= TALLOC_FLAG_LOOP;
1019 _talloc_free_children_internal(tc, ptr, location);
1021 tc->flags |= TALLOC_FLAG_FREE;
1023 /* we mark the freed memory with where we called the free
1024 * from. This means on a double free error we can report where
1025 * the first free came from
1027 tc->name = location;
1029 if (tc->flags & TALLOC_FLAG_POOL) {
1030 struct talloc_pool_hdr *pool;
1032 pool = talloc_pool_from_chunk(tc);
1034 if (unlikely(pool->object_count == 0)) {
1035 talloc_abort("Pool object count zero!");
1036 return 0;
1039 pool->object_count--;
1041 if (likely(pool->object_count != 0)) {
1042 return 0;
1046 * With object_count==0, a pool becomes a normal piece of
1047 * memory to free. If it's allocated inside a pool, it needs
1048 * to be freed as poolmem, else it needs to be just freed.
1050 ptr_to_free = pool;
1051 } else {
1052 ptr_to_free = tc;
1055 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1056 _talloc_free_poolmem(tc, location);
1057 return 0;
1060 talloc_memlimit_update_on_free(tc);
1062 TC_INVALIDATE_FULL_CHUNK(tc);
1063 free(ptr_to_free);
1064 return 0;
1067 static inline size_t _talloc_total_limit_size(const void *ptr,
1068 struct talloc_memlimit *old_limit,
1069 struct talloc_memlimit *new_limit);
1072 move a lump of memory from one talloc context to another return the
1073 ptr on success, or NULL if it could not be transferred.
1074 passing NULL as ptr will always return NULL with no side effects.
1076 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
1078 struct talloc_chunk *tc, *new_tc;
1079 size_t ctx_size = 0;
1081 if (unlikely(!ptr)) {
1082 return NULL;
1085 if (unlikely(new_ctx == NULL)) {
1086 new_ctx = null_context;
1089 tc = talloc_chunk_from_ptr(ptr);
1091 if (tc->limit != NULL) {
1093 ctx_size = _talloc_total_limit_size(ptr, NULL, NULL);
1095 /* Decrement the memory limit from the source .. */
1096 talloc_memlimit_shrink(tc->limit->upper, ctx_size);
1098 if (tc->limit->parent == tc) {
1099 tc->limit->upper = NULL;
1100 } else {
1101 tc->limit = NULL;
1105 if (unlikely(new_ctx == NULL)) {
1106 if (tc->parent) {
1107 _TLIST_REMOVE(tc->parent->child, tc);
1108 if (tc->parent->child) {
1109 tc->parent->child->parent = tc->parent;
1111 } else {
1112 if (tc->prev) tc->prev->next = tc->next;
1113 if (tc->next) tc->next->prev = tc->prev;
1116 tc->parent = tc->next = tc->prev = NULL;
1117 return discard_const_p(void, ptr);
1120 new_tc = talloc_chunk_from_ptr(new_ctx);
1122 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
1123 return discard_const_p(void, ptr);
1126 if (tc->parent) {
1127 _TLIST_REMOVE(tc->parent->child, tc);
1128 if (tc->parent->child) {
1129 tc->parent->child->parent = tc->parent;
1131 } else {
1132 if (tc->prev) tc->prev->next = tc->next;
1133 if (tc->next) tc->next->prev = tc->prev;
1134 tc->prev = tc->next = NULL;
1137 tc->parent = new_tc;
1138 if (new_tc->child) new_tc->child->parent = NULL;
1139 _TLIST_ADD(new_tc->child, tc);
1141 if (tc->limit || new_tc->limit) {
1142 ctx_size = _talloc_total_limit_size(ptr, tc->limit,
1143 new_tc->limit);
1144 /* .. and increment it in the destination. */
1145 if (new_tc->limit) {
1146 talloc_memlimit_grow(new_tc->limit, ctx_size);
1150 return discard_const_p(void, ptr);
1154 move a lump of memory from one talloc context to another return the
1155 ptr on success, or NULL if it could not be transferred.
1156 passing NULL as ptr will always return NULL with no side effects.
1158 _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
1160 struct talloc_chunk *tc;
1162 if (unlikely(ptr == NULL)) {
1163 return NULL;
1166 tc = talloc_chunk_from_ptr(ptr);
1168 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
1169 struct talloc_reference_handle *h;
1171 talloc_log("WARNING: talloc_steal with references at %s\n",
1172 location);
1174 for (h=tc->refs; h; h=h->next) {
1175 talloc_log("\treference at %s\n",
1176 h->location);
1180 #if 0
1181 /* this test is probably too expensive to have on in the
1182 normal build, but it useful for debugging */
1183 if (talloc_is_parent(new_ctx, ptr)) {
1184 talloc_log("WARNING: stealing into talloc child at %s\n", location);
1186 #endif
1188 return _talloc_steal_internal(new_ctx, ptr);
1192 this is like a talloc_steal(), but you must supply the old
1193 parent. This resolves the ambiguity in a talloc_steal() which is
1194 called on a context that has more than one parent (via references)
1196 The old parent can be either a reference or a parent
1198 _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
1200 struct talloc_chunk *tc;
1201 struct talloc_reference_handle *h;
1203 if (unlikely(ptr == NULL)) {
1204 return NULL;
1207 if (old_parent == talloc_parent(ptr)) {
1208 return _talloc_steal_internal(new_parent, ptr);
1211 tc = talloc_chunk_from_ptr(ptr);
1212 for (h=tc->refs;h;h=h->next) {
1213 if (talloc_parent(h) == old_parent) {
1214 if (_talloc_steal_internal(new_parent, h) != h) {
1215 return NULL;
1217 return discard_const_p(void, ptr);
1221 /* it wasn't a parent */
1222 return NULL;
1226 remove a secondary reference to a pointer. This undo's what
1227 talloc_reference() has done. The context and pointer arguments
1228 must match those given to a talloc_reference()
1230 static inline int talloc_unreference(const void *context, const void *ptr)
1232 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1233 struct talloc_reference_handle *h;
1235 if (unlikely(context == NULL)) {
1236 context = null_context;
1239 for (h=tc->refs;h;h=h->next) {
1240 struct talloc_chunk *p = talloc_parent_chunk(h);
1241 if (p == NULL) {
1242 if (context == NULL) break;
1243 } else if (TC_PTR_FROM_CHUNK(p) == context) {
1244 break;
1247 if (h == NULL) {
1248 return -1;
1251 return _talloc_free_internal(h, __location__);
1255 remove a specific parent context from a pointer. This is a more
1256 controlled variant of talloc_free()
1258 _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
1260 struct talloc_chunk *tc_p, *new_p, *tc_c;
1261 void *new_parent;
1263 if (ptr == NULL) {
1264 return -1;
1267 if (context == NULL) {
1268 context = null_context;
1271 if (talloc_unreference(context, ptr) == 0) {
1272 return 0;
1275 if (context != NULL) {
1276 tc_c = talloc_chunk_from_ptr(context);
1277 } else {
1278 tc_c = NULL;
1280 if (tc_c != talloc_parent_chunk(ptr)) {
1281 return -1;
1284 tc_p = talloc_chunk_from_ptr(ptr);
1286 if (tc_p->refs == NULL) {
1287 return _talloc_free_internal(ptr, __location__);
1290 new_p = talloc_parent_chunk(tc_p->refs);
1291 if (new_p) {
1292 new_parent = TC_PTR_FROM_CHUNK(new_p);
1293 } else {
1294 new_parent = NULL;
1297 if (talloc_unreference(new_parent, ptr) != 0) {
1298 return -1;
1301 _talloc_steal_internal(new_parent, ptr);
1303 return 0;
1307 add a name to an existing pointer - va_list version
1309 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
1311 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
1313 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1314 tc->name = talloc_vasprintf(ptr, fmt, ap);
1315 if (likely(tc->name)) {
1316 _talloc_set_name_const(tc->name, ".name");
1318 return tc->name;
1322 add a name to an existing pointer
1324 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
1326 const char *name;
1327 va_list ap;
1328 va_start(ap, fmt);
1329 name = talloc_set_name_v(ptr, fmt, ap);
1330 va_end(ap);
1331 return name;
1336 create a named talloc pointer. Any talloc pointer can be named, and
1337 talloc_named() operates just like talloc() except that it allows you
1338 to name the pointer.
1340 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
1342 va_list ap;
1343 void *ptr;
1344 const char *name;
1346 ptr = __talloc(context, size);
1347 if (unlikely(ptr == NULL)) return NULL;
1349 va_start(ap, fmt);
1350 name = talloc_set_name_v(ptr, fmt, ap);
1351 va_end(ap);
1353 if (unlikely(name == NULL)) {
1354 _talloc_free_internal(ptr, __location__);
1355 return NULL;
1358 return ptr;
1362 return the name of a talloc ptr, or "UNNAMED"
1364 static inline const char *__talloc_get_name(const void *ptr)
1366 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1367 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
1368 return ".reference";
1370 if (likely(tc->name)) {
1371 return tc->name;
1373 return "UNNAMED";
1376 _PUBLIC_ const char *talloc_get_name(const void *ptr)
1378 return __talloc_get_name(ptr);
1382 check if a pointer has the given name. If it does, return the pointer,
1383 otherwise return NULL
1385 _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1387 const char *pname;
1388 if (unlikely(ptr == NULL)) return NULL;
1389 pname = __talloc_get_name(ptr);
1390 if (likely(pname == name || strcmp(pname, name) == 0)) {
1391 return discard_const_p(void, ptr);
1393 return NULL;
1396 static void talloc_abort_type_mismatch(const char *location,
1397 const char *name,
1398 const char *expected)
1400 const char *reason;
1402 reason = talloc_asprintf(NULL,
1403 "%s: Type mismatch: name[%s] expected[%s]",
1404 location,
1405 name?name:"NULL",
1406 expected);
1407 if (!reason) {
1408 reason = "Type mismatch";
1411 talloc_abort(reason);
1414 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1416 const char *pname;
1418 if (unlikely(ptr == NULL)) {
1419 talloc_abort_type_mismatch(location, NULL, name);
1420 return NULL;
1423 pname = __talloc_get_name(ptr);
1424 if (likely(pname == name || strcmp(pname, name) == 0)) {
1425 return discard_const_p(void, ptr);
1428 talloc_abort_type_mismatch(location, pname, name);
1429 return NULL;
1433 this is for compatibility with older versions of talloc
1435 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1437 va_list ap;
1438 void *ptr;
1439 const char *name;
1441 ptr = __talloc(NULL, 0);
1442 if (unlikely(ptr == NULL)) return NULL;
1444 va_start(ap, fmt);
1445 name = talloc_set_name_v(ptr, fmt, ap);
1446 va_end(ap);
1448 if (unlikely(name == NULL)) {
1449 _talloc_free_internal(ptr, __location__);
1450 return NULL;
1453 return ptr;
1456 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
1457 void *ptr,
1458 const char *location)
1460 while (tc->child) {
1461 /* we need to work out who will own an abandoned child
1462 if it cannot be freed. In priority order, the first
1463 choice is owner of any remaining reference to this
1464 pointer, the second choice is our parent, and the
1465 final choice is the null context. */
1466 void *child = TC_PTR_FROM_CHUNK(tc->child);
1467 const void *new_parent = null_context;
1468 if (unlikely(tc->child->refs)) {
1469 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1470 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1472 if (unlikely(_talloc_free_internal(child, location) == -1)) {
1473 if (talloc_parent_chunk(child) != tc) {
1475 * Destructor already reparented this child.
1476 * No further reparenting needed.
1478 return;
1480 if (new_parent == null_context) {
1481 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1482 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1484 _talloc_steal_internal(new_parent, child);
1490 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1491 should probably not be used in new code. It's in here to keep the talloc
1492 code consistent across Samba 3 and 4.
1494 _PUBLIC_ void talloc_free_children(void *ptr)
1496 struct talloc_chunk *tc_name = NULL;
1497 struct talloc_chunk *tc;
1499 if (unlikely(ptr == NULL)) {
1500 return;
1503 tc = talloc_chunk_from_ptr(ptr);
1505 /* we do not want to free the context name if it is a child .. */
1506 if (likely(tc->child)) {
1507 for (tc_name = tc->child; tc_name; tc_name = tc_name->next) {
1508 if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break;
1510 if (tc_name) {
1511 _TLIST_REMOVE(tc->child, tc_name);
1512 if (tc->child) {
1513 tc->child->parent = tc;
1518 _talloc_free_children_internal(tc, ptr, __location__);
1520 /* .. so we put it back after all other children have been freed */
1521 if (tc_name) {
1522 if (tc->child) {
1523 tc->child->parent = NULL;
1525 tc_name->parent = tc;
1526 _TLIST_ADD(tc->child, tc_name);
1531 Allocate a bit of memory as a child of an existing pointer
1533 _PUBLIC_ void *_talloc(const void *context, size_t size)
1535 return __talloc(context, size);
1539 externally callable talloc_set_name_const()
1541 _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1543 _talloc_set_name_const(ptr, name);
1547 create a named talloc pointer. Any talloc pointer can be named, and
1548 talloc_named() operates just like talloc() except that it allows you
1549 to name the pointer.
1551 _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1553 return _talloc_named_const(context, size, name);
1557 free a talloc pointer. This also frees all child pointers of this
1558 pointer recursively
1560 return 0 if the memory is actually freed, otherwise -1. The memory
1561 will not be freed if the ref_count is > 1 or the destructor (if
1562 any) returns non-zero
1564 _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1566 struct talloc_chunk *tc;
1568 if (unlikely(ptr == NULL)) {
1569 return -1;
1572 tc = talloc_chunk_from_ptr(ptr);
1574 if (unlikely(tc->refs != NULL)) {
1575 struct talloc_reference_handle *h;
1577 if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1578 /* in this case we do know which parent should
1579 get this pointer, as there is really only
1580 one parent */
1581 return talloc_unlink(null_context, ptr);
1584 talloc_log("ERROR: talloc_free with references at %s\n",
1585 location);
1587 for (h=tc->refs; h; h=h->next) {
1588 talloc_log("\treference at %s\n",
1589 h->location);
1591 return -1;
1594 return _talloc_free_internal(ptr, location);
1600 A talloc version of realloc. The context argument is only used if
1601 ptr is NULL
1603 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1605 struct talloc_chunk *tc;
1606 void *new_ptr;
1607 bool malloced = false;
1608 struct talloc_pool_hdr *pool_hdr = NULL;
1609 size_t old_size = 0;
1610 size_t new_size = 0;
1612 /* size zero is equivalent to free() */
1613 if (unlikely(size == 0)) {
1614 talloc_unlink(context, ptr);
1615 return NULL;
1618 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1619 return NULL;
1622 /* realloc(NULL) is equivalent to malloc() */
1623 if (ptr == NULL) {
1624 return _talloc_named_const(context, size, name);
1627 tc = talloc_chunk_from_ptr(ptr);
1629 /* don't allow realloc on referenced pointers */
1630 if (unlikely(tc->refs)) {
1631 return NULL;
1634 /* don't let anybody try to realloc a talloc_pool */
1635 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1636 return NULL;
1639 if (tc->limit && (size > tc->size)) {
1640 if (!talloc_memlimit_check(tc->limit, (size - tc->size))) {
1641 errno = ENOMEM;
1642 return NULL;
1646 /* handle realloc inside a talloc_pool */
1647 if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
1648 pool_hdr = tc->pool;
1651 #if (ALWAYS_REALLOC == 0)
1652 /* don't shrink if we have less than 1k to gain */
1653 if (size < tc->size && tc->limit == NULL) {
1654 if (pool_hdr) {
1655 void *next_tc = tc_next_chunk(tc);
1656 TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1657 tc->size = size;
1658 if (next_tc == pool_hdr->end) {
1659 /* note: tc->size has changed, so this works */
1660 pool_hdr->end = tc_next_chunk(tc);
1662 return ptr;
1663 } else if ((tc->size - size) < 1024) {
1665 * if we call TC_INVALIDATE_SHRINK_CHUNK() here
1666 * we would need to call TC_UNDEFINE_GROW_CHUNK()
1667 * after each realloc call, which slows down
1668 * testing a lot :-(.
1670 * That is why we only mark memory as undefined here.
1672 TC_UNDEFINE_SHRINK_CHUNK(tc, size);
1674 /* do not shrink if we have less than 1k to gain */
1675 tc->size = size;
1676 return ptr;
1678 } else if (tc->size == size) {
1680 * do not change the pointer if it is exactly
1681 * the same size.
1683 return ptr;
1685 #endif
1687 /* by resetting magic we catch users of the old memory */
1688 tc->flags |= TALLOC_FLAG_FREE;
1690 #if ALWAYS_REALLOC
1691 if (pool_hdr) {
1692 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1693 pool_hdr->object_count--;
1695 if (new_ptr == NULL) {
1696 new_ptr = malloc(TC_HDR_SIZE+size);
1697 malloced = true;
1698 new_size = size;
1701 if (new_ptr) {
1702 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1703 TC_INVALIDATE_FULL_CHUNK(tc);
1705 } else {
1706 /* We're doing malloc then free here, so record the difference. */
1707 old_size = tc->size;
1708 new_size = size;
1709 new_ptr = malloc(size + TC_HDR_SIZE);
1710 if (new_ptr) {
1711 memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1712 free(tc);
1715 #else
1716 if (pool_hdr) {
1717 struct talloc_chunk *pool_tc;
1718 void *next_tc = tc_next_chunk(tc);
1719 size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size);
1720 size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
1721 size_t space_needed;
1722 size_t space_left;
1723 unsigned int chunk_count = pool_hdr->object_count;
1725 pool_tc = talloc_chunk_from_pool(pool_hdr);
1726 if (!(pool_tc->flags & TALLOC_FLAG_FREE)) {
1727 chunk_count -= 1;
1730 if (chunk_count == 1) {
1732 * optimize for the case where 'tc' is the only
1733 * chunk in the pool.
1735 char *start = tc_pool_first_chunk(pool_hdr);
1736 space_needed = new_chunk_size;
1737 space_left = (char *)tc_pool_end(pool_hdr) - start;
1739 if (space_left >= space_needed) {
1740 size_t old_used = TC_HDR_SIZE + tc->size;
1741 size_t new_used = TC_HDR_SIZE + size;
1742 new_ptr = start;
1744 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
1747 * The area from
1748 * start -> tc may have
1749 * been freed and thus been marked as
1750 * VALGRIND_MEM_NOACCESS. Set it to
1751 * VALGRIND_MEM_UNDEFINED so we can
1752 * copy into it without valgrind errors.
1753 * We can't just mark
1754 * new_ptr -> new_ptr + old_used
1755 * as this may overlap on top of tc,
1756 * (which is why we use memmove, not
1757 * memcpy below) hence the MIN.
1759 size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used);
1760 VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len);
1762 #endif
1764 memmove(new_ptr, tc, old_used);
1766 tc = (struct talloc_chunk *)new_ptr;
1767 TC_UNDEFINE_GROW_CHUNK(tc, size);
1770 * first we do not align the pool pointer
1771 * because we want to invalidate the padding
1772 * too.
1774 pool_hdr->end = new_used + (char *)new_ptr;
1775 tc_invalidate_pool(pool_hdr);
1777 /* now the aligned pointer */
1778 pool_hdr->end = new_chunk_size + (char *)new_ptr;
1779 goto got_new_ptr;
1782 next_tc = NULL;
1785 if (new_chunk_size == old_chunk_size) {
1786 TC_UNDEFINE_GROW_CHUNK(tc, size);
1787 tc->flags &= ~TALLOC_FLAG_FREE;
1788 tc->size = size;
1789 return ptr;
1792 if (next_tc == pool_hdr->end) {
1794 * optimize for the case where 'tc' is the last
1795 * chunk in the pool.
1797 space_needed = new_chunk_size - old_chunk_size;
1798 space_left = tc_pool_space_left(pool_hdr);
1800 if (space_left >= space_needed) {
1801 TC_UNDEFINE_GROW_CHUNK(tc, size);
1802 tc->flags &= ~TALLOC_FLAG_FREE;
1803 tc->size = size;
1804 pool_hdr->end = tc_next_chunk(tc);
1805 return ptr;
1809 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1811 if (new_ptr == NULL) {
1812 new_ptr = malloc(TC_HDR_SIZE+size);
1813 malloced = true;
1814 new_size = size;
1817 if (new_ptr) {
1818 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1820 _talloc_free_poolmem(tc, __location__ "_talloc_realloc");
1823 else {
1824 /* We're doing realloc here, so record the difference. */
1825 old_size = tc->size;
1826 new_size = size;
1827 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1829 got_new_ptr:
1830 #endif
1831 if (unlikely(!new_ptr)) {
1832 tc->flags &= ~TALLOC_FLAG_FREE;
1833 return NULL;
1836 tc = (struct talloc_chunk *)new_ptr;
1837 tc->flags &= ~TALLOC_FLAG_FREE;
1838 if (malloced) {
1839 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1841 if (tc->parent) {
1842 tc->parent->child = tc;
1844 if (tc->child) {
1845 tc->child->parent = tc;
1848 if (tc->prev) {
1849 tc->prev->next = tc;
1851 if (tc->next) {
1852 tc->next->prev = tc;
1855 if (new_size > old_size) {
1856 talloc_memlimit_grow(tc->limit, new_size - old_size);
1857 } else if (new_size < old_size) {
1858 talloc_memlimit_shrink(tc->limit, old_size - new_size);
1861 tc->size = size;
1862 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1864 return TC_PTR_FROM_CHUNK(tc);
1868 a wrapper around talloc_steal() for situations where you are moving a pointer
1869 between two structures, and want the old pointer to be set to NULL
1871 _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
1873 const void **pptr = discard_const_p(const void *,_pptr);
1874 void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1875 (*pptr) = NULL;
1876 return ret;
1879 enum talloc_mem_count_type {
1880 TOTAL_MEM_SIZE,
1881 TOTAL_MEM_BLOCKS,
1882 TOTAL_MEM_LIMIT,
1885 static inline size_t _talloc_total_mem_internal(const void *ptr,
1886 enum talloc_mem_count_type type,
1887 struct talloc_memlimit *old_limit,
1888 struct talloc_memlimit *new_limit)
1890 size_t total = 0;
1891 struct talloc_chunk *c, *tc;
1893 if (ptr == NULL) {
1894 ptr = null_context;
1896 if (ptr == NULL) {
1897 return 0;
1900 tc = talloc_chunk_from_ptr(ptr);
1902 if (old_limit || new_limit) {
1903 if (tc->limit && tc->limit->upper == old_limit) {
1904 tc->limit->upper = new_limit;
1908 /* optimize in the memlimits case */
1909 if (type == TOTAL_MEM_LIMIT &&
1910 tc->limit != NULL &&
1911 tc->limit != old_limit &&
1912 tc->limit->parent == tc) {
1913 return tc->limit->cur_size;
1916 if (tc->flags & TALLOC_FLAG_LOOP) {
1917 return 0;
1920 tc->flags |= TALLOC_FLAG_LOOP;
1922 if (old_limit || new_limit) {
1923 if (old_limit == tc->limit) {
1924 tc->limit = new_limit;
1928 switch (type) {
1929 case TOTAL_MEM_SIZE:
1930 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1931 total = tc->size;
1933 break;
1934 case TOTAL_MEM_BLOCKS:
1935 total++;
1936 break;
1937 case TOTAL_MEM_LIMIT:
1938 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1940 * Don't count memory allocated from a pool
1941 * when calculating limits. Only count the
1942 * pool itself.
1944 if (!(tc->flags & TALLOC_FLAG_POOLMEM)) {
1945 if (tc->flags & TALLOC_FLAG_POOL) {
1947 * If this is a pool, the allocated
1948 * size is in the pool header, and
1949 * remember to add in the prefix
1950 * length.
1952 struct talloc_pool_hdr *pool_hdr
1953 = talloc_pool_from_chunk(tc);
1954 total = pool_hdr->poolsize +
1955 TC_HDR_SIZE +
1956 TP_HDR_SIZE;
1957 } else {
1958 total = tc->size + TC_HDR_SIZE;
1962 break;
1964 for (c = tc->child; c; c = c->next) {
1965 total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type,
1966 old_limit, new_limit);
1969 tc->flags &= ~TALLOC_FLAG_LOOP;
1971 return total;
1975 return the total size of a talloc pool (subtree)
1977 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1979 return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL);
1983 return the total number of blocks in a talloc pool (subtree)
1985 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1987 return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL);
1991 return the number of external references to a pointer
1993 _PUBLIC_ size_t talloc_reference_count(const void *ptr)
1995 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1996 struct talloc_reference_handle *h;
1997 size_t ret = 0;
1999 for (h=tc->refs;h;h=h->next) {
2000 ret++;
2002 return ret;
2006 report on memory usage by all children of a pointer, giving a full tree view
2008 _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
2009 void (*callback)(const void *ptr,
2010 int depth, int max_depth,
2011 int is_ref,
2012 void *private_data),
2013 void *private_data)
2015 struct talloc_chunk *c, *tc;
2017 if (ptr == NULL) {
2018 ptr = null_context;
2020 if (ptr == NULL) return;
2022 tc = talloc_chunk_from_ptr(ptr);
2024 if (tc->flags & TALLOC_FLAG_LOOP) {
2025 return;
2028 callback(ptr, depth, max_depth, 0, private_data);
2030 if (max_depth >= 0 && depth >= max_depth) {
2031 return;
2034 tc->flags |= TALLOC_FLAG_LOOP;
2035 for (c=tc->child;c;c=c->next) {
2036 if (c->name == TALLOC_MAGIC_REFERENCE) {
2037 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
2038 callback(h->ptr, depth + 1, max_depth, 1, private_data);
2039 } else {
2040 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
2043 tc->flags &= ~TALLOC_FLAG_LOOP;
2046 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
2048 const char *name = __talloc_get_name(ptr);
2049 struct talloc_chunk *tc;
2050 FILE *f = (FILE *)_f;
2052 if (is_ref) {
2053 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
2054 return;
2057 tc = talloc_chunk_from_ptr(ptr);
2058 if (tc->limit && tc->limit->parent == tc) {
2059 fprintf(f, "%*s%-30s is a memlimit context"
2060 " (max_size = %lu bytes, cur_size = %lu bytes)\n",
2061 depth*4, "",
2062 name,
2063 (unsigned long)tc->limit->max_size,
2064 (unsigned long)tc->limit->cur_size);
2067 if (depth == 0) {
2068 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
2069 (max_depth < 0 ? "full " :""), name,
2070 (unsigned long)talloc_total_size(ptr),
2071 (unsigned long)talloc_total_blocks(ptr));
2072 return;
2075 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
2076 depth*4, "",
2077 name,
2078 (unsigned long)talloc_total_size(ptr),
2079 (unsigned long)talloc_total_blocks(ptr),
2080 (int)talloc_reference_count(ptr), ptr);
2082 #if 0
2083 fprintf(f, "content: ");
2084 if (talloc_total_size(ptr)) {
2085 int tot = talloc_total_size(ptr);
2086 int i;
2088 for (i = 0; i < tot; i++) {
2089 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
2090 fprintf(f, "%c", ((char *)ptr)[i]);
2091 } else {
2092 fprintf(f, "~%02x", ((char *)ptr)[i]);
2096 fprintf(f, "\n");
2097 #endif
2101 report on memory usage by all children of a pointer, giving a full tree view
2103 _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
2105 if (f) {
2106 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
2107 fflush(f);
2112 report on memory usage by all children of a pointer, giving a full tree view
2114 _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
2116 talloc_report_depth_file(ptr, 0, -1, f);
2120 report on memory usage by all children of a pointer
2122 _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
2124 talloc_report_depth_file(ptr, 0, 1, f);
2128 report on any memory hanging off the null context
2130 static void talloc_report_null(void)
2132 if (talloc_total_size(null_context) != 0) {
2133 talloc_report(null_context, stderr);
2138 report on any memory hanging off the null context
2140 static void talloc_report_null_full(void)
2142 if (talloc_total_size(null_context) != 0) {
2143 talloc_report_full(null_context, stderr);
2148 enable tracking of the NULL context
2150 _PUBLIC_ void talloc_enable_null_tracking(void)
2152 if (null_context == NULL) {
2153 null_context = _talloc_named_const(NULL, 0, "null_context");
2154 if (autofree_context != NULL) {
2155 talloc_reparent(NULL, null_context, autofree_context);
2161 enable tracking of the NULL context, not moving the autofree context
2162 into the NULL context. This is needed for the talloc testsuite
2164 _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
2166 if (null_context == NULL) {
2167 null_context = _talloc_named_const(NULL, 0, "null_context");
2172 disable tracking of the NULL context
2174 _PUBLIC_ void talloc_disable_null_tracking(void)
2176 if (null_context != NULL) {
2177 /* we have to move any children onto the real NULL
2178 context */
2179 struct talloc_chunk *tc, *tc2;
2180 tc = talloc_chunk_from_ptr(null_context);
2181 for (tc2 = tc->child; tc2; tc2=tc2->next) {
2182 if (tc2->parent == tc) tc2->parent = NULL;
2183 if (tc2->prev == tc) tc2->prev = NULL;
2185 for (tc2 = tc->next; tc2; tc2=tc2->next) {
2186 if (tc2->parent == tc) tc2->parent = NULL;
2187 if (tc2->prev == tc) tc2->prev = NULL;
2189 tc->child = NULL;
2190 tc->next = NULL;
2192 talloc_free(null_context);
2193 null_context = NULL;
2197 enable leak reporting on exit
2199 _PUBLIC_ void talloc_enable_leak_report(void)
2201 talloc_enable_null_tracking();
2202 atexit(talloc_report_null);
2206 enable full leak reporting on exit
2208 _PUBLIC_ void talloc_enable_leak_report_full(void)
2210 talloc_enable_null_tracking();
2211 atexit(talloc_report_null_full);
2215 talloc and zero memory.
2217 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
2219 void *p = _talloc_named_const(ctx, size, name);
2221 if (p) {
2222 memset(p, '\0', size);
2225 return p;
2229 memdup with a talloc.
2231 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
2233 void *newp = _talloc_named_const(t, size, name);
2235 if (likely(newp)) {
2236 memcpy(newp, p, size);
2239 return newp;
2242 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
2244 char *ret;
2246 ret = (char *)__talloc(t, len + 1);
2247 if (unlikely(!ret)) return NULL;
2249 memcpy(ret, p, len);
2250 ret[len] = 0;
2252 _talloc_set_name_const(ret, ret);
2253 return ret;
2257 strdup with a talloc
2259 _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
2261 if (unlikely(!p)) return NULL;
2262 return __talloc_strlendup(t, p, strlen(p));
2266 strndup with a talloc
2268 _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
2270 if (unlikely(!p)) return NULL;
2271 return __talloc_strlendup(t, p, strnlen(p, n));
2274 static inline char *__talloc_strlendup_append(char *s, size_t slen,
2275 const char *a, size_t alen)
2277 char *ret;
2279 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
2280 if (unlikely(!ret)) return NULL;
2282 /* append the string and the trailing \0 */
2283 memcpy(&ret[slen], a, alen);
2284 ret[slen+alen] = 0;
2286 _talloc_set_name_const(ret, ret);
2287 return ret;
2291 * Appends at the end of the string.
2293 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
2295 if (unlikely(!s)) {
2296 return talloc_strdup(NULL, a);
2299 if (unlikely(!a)) {
2300 return s;
2303 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
2307 * Appends at the end of the talloc'ed buffer,
2308 * not the end of the string.
2310 _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
2312 size_t slen;
2314 if (unlikely(!s)) {
2315 return talloc_strdup(NULL, a);
2318 if (unlikely(!a)) {
2319 return s;
2322 slen = talloc_get_size(s);
2323 if (likely(slen > 0)) {
2324 slen--;
2327 return __talloc_strlendup_append(s, slen, a, strlen(a));
2331 * Appends at the end of the string.
2333 _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
2335 if (unlikely(!s)) {
2336 return talloc_strndup(NULL, a, n);
2339 if (unlikely(!a)) {
2340 return s;
2343 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
2347 * Appends at the end of the talloc'ed buffer,
2348 * not the end of the string.
2350 _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
2352 size_t slen;
2354 if (unlikely(!s)) {
2355 return talloc_strndup(NULL, a, n);
2358 if (unlikely(!a)) {
2359 return s;
2362 slen = talloc_get_size(s);
2363 if (likely(slen > 0)) {
2364 slen--;
2367 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
2370 #ifndef HAVE_VA_COPY
2371 #ifdef HAVE___VA_COPY
2372 #define va_copy(dest, src) __va_copy(dest, src)
2373 #else
2374 #define va_copy(dest, src) (dest) = (src)
2375 #endif
2376 #endif
2378 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
2380 int len;
2381 char *ret;
2382 va_list ap2;
2383 char buf[1024];
2385 /* this call looks strange, but it makes it work on older solaris boxes */
2386 va_copy(ap2, ap);
2387 len = vsnprintf(buf, sizeof(buf), fmt, ap2);
2388 va_end(ap2);
2389 if (unlikely(len < 0)) {
2390 return NULL;
2393 ret = (char *)__talloc(t, len+1);
2394 if (unlikely(!ret)) return NULL;
2396 if (len < sizeof(buf)) {
2397 memcpy(ret, buf, len+1);
2398 } else {
2399 va_copy(ap2, ap);
2400 vsnprintf(ret, len+1, fmt, ap2);
2401 va_end(ap2);
2404 _talloc_set_name_const(ret, ret);
2405 return ret;
2410 Perform string formatting, and return a pointer to newly allocated
2411 memory holding the result, inside a memory pool.
2413 _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
2415 va_list ap;
2416 char *ret;
2418 va_start(ap, fmt);
2419 ret = talloc_vasprintf(t, fmt, ap);
2420 va_end(ap);
2421 return ret;
2424 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2425 const char *fmt, va_list ap)
2426 PRINTF_ATTRIBUTE(3,0);
2428 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2429 const char *fmt, va_list ap)
2431 ssize_t alen;
2432 va_list ap2;
2433 char c;
2435 va_copy(ap2, ap);
2436 alen = vsnprintf(&c, 1, fmt, ap2);
2437 va_end(ap2);
2439 if (alen <= 0) {
2440 /* Either the vsnprintf failed or the format resulted in
2441 * no characters being formatted. In the former case, we
2442 * ought to return NULL, in the latter we ought to return
2443 * the original string. Most current callers of this
2444 * function expect it to never return NULL.
2446 return s;
2449 s = talloc_realloc(NULL, s, char, slen + alen + 1);
2450 if (!s) return NULL;
2452 va_copy(ap2, ap);
2453 vsnprintf(s + slen, alen + 1, fmt, ap2);
2454 va_end(ap2);
2456 _talloc_set_name_const(s, s);
2457 return s;
2461 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2462 * and return @p s, which may have moved. Good for gradually
2463 * accumulating output into a string buffer. Appends at the end
2464 * of the string.
2466 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
2468 if (unlikely(!s)) {
2469 return talloc_vasprintf(NULL, fmt, ap);
2472 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
2476 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2477 * and return @p s, which may have moved. Always appends at the
2478 * end of the talloc'ed buffer, not the end of the string.
2480 _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
2482 size_t slen;
2484 if (unlikely(!s)) {
2485 return talloc_vasprintf(NULL, fmt, ap);
2488 slen = talloc_get_size(s);
2489 if (likely(slen > 0)) {
2490 slen--;
2493 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
2497 Realloc @p s to append the formatted result of @p fmt and return @p
2498 s, which may have moved. Good for gradually accumulating output
2499 into a string buffer.
2501 _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
2503 va_list ap;
2505 va_start(ap, fmt);
2506 s = talloc_vasprintf_append(s, fmt, ap);
2507 va_end(ap);
2508 return s;
2512 Realloc @p s to append the formatted result of @p fmt and return @p
2513 s, which may have moved. Good for gradually accumulating output
2514 into a buffer.
2516 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
2518 va_list ap;
2520 va_start(ap, fmt);
2521 s = talloc_vasprintf_append_buffer(s, fmt, ap);
2522 va_end(ap);
2523 return s;
2527 alloc an array, checking for integer overflow in the array size
2529 _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2531 if (count >= MAX_TALLOC_SIZE/el_size) {
2532 return NULL;
2534 return _talloc_named_const(ctx, el_size * count, name);
2538 alloc an zero array, checking for integer overflow in the array size
2540 _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2542 if (count >= MAX_TALLOC_SIZE/el_size) {
2543 return NULL;
2545 return _talloc_zero(ctx, el_size * count, name);
2549 realloc an array, checking for integer overflow in the array size
2551 _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
2553 if (count >= MAX_TALLOC_SIZE/el_size) {
2554 return NULL;
2556 return _talloc_realloc(ctx, ptr, el_size * count, name);
2560 a function version of talloc_realloc(), so it can be passed as a function pointer
2561 to libraries that want a realloc function (a realloc function encapsulates
2562 all the basic capabilities of an allocation library, which is why this is useful)
2564 _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
2566 return _talloc_realloc(context, ptr, size, NULL);
2570 static int talloc_autofree_destructor(void *ptr)
2572 autofree_context = NULL;
2573 return 0;
2576 static void talloc_autofree(void)
2578 talloc_free(autofree_context);
2582 return a context which will be auto-freed on exit
2583 this is useful for reducing the noise in leak reports
2585 _PUBLIC_ void *talloc_autofree_context(void)
2587 if (autofree_context == NULL) {
2588 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
2589 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
2590 atexit(talloc_autofree);
2592 return autofree_context;
2595 _PUBLIC_ size_t talloc_get_size(const void *context)
2597 struct talloc_chunk *tc;
2599 if (context == NULL) {
2600 context = null_context;
2602 if (context == NULL) {
2603 return 0;
2606 tc = talloc_chunk_from_ptr(context);
2608 return tc->size;
2612 find a parent of this context that has the given name, if any
2614 _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
2616 struct talloc_chunk *tc;
2618 if (context == NULL) {
2619 return NULL;
2622 tc = talloc_chunk_from_ptr(context);
2623 while (tc) {
2624 if (tc->name && strcmp(tc->name, name) == 0) {
2625 return TC_PTR_FROM_CHUNK(tc);
2627 while (tc && tc->prev) tc = tc->prev;
2628 if (tc) {
2629 tc = tc->parent;
2632 return NULL;
2636 show the parentage of a context
2638 _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2640 struct talloc_chunk *tc;
2642 if (context == NULL) {
2643 fprintf(file, "talloc no parents for NULL\n");
2644 return;
2647 tc = talloc_chunk_from_ptr(context);
2648 fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context));
2649 while (tc) {
2650 fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2651 while (tc && tc->prev) tc = tc->prev;
2652 if (tc) {
2653 tc = tc->parent;
2656 fflush(file);
2660 return 1 if ptr is a parent of context
2662 static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2664 struct talloc_chunk *tc;
2666 if (context == NULL) {
2667 return 0;
2670 tc = talloc_chunk_from_ptr(context);
2671 while (tc) {
2672 if (depth <= 0) {
2673 return 0;
2675 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2676 while (tc && tc->prev) tc = tc->prev;
2677 if (tc) {
2678 tc = tc->parent;
2679 depth--;
2682 return 0;
2686 return 1 if ptr is a parent of context
2688 _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2690 return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
2694 return the total size of memory used by this context and all children
2696 static inline size_t _talloc_total_limit_size(const void *ptr,
2697 struct talloc_memlimit *old_limit,
2698 struct talloc_memlimit *new_limit)
2700 return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT,
2701 old_limit, new_limit);
2704 static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size)
2706 struct talloc_memlimit *l;
2708 for (l = limit; l != NULL; l = l->upper) {
2709 if (l->max_size != 0 &&
2710 ((l->max_size <= l->cur_size) ||
2711 (l->max_size - l->cur_size < size))) {
2712 return false;
2716 return true;
2720 Update memory limits when freeing a talloc_chunk.
2722 static void talloc_memlimit_update_on_free(struct talloc_chunk *tc)
2724 size_t limit_shrink_size;
2726 if (!tc->limit) {
2727 return;
2731 * Pool entries don't count. Only the pools
2732 * themselves are counted as part of the memory
2733 * limits. Note that this also takes care of
2734 * nested pools which have both flags
2735 * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set.
2737 if (tc->flags & TALLOC_FLAG_POOLMEM) {
2738 return;
2742 * If we are part of a memory limited context hierarchy
2743 * we need to subtract the memory used from the counters
2746 limit_shrink_size = tc->size+TC_HDR_SIZE;
2749 * If we're deallocating a pool, take into
2750 * account the prefix size added for the pool.
2753 if (tc->flags & TALLOC_FLAG_POOL) {
2754 limit_shrink_size += TP_HDR_SIZE;
2757 talloc_memlimit_shrink(tc->limit, limit_shrink_size);
2759 if (tc->limit->parent == tc) {
2760 free(tc->limit);
2763 tc->limit = NULL;
2767 Increase memory limit accounting after a malloc/realloc.
2769 static void talloc_memlimit_grow(struct talloc_memlimit *limit,
2770 size_t size)
2772 struct talloc_memlimit *l;
2774 for (l = limit; l != NULL; l = l->upper) {
2775 size_t new_cur_size = l->cur_size + size;
2776 if (new_cur_size < l->cur_size) {
2777 talloc_abort("logic error in talloc_memlimit_grow\n");
2778 return;
2780 l->cur_size = new_cur_size;
2785 Decrease memory limit accounting after a free/realloc.
2787 static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
2788 size_t size)
2790 struct talloc_memlimit *l;
2792 for (l = limit; l != NULL; l = l->upper) {
2793 if (l->cur_size < size) {
2794 talloc_abort("logic error in talloc_memlimit_shrink\n");
2795 return;
2797 l->cur_size = l->cur_size - size;
2801 _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
2803 struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);
2804 struct talloc_memlimit *orig_limit;
2805 struct talloc_memlimit *limit = NULL;
2807 if (tc->limit && tc->limit->parent == tc) {
2808 tc->limit->max_size = max_size;
2809 return 0;
2811 orig_limit = tc->limit;
2813 limit = malloc(sizeof(struct talloc_memlimit));
2814 if (limit == NULL) {
2815 return 1;
2817 limit->parent = tc;
2818 limit->max_size = max_size;
2819 limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit);
2821 if (orig_limit) {
2822 limit->upper = orig_limit;
2823 } else {
2824 limit->upper = NULL;
2827 return 0;