2 Samba Unix SMB/CIFS implementation.
4 Samba temporary memory allocation functions - new interface
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 inspired by http://swapped.cc/halloc/
30 #define talloc(ctx, size) _talloc(ctx, size)
32 #define MAX_TALLOC_SIZE 0x10000000
33 #define TALLOC_MAGIC 0xe814ec4f
34 #define TALLOC_MAGIC_FREE 0x7faebef3
36 static void *null_context
;
39 struct talloc_chunk
*next
, *prev
;
40 struct talloc_chunk
*parent
, *child
;
44 int (*destructor
)(void *);
48 /* panic if we get a bad magic value */
49 static struct talloc_chunk
*talloc_chunk_from_ptr(void *ptr
)
51 struct talloc_chunk
*tc
= ((struct talloc_chunk
*)ptr
)-1;
52 if (tc
->magic
!= TALLOC_MAGIC
) {
53 if (tc
->magic
== TALLOC_MAGIC_FREE
) {
54 smb_panic("Bad talloc magic value - double free\n");
56 smb_panic("Bad talloc magic value\n");
63 Allocate a bit of memory as a child of an existing pointer
65 void *_talloc(void *context
, size_t size
)
67 struct talloc_chunk
*tc
;
69 if (context
== NULL
) {
70 context
= null_context
;
73 if (size
>= MAX_TALLOC_SIZE
) {
77 tc
= malloc(sizeof(*tc
)+size
);
83 tc
->magic
= TALLOC_MAGIC
;
85 tc
->destructor
= NULL
;
90 struct talloc_chunk
*parent
= talloc_chunk_from_ptr(context
);
95 parent
->child
->parent
= NULL
;
98 DLIST_ADD(parent
->child
, tc
);
100 tc
->next
= tc
->prev
= tc
->parent
= NULL
;
103 return (void *)(tc
+1);
108 setup a destructor to be called on free of a pointer
109 the destructor should return 0 on success, or -1 on failure.
110 if the destructor fails then the free is failed, and the memory can
111 be continued to be used
113 void talloc_set_destructor(void *ptr
, int (*destructor
)(void *))
115 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
116 tc
->destructor
= destructor
;
120 increase the reference count on a piece of memory. To decrease the
121 reference count call talloc_free(), which will free the memory if
122 the reference count reaches zero
124 void talloc_increase_ref_count(void *ptr
)
126 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
132 add a name to an existing pointer - va_list version
134 static void talloc_set_name_v(void *ptr
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
136 static void talloc_set_name_v(void *ptr
, const char *fmt
, va_list ap
)
138 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
139 tc
->name
= talloc_vasprintf(ptr
, fmt
, ap
);
143 add a name to an existing pointer
145 void talloc_set_name(void *ptr
, const char *fmt
, ...) _PRINTF_ATTRIBUTE(2,3)
149 talloc_set_name_v(ptr
, fmt
, ap
);
154 more efficient way to add a name to a pointer - the name must point to a
157 void talloc_set_name_const(void *ptr
, const char *name
)
159 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
164 create a named talloc pointer. Any talloc pointer can be named, and
165 talloc_named() operates just like talloc() except that it allows you
168 void *talloc_named(void *context
, size_t size
,
169 const char *fmt
, ...) _PRINTF_ATTRIBUTE(3,4)
174 ptr
= talloc(context
, size
);
180 talloc_set_name_v(ptr
, fmt
, ap
);
187 create a named talloc pointer. Any talloc pointer can be named, and
188 talloc_named() operates just like talloc() except that it allows you
191 void *talloc_named_const(void *context
, size_t size
, const char *name
)
195 ptr
= talloc(context
, size
);
200 talloc_set_name_const(ptr
, name
);
206 return the name of a talloc ptr, or "UNNAMED"
208 const char *talloc_get_name(void *ptr
)
210 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
218 this is for compatibility with older versions of talloc
220 void *talloc_init(const char *fmt
, ...) _PRINTF_ATTRIBUTE(1,2)
225 ptr
= talloc(NULL
, 0);
231 talloc_set_name_v(ptr
, fmt
, ap
);
240 free a talloc pointer. This also frees all child pointers of this
243 return 0 if the memory is actually freed, otherwise -1. The memory
244 will not be freed if the ref_count is > 1 or the destructor (if
245 any) returns non-zero
247 int talloc_free(void *ptr
)
249 struct talloc_chunk
*tc
;
255 tc
= talloc_chunk_from_ptr(ptr
);
258 if (tc
->ref_count
!= 0) {
262 if (tc
->destructor
&& tc
->destructor(ptr
) == -1) {
268 if (talloc_free(tc
->child
+ 1) != 0) {
269 tc
->child
->parent
= NULL
;
275 DLIST_REMOVE(tc
->parent
->child
, tc
);
276 if (tc
->parent
->child
) {
277 tc
->parent
->child
->parent
= tc
->parent
;
280 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
281 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
284 tc
->magic
= TALLOC_MAGIC_FREE
;
293 A talloc version of realloc
295 void *_talloc_realloc(void *ptr
, size_t size
, const char *name
)
297 struct talloc_chunk
*tc
;
300 /* size zero is equivalent to free() */
306 /* realloc(NULL) is equavalent to malloc() */
308 return talloc_named_const(NULL
, size
, name
);
311 tc
= talloc_chunk_from_ptr(ptr
);
313 /* by resetting magic we catch users of the old memory */
314 tc
->magic
= TALLOC_MAGIC_FREE
;
316 new_ptr
= realloc(tc
, size
+ sizeof(*tc
));
318 tc
->magic
= TALLOC_MAGIC
;
323 tc
->magic
= TALLOC_MAGIC
;
325 tc
->parent
->child
= new_ptr
;
336 talloc_set_name_const(tc
+1, name
);
338 return (void *)(tc
+1);
342 move a lump of memory from one talloc context to another return the
343 ptr on success, or NUL if it could not be transferred
345 void *talloc_steal(void *new_ctx
, void *ptr
)
347 struct talloc_chunk
*tc
, *new_tc
;
353 tc
= talloc_chunk_from_ptr(ptr
);
354 new_tc
= talloc_chunk_from_ptr(new_ctx
);
361 DLIST_REMOVE(tc
->parent
->child
, tc
);
362 if (tc
->parent
->child
) {
363 tc
->parent
->child
->parent
= tc
->parent
;
366 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
367 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
371 if (new_tc
->child
) new_tc
->child
->parent
= NULL
;
372 DLIST_ADD(new_tc
->child
, tc
);
378 return the total size of a talloc pool (subtree)
380 static off_t
talloc_total_size(void *ptr
)
383 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
386 for (c
=tc
->child
;c
;c
=c
->next
) {
387 total
+= talloc_total_size(c
+1);
393 return the total number of blocks in a talloc pool (subtree)
395 static off_t
talloc_total_blocks(void *ptr
)
398 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
401 for (c
=tc
->child
;c
;c
=c
->next
) {
402 total
+= talloc_total_blocks(c
+1);
408 report on memory usage by all children of a pointer
410 void talloc_report(void *ptr
, FILE *f
)
412 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
414 fprintf(f
,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
415 talloc_get_name(ptr
),
416 (unsigned long)talloc_total_size(ptr
),
417 (unsigned long)talloc_total_blocks(ptr
));
419 for (c
=tc
->child
;c
;c
=c
->next
) {
420 fprintf(f
, "\t%-30s contains %6lu bytes in %3lu blocks\n",
421 talloc_get_name(c
+1),
422 (unsigned long)talloc_total_size(c
+1),
423 (unsigned long)talloc_total_blocks(c
+1));
429 report on any memory hanging off the null context
431 static void talloc_report_all(void)
433 talloc_report(null_context
, stderr
);
437 enable leak reporting on exit
439 void talloc_enable_leak_check(void)
441 null_context
= talloc_named(NULL
, 0, "null_context");
442 atexit(talloc_report_all
);
446 talloc and zero memory.
448 void *talloc_zero(void *t
, size_t size
)
450 void *p
= talloc(t
, size
);
453 memset(p
, '\0', size
);
461 memdup with a talloc.
463 void *talloc_memdup(void *t
, const void *p
, size_t size
)
465 void *newp
= talloc(t
,size
);
468 memcpy(newp
, p
, size
);
477 char *talloc_strdup(void *t
, const char *p
)
482 return talloc_memdup(t
, p
, strlen(p
) + 1);
486 strndup with a talloc
488 char *talloc_strndup(void *t
, const char *p
, size_t n
)
490 size_t len
= strnlen(p
, n
);
493 ret
= talloc(t
, len
+ 1);
494 if (!ret
) { return NULL
; }
500 char *talloc_vasprintf(void *t
, const char *fmt
, va_list ap
) _PRINTF_ATTRIBUTE(2,0)
508 len
= vsnprintf(NULL
, 0, fmt
, ap2
);
510 ret
= talloc(t
, len
+1);
513 vsnprintf(ret
, len
+1, fmt
, ap2
);
521 Perform string formatting, and return a pointer to newly allocated
522 memory holding the result, inside a memory pool.
524 char *talloc_asprintf(void *t
, const char *fmt
, ...) _PRINTF_ATTRIBUTE(2,3)
530 ret
= talloc_vasprintf(t
, fmt
, ap
);
537 * Realloc @p s to append the formatted result of @p fmt and @p ap,
538 * and return @p s, which may have moved. Good for gradually
539 * accumulating output into a string buffer.
542 static char *talloc_vasprintf_append(char *s
,
543 const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
545 static char *talloc_vasprintf_append(char *s
,
546 const char *fmt
, va_list ap
)
558 len
= vsnprintf(NULL
, 0, fmt
, ap2
);
560 s
= talloc_realloc(s
, s_len
+ len
+1);
565 vsnprintf(s
+s_len
, len
+1, fmt
, ap2
);
571 Realloc @p s to append the formatted result of @p fmt and return @p
572 s, which may have moved. Good for gradually accumulating output
573 into a string buffer.
575 char *talloc_asprintf_append(char *s
,
576 const char *fmt
, ...) _PRINTF_ATTRIBUTE(2,3)
581 s
= talloc_vasprintf_append(s
, fmt
, ap
);
587 alloc an array, checking for integer overflow in the array size
589 void *talloc_array(void *ctx
, size_t el_size
, uint_t count
, const char *name
)
592 count
>= MAX_TALLOC_SIZE
/el_size
) {
595 return talloc_named_const(ctx
, el_size
* count
, name
);
600 realloc an array, checking for integer overflow in the array size
602 void *talloc_realloc_array(void *ptr
, size_t el_size
, uint_t count
, const char *name
)
605 count
>= MAX_TALLOC_SIZE
/el_size
) {
608 ptr
= talloc_realloc(ptr
, el_size
* count
);
610 talloc_set_name_const(ptr
, name
);
616 a alloc function for ldb that uses talloc
618 void *talloc_ldb_alloc(void *context
, void *ptr
, size_t size
)
621 return talloc(context
, size
);
627 return talloc_realloc(ptr
, size
);