Commit 12aab84a authored by Philip Langdale's avatar Philip Langdale

xtalloc: Re-prefix all ta_* symbols to xta_*

xtalloc was copied from mpv, which means that we see symbol
collisions if libplacebo is statically linked into mpv. So
use an `xta_` prefix for all the functions. In practice, this
has almost no effect on the consuming code because everything
is accessed via macros.
parent 4912e344
Pipeline #6461 passed with stages
in 1 minute and 33 seconds
...@@ -39,7 +39,7 @@ enum pl_shader_buf { ...@@ -39,7 +39,7 @@ enum pl_shader_buf {
struct pl_shader { struct pl_shader {
struct pl_context *ctx; struct pl_context *ctx;
struct pl_shader_res res; // for accumulating vertex_attribs etc. struct pl_shader_res res; // for accumulating vertex_attribs etc.
struct ta_ref *tmp; struct xta_ref *tmp;
bool failed; bool failed;
bool mutable; bool mutable;
int output_w; int output_w;
......
...@@ -24,78 +24,78 @@ ...@@ -24,78 +24,78 @@
// Note: all talloc wrappers are wired to the "x" functions, which abort on OOM. // Note: all talloc wrappers are wired to the "x" functions, which abort on OOM.
// libtalloc doesn't do that, but the mplayer2/mpv internal copies of it did. // libtalloc doesn't do that, but the mplayer2/mpv internal copies of it did.
#define talloc ta_xnew #define talloc xta_xnew
#define talloc_zero ta_xznew #define talloc_zero xta_xznew
#define talloc_array ta_xnew_array #define talloc_array xta_xnew_array
#define talloc_zero_array ta_xznew_array #define talloc_zero_array xta_xznew_array
#define talloc_array_size ta_xnew_array_size #define talloc_array_size xta_xnew_array_size
#define talloc_realloc ta_xrealloc #define talloc_realloc xta_xrealloc
#define talloc_ptrtype ta_xnew_ptrtype #define talloc_ptrtype xta_xnew_ptrtype
#define talloc_array_ptrtype ta_xnew_array_ptrtype #define talloc_array_ptrtype xta_xnew_array_ptrtype
#define talloc_steal ta_xsteal #define talloc_steal xta_xsteal
#define talloc_realloc_size ta_xrealloc_size #define talloc_realloc_size xta_xrealloc_size
#define talloc_new ta_xnew_context #define talloc_new xta_xnew_context
#define talloc_set_destructor ta_xset_destructor #define talloc_set_destructor xta_xset_destructor
#define talloc_parent ta_find_parent #define talloc_parent xta_find_parent
#define talloc_enable_leak_report ta_enable_leak_report #define talloc_enable_leak_report xta_enable_leak_report
#define talloc_print_leak_report ta_print_leak_report #define talloc_print_leak_report xta_print_leak_report
#define talloc_size ta_xalloc_size #define talloc_size xta_xalloc_size
#define talloc_zero_size ta_xzalloc_size #define talloc_zero_size xta_xzalloc_size
#define talloc_get_size ta_get_size #define talloc_get_size xta_get_size
#define talloc_free_children ta_free_children #define talloc_free_children xta_free_children
#define talloc_free ta_free #define talloc_free xta_free
#define talloc_memdup ta_xmemdup #define talloc_memdup xta_xmemdup
#define talloc_strdup ta_xstrdup #define talloc_strdup xta_xstrdup
#define talloc_strndup ta_xstrndup #define talloc_strndup xta_xstrndup
#define talloc_ptrdup ta_xdup_ptrtype #define talloc_ptrdup xta_xdup_ptrtype
#define talloc_asprintf ta_xasprintf #define talloc_asprintf xta_xasprintf
#define talloc_vasprintf ta_xvasprintf #define talloc_vasprintf xta_xvasprintf
// Don't define linker-level symbols, as that would clash with real libtalloc. // Don't define linker-level symbols, as that would clash with real libtalloc.
#define talloc_strdup_append ta_talloc_strdup_append #define talloc_strdup_append xta_talloc_strdup_append
#define talloc_strdup_append_buffer ta_talloc_strdup_append_buffer #define talloc_strdup_append_buffer xta_talloc_strdup_append_buffer
#define talloc_strndup_append ta_talloc_strndup_append #define talloc_strndup_append xta_talloc_strndup_append
#define talloc_strndup_append_buffer ta_talloc_strndup_append_buffer #define talloc_strndup_append_buffer xta_talloc_strndup_append_buffer
#define talloc_vasprintf_append ta_talloc_vasprintf_append #define talloc_vasprintf_append xta_talloc_vasprintf_append
#define talloc_vasprintf_append_buffer ta_talloc_vasprintf_append_buffer #define talloc_vasprintf_append_buffer xta_talloc_vasprintf_append_buffer
#define talloc_asprintf_append ta_talloc_asprintf_append #define talloc_asprintf_append xta_talloc_asprintf_append
#define talloc_asprintf_append_buffer ta_talloc_asprintf_append_buffer #define talloc_asprintf_append_buffer xta_talloc_asprintf_append_buffer
char *ta_talloc_strdup(void *t, const char *p); char *xta_talloc_strdup(void *t, const char *p);
char *ta_talloc_strdup_append(char *s, const char *a); char *xta_talloc_strdup_append(char *s, const char *a);
char *ta_talloc_strdup_append_buffer(char *s, const char *a); char *xta_talloc_strdup_append_buffer(char *s, const char *a);
char *ta_talloc_strndup(void *t, const char *p, size_t n); char *xta_talloc_strndup(void *t, const char *p, size_t n);
char *ta_talloc_strndup_append(char *s, const char *a, size_t n); char *xta_talloc_strndup_append(char *s, const char *a, size_t n);
char *ta_talloc_strndup_append_buffer(char *s, const char *a, size_t n); char *xta_talloc_strndup_append_buffer(char *s, const char *a, size_t n);
char *ta_talloc_vasprintf_append(char *s, const char *fmt, va_list ap) TA_PRF(2, 0); char *xta_talloc_vasprintf_append(char *s, const char *fmt, va_list ap) TA_PRF(2, 0);
char *ta_talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) TA_PRF(2, 0); char *xta_talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) TA_PRF(2, 0);
char *ta_talloc_asprintf_append(char *s, const char *fmt, ...) TA_PRF(2, 3); char *xta_talloc_asprintf_append(char *s, const char *fmt, ...) TA_PRF(2, 3);
char *ta_talloc_asprintf_append_buffer(char *s, const char *fmt, ...) TA_PRF(2, 3); char *xta_talloc_asprintf_append_buffer(char *s, const char *fmt, ...) TA_PRF(2, 3);
// Talloc refcounting // Talloc refcounting
struct ta_ref; struct xta_ref;
// ta_ref_deref will free the ref and all of its children as soon as the // xta_ref_deref will free the ref and all of its children as soon as the
// internal refcount reaches 0 // internal refcount reaches 0
struct ta_ref *ta_ref_new(void *t); struct xta_ref *xta_ref_new(void *t);
struct ta_ref *ta_ref_dup(struct ta_ref *ref); struct xta_ref *xta_ref_dup(struct xta_ref *ref);
void ta_ref_deref(struct ta_ref **ref); void xta_ref_deref(struct xta_ref **ref);
// Attaches a reference as a child of another talloc ctx, such that freeing // Attaches a reference as a child of another talloc ctx, such that freeing
// `t` is like dereferencing the ta_ref. // `t` is like dereferencing the xta_ref.
bool ta_ref_attach(void *t, struct ta_ref *ref); bool xta_ref_attach(void *t, struct xta_ref *ref);
#define talloc_ref_new(...) ta_oom_p(ta_ref_new(__VA_ARGS__)) #define talloc_ref_new(...) xta_oom_p(xta_ref_new(__VA_ARGS__))
#define talloc_ref_dup(...) ta_oom_p(ta_ref_dup(__VA_ARGS__)) #define talloc_ref_dup(...) xta_oom_p(xta_ref_dup(__VA_ARGS__))
#define talloc_ref_deref(...) ta_ref_deref(__VA_ARGS__) #define talloc_ref_deref(...) xta_ref_deref(__VA_ARGS__)
#define talloc_ref_attach(...) ta_oom_b(ta_ref_attach(__VA_ARGS__)) #define talloc_ref_attach(...) xta_oom_b(xta_ref_attach(__VA_ARGS__))
// Utility functions (ported from mpv) // Utility functions (ported from mpv)
...@@ -107,15 +107,15 @@ bool ta_ref_attach(void *t, struct ta_ref *ref); ...@@ -107,15 +107,15 @@ bool ta_ref_attach(void *t, struct ta_ref *ref);
#define TARRAY_RESIZE(ctx, p, count) \ #define TARRAY_RESIZE(ctx, p, count) \
do { \ do { \
(p) = ta_xrealloc_size(ctx, p, \ (p) = xta_xrealloc_size(ctx, p, \
ta_calc_array_size(sizeof((p)[0]), count)); \ xta_calc_array_size(sizeof((p)[0]), count)); \
} while (0) } while (0)
#define TARRAY_GROW(ctx, p, nextidx) \ #define TARRAY_GROW(ctx, p, nextidx) \
do { \ do { \
size_t nextidx_ = (nextidx); \ size_t nextidx_ = (nextidx); \
if (nextidx_ >= TALLOC_AVAIL(p)) \ if (nextidx_ >= TALLOC_AVAIL(p)) \
TARRAY_RESIZE(ctx, p, ta_calc_prealloc_elems(nextidx_)); \ TARRAY_RESIZE(ctx, p, xta_calc_prealloc_elems(nextidx_)); \
assert(p); \ assert(p); \
} while (0) } while (0)
......
...@@ -29,16 +29,16 @@ ...@@ -29,16 +29,16 @@
#define TA_MEMORY_DEBUGGING #define TA_MEMORY_DEBUGGING
#endif #endif
struct ta_header { struct xta_header {
size_t size; // size of the user allocation size_t size; // size of the user allocation
struct ta_header *prev; // ring list containing siblings struct xta_header *prev; // ring list containing siblings
struct ta_header *next; struct xta_header *next;
struct ta_ext_header *ext; struct xta_ext_header *ext;
#ifdef TA_MEMORY_DEBUGGING #ifdef TA_MEMORY_DEBUGGING
unsigned int canary; unsigned int canary;
struct ta_header *leak_next; struct xta_header *leak_next;
struct ta_header *leak_prev; struct xta_header *leak_prev;
const char *name; const char *name;
#endif #endif
}; };
...@@ -46,13 +46,13 @@ struct ta_header { ...@@ -46,13 +46,13 @@ struct ta_header {
#define CANARY 0xD3ADB3EF #define CANARY 0xD3ADB3EF
union aligned_header { union aligned_header {
struct ta_header ta; struct xta_header ta;
// Make sure to satisfy typical alignment requirements // Make sure to satisfy typical alignment requirements
void *align_ptr; void *align_ptr;
int align_int; int align_int;
double align_d; double align_d;
long long align_ll; long long align_ll;
char align_min[(sizeof(struct ta_header) + MIN_ALIGN - 1) & ~(MIN_ALIGN - 1)]; char align_min[(sizeof(struct xta_header) + MIN_ALIGN - 1) & ~(MIN_ALIGN - 1)];
}; };
#define PTR_TO_HEADER(ptr) (&((union aligned_header *)(ptr) - 1)->ta) #define PTR_TO_HEADER(ptr) (&((union aligned_header *)(ptr) - 1)->ta)
...@@ -61,41 +61,41 @@ union aligned_header { ...@@ -61,41 +61,41 @@ union aligned_header {
#define MAX_ALLOC (((size_t)-1) - sizeof(union aligned_header)) #define MAX_ALLOC (((size_t)-1) - sizeof(union aligned_header))
// Needed for non-leaf allocations, or extended features such as destructors. // Needed for non-leaf allocations, or extended features such as destructors.
struct ta_ext_header { struct xta_ext_header {
struct ta_header *header; // points back to normal header struct xta_header *header; // points back to normal header
struct ta_header children; // list of children, with this as sentinel struct xta_header children; // list of children, with this as sentinel
void (*destructor)(void *); void (*destructor)(void *);
}; };
// ta_ext_header.children.size is set to this // xta_ext_header.children.size is set to this
#define CHILDREN_SENTINEL ((size_t)-1) #define CHILDREN_SENTINEL ((size_t)-1)
static void ta_dbg_add(struct ta_header *h); static void xta_dbg_add(struct xta_header *h);
static void ta_dbg_check_header(struct ta_header *h); static void xta_dbg_check_header(struct xta_header *h);
static void ta_dbg_remove(struct ta_header *h); static void xta_dbg_remove(struct xta_header *h);
static struct ta_header *get_header(void *ptr) static struct xta_header *get_header(void *ptr)
{ {
struct ta_header *h = ptr ? PTR_TO_HEADER(ptr) : NULL; struct xta_header *h = ptr ? PTR_TO_HEADER(ptr) : NULL;
ta_dbg_check_header(h); xta_dbg_check_header(h);
return h; return h;
} }
static struct ta_ext_header *get_or_alloc_ext_header(void *ptr) static struct xta_ext_header *get_or_alloc_ext_header(void *ptr)
{ {
struct ta_header *h = get_header(ptr); struct xta_header *h = get_header(ptr);
if (!h) if (!h)
return NULL; return NULL;
if (!h->ext) { if (!h->ext) {
h->ext = malloc(sizeof(struct ta_ext_header)); h->ext = malloc(sizeof(struct xta_ext_header));
if (!h->ext) if (!h->ext)
return NULL; return NULL;
*h->ext = (struct ta_ext_header) { *h->ext = (struct xta_ext_header) {
.header = h, .header = h,
.children = { .children = {
.next = &h->ext->children, .next = &h->ext->children,
.prev = &h->ext->children, .prev = &h->ext->children,
// Needed by ta_find_parent(): // Needed by xta_find_parent():
.size = CHILDREN_SENTINEL, .size = CHILDREN_SENTINEL,
.ext = h->ext, .ext = h->ext,
}, },
...@@ -109,17 +109,17 @@ static struct ta_ext_header *get_or_alloc_ext_header(void *ptr) ...@@ -109,17 +109,17 @@ static struct ta_ext_header *get_or_alloc_ext_header(void *ptr)
* parent of ptr. Operations ptr==NULL always succeed and do nothing. * parent of ptr. Operations ptr==NULL always succeed and do nothing.
* Returns true on success, false on OOM. * Returns true on success, false on OOM.
* *
* Warning: if ta_parent is a direct or indirect child of ptr, things will go * Warning: if xta_parent is a direct or indirect child of ptr, things will go
* wrong. The function will apparently succeed, but creates circular * wrong. The function will apparently succeed, but creates circular
* parent links, which are not allowed. * parent links, which are not allowed.
*/ */
bool ta_set_parent(void *ptr, void *ta_parent) bool xta_set_parent(void *ptr, void *xta_parent)
{ {
struct ta_header *ch = get_header(ptr); struct xta_header *ch = get_header(ptr);
if (!ch) if (!ch)
return true; return true;
struct ta_ext_header *parent_eh = get_or_alloc_ext_header(ta_parent); struct xta_ext_header *parent_eh = get_or_alloc_ext_header(xta_parent);
if (ta_parent && !parent_eh) // do nothing on OOM if (xta_parent && !parent_eh) // do nothing on OOM
return false; return false;
// Unlink from previous parent // Unlink from previous parent
if (ch->next) { if (ch->next) {
...@@ -129,7 +129,7 @@ bool ta_set_parent(void *ptr, void *ta_parent) ...@@ -129,7 +129,7 @@ bool ta_set_parent(void *ptr, void *ta_parent)
} }
// Link to new parent - insert at end of list (possibly orders destructors) // Link to new parent - insert at end of list (possibly orders destructors)
if (parent_eh) { if (parent_eh) {
struct ta_header *children = &parent_eh->children; struct xta_header *children = &parent_eh->children;
ch->next = children; ch->next = children;
ch->prev = children->prev; ch->prev = children->prev;
children->prev->next = ch; children->prev->next = ch;
...@@ -138,43 +138,43 @@ bool ta_set_parent(void *ptr, void *ta_parent) ...@@ -138,43 +138,43 @@ bool ta_set_parent(void *ptr, void *ta_parent)
return true; return true;
} }
/* Allocate size bytes of memory. If ta_parent is not NULL, this is used as /* Allocate size bytes of memory. If xta_parent is not NULL, this is used as
* parent allocation (if ta_parent is freed, this allocation is automatically * parent allocation (if xta_parent is freed, this allocation is automatically
* freed as well). size==0 allocates a block of size 0 (i.e. returns non-NULL). * freed as well). size==0 allocates a block of size 0 (i.e. returns non-NULL).
* Returns NULL on OOM. * Returns NULL on OOM.
*/ */
void *ta_alloc_size(void *ta_parent, size_t size) void *xta_alloc_size(void *xta_parent, size_t size)
{ {
if (size >= MAX_ALLOC) if (size >= MAX_ALLOC)
return NULL; return NULL;
struct ta_header *h = malloc(sizeof(union aligned_header) + size); struct xta_header *h = malloc(sizeof(union aligned_header) + size);
if (!h) if (!h)
return NULL; return NULL;
*h = (struct ta_header) {.size = size}; *h = (struct xta_header) {.size = size};
ta_dbg_add(h); xta_dbg_add(h);
void *ptr = PTR_FROM_HEADER(h); void *ptr = PTR_FROM_HEADER(h);
if (!ta_set_parent(ptr, ta_parent)) { if (!xta_set_parent(ptr, xta_parent)) {
ta_free(ptr); xta_free(ptr);
return NULL; return NULL;
} }
return ptr; return ptr;
} }
/* Exactly the same as ta_alloc_size(), but the returned memory block is /* Exactly the same as xta_alloc_size(), but the returned memory block is
* initialized to 0. * initialized to 0.
*/ */
void *ta_zalloc_size(void *ta_parent, size_t size) void *xta_zalloc_size(void *xta_parent, size_t size)
{ {
if (size >= MAX_ALLOC) if (size >= MAX_ALLOC)
return NULL; return NULL;
struct ta_header *h = calloc(1, sizeof(union aligned_header) + size); struct xta_header *h = calloc(1, sizeof(union aligned_header) + size);
if (!h) if (!h)
return NULL; return NULL;
*h = (struct ta_header) {.size = size}; *h = (struct xta_header) {.size = size};
ta_dbg_add(h); xta_dbg_add(h);
void *ptr = PTR_FROM_HEADER(h); void *ptr = PTR_FROM_HEADER(h);
if (!ta_set_parent(ptr, ta_parent)) { if (!xta_set_parent(ptr, xta_parent)) {
ta_free(ptr); xta_free(ptr);
return NULL; return NULL;
} }
return ptr; return ptr;
...@@ -184,31 +184,31 @@ void *ta_zalloc_size(void *ta_parent, size_t size) ...@@ -184,31 +184,31 @@ void *ta_zalloc_size(void *ta_parent, size_t size)
* realloc(), the returned pointer can be different, and on OOM, NULL is * realloc(), the returned pointer can be different, and on OOM, NULL is
* returned. * returned.
* *
* size==0 is equivalent to ta_free(ptr). * size==0 is equivalent to xta_free(ptr).
* ptr==NULL is equivalent to ta_alloc_size(ta_parent, size). * ptr==NULL is equivalent to xta_alloc_size(xta_parent, size).
* *
* ta_parent is used only in the ptr==NULL case. * xta_parent is used only in the ptr==NULL case.
* *
* Returns NULL if the operation failed. * Returns NULL if the operation failed.
* NULL is also returned if size==0. * NULL is also returned if size==0.
*/ */
void *ta_realloc_size(void *ta_parent, void *ptr, size_t size) void *xta_realloc_size(void *xta_parent, void *ptr, size_t size)
{ {
if (size >= MAX_ALLOC) if (size >= MAX_ALLOC)
return NULL; return NULL;
if (!size) { if (!size) {
ta_free(ptr); xta_free(ptr);
return NULL; return NULL;
} }
if (!ptr) if (!ptr)
return ta_alloc_size(ta_parent, size); return xta_alloc_size(xta_parent, size);
struct ta_header *h = get_header(ptr); struct xta_header *h = get_header(ptr);
struct ta_header *old_h = h; struct xta_header *old_h = h;
if (h->size == size) if (h->size == size)
return ptr; return ptr;
ta_dbg_remove(h); xta_dbg_remove(h);
h = realloc(h, sizeof(union aligned_header) + size); h = realloc(h, sizeof(union aligned_header) + size);
ta_dbg_add(h ? h : old_h); xta_dbg_add(h ? h : old_h);
if (!h) if (!h)
return NULL; return NULL;
h->size = size; h->size = size;
...@@ -229,53 +229,53 @@ void *ta_realloc_size(void *ta_parent, void *ptr, size_t size) ...@@ -229,53 +229,53 @@ void *ta_realloc_size(void *ta_parent, void *ptr, size_t size)
} }
/* Return the allocated size of ptr. This returns the size parameter of the /* Return the allocated size of ptr. This returns the size parameter of the
* most recent ta_alloc.../ta_realloc... call. * most recent xta_alloc.../xta_realloc... call.
* If ptr==NULL, return 0. * If ptr==NULL, return 0.
*/ */
size_t ta_get_size(void *ptr) size_t xta_get_size(void *ptr)
{ {
struct ta_header *h = get_header(ptr); struct xta_header *h = get_header(ptr);
return h ? h->size : 0; return h ? h->size : 0;
} }
/* Free all allocations that (recursively) have ptr as parent allocation, but /* Free all allocations that (recursively) have ptr as parent allocation, but
* do not free ptr itself. * do not free ptr itself.
*/ */
void ta_free_children(void *ptr) void xta_free_children(void *ptr)
{ {
struct ta_header *h = get_header(ptr); struct xta_header *h = get_header(ptr);
struct ta_ext_header *eh = h ? h->ext : NULL; struct xta_ext_header *eh = h ? h->ext : NULL;
if (!eh) if (!eh)
return; return;
while (eh->children.next != &eh->children) { while (eh->children.next != &eh->children) {
struct ta_header *next = eh->children.next; struct xta_header *next = eh->children.next;
ta_free(PTR_FROM_HEADER(next)); xta_free(PTR_FROM_HEADER(next));
assert(eh->children.next != next); assert(eh->children.next != next);
} }
} }
/* Free the given allocation, and all of its direct and indirect children. /* Free the given allocation, and all of its direct and indirect children.
*/ */
void ta_free(void *ptr) void xta_free(void *ptr)
{ {
struct ta_header *h = get_header(ptr); struct xta_header *h = get_header(ptr);
if (!h) if (!h)
return; return;
if (h->ext && h->ext->destructor) if (h->ext && h->ext->destructor)
h->ext->destructor(ptr); h->ext->destructor(ptr);
ta_free_children(ptr); xta_free_children(ptr);
if (h->next) { if (h->next) {
// Unlink from sibling list // Unlink from sibling list
h->next->prev = h->prev; h->next->prev = h->prev;
h->prev->next = h->next; h->prev->next = h->next;
} }
ta_dbg_remove(h); xta_dbg_remove(h);
free(h->ext); free(h->ext);
free(h); free(h);
} }
/* Set a destructor that is to be called when the given allocation is freed. /* Set a destructor that is to be called when the given allocation is freed.
* (Whether the allocation is directly freed with ta_free() or indirectly by * (Whether the allocation is directly freed with xta_free() or indirectly by
* freeing its parent does not matter.) There is only one destructor. If an * freeing its parent does not matter.) There is only one destructor. If an
* destructor was already set, it's overwritten. * destructor was already set, it's overwritten.
* *
...@@ -286,9 +286,9 @@ void ta_free(void *ptr) ...@@ -286,9 +286,9 @@ void ta_free(void *ptr)
* *
* Returns false if ptr==NULL, or on OOM. * Returns false if ptr==NULL, or on OOM.
*/ */
bool ta_set_destructor(void *ptr, void (*destructor)(void *)) bool xta_set_destructor(void *ptr, void (*destructor)(void *))
{ {
struct ta_ext_header *eh = get_or_alloc_ext_header(ptr); struct xta_ext_header *eh = get_or_alloc_ext_header(ptr);
if (!eh) if (!eh)
return false; return false;
eh->destructor = destructor; eh->destructor = destructor;
...@@ -299,12 +299,12 @@ bool ta_set_destructor(void *ptr, void (*destructor)(void *)) ...@@ -299,12 +299,12 @@ bool ta_set_destructor(void *ptr, void (*destructor)(void *))
* *
* Warning: this has O(N) runtime complexity with N sibling allocations! * Warning: this has O(N) runtime complexity with N sibling allocations!
*/ */
void *ta_find_parent(void *ptr) void *xta_find_parent(void *ptr)
{ {
struct ta_header *h = get_header(ptr); struct xta_header *h = get_header(ptr);
if (!h || !h->next) if (!h || !h->next)
return NULL; return NULL;
for (struct ta_header *cur = h->next; cur != h; cur = cur->next) { for (struct xta_header *cur = h->next; cur != h; cur = cur->next) {
if (cur->size == CHILDREN_SENTINEL) if (cur->size == CHILDREN_SENTINEL)
return PTR_FROM_HEADER(cur->ext->header); return PTR_FROM_HEADER(cur->ext->header);
} }
...@@ -315,60 +315,60 @@ void *ta_find_parent(void *ptr) ...@@ -315,60 +315,60 @@ void *ta_find_parent(void *ptr)
#include <pthread.h> #include <pthread.h>
static pthread_mutex_t ta_dbg_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t xta_dbg_mutex = PTHREAD_MUTEX_INITIALIZER;
static bool enable_leak_check; // pretty much constant static bool enable_leak_check; // pretty much constant
static struct ta_header leak_node; static struct xta_header leak_node;
static char allocation_is_string; static char allocation_is_string;
static void ta_dbg_add(struct ta_header *h) static void xta_dbg_add(struct xta_header *h)
{ {
h->canary = CANARY; h->canary = CANARY;
if (enable_leak_check) { if (enable_leak_check) {
pthread_mutex_lock(&ta_dbg_mutex); pthread_mutex_lock(&xta_dbg_mutex);
h->leak_next = &leak_node; h->leak_next = &leak_node;
h->leak_prev = leak_node.leak_prev; h->leak_prev = leak_node.leak_prev;
leak_node.leak_prev->leak_next = h; leak_node.leak_prev->leak_next = h;
leak_node.leak_prev = h; leak_node.leak_prev = h;
pthread_mutex_unlock(&ta_dbg_mutex); pthread_mutex_unlock(&xta_dbg_mutex);
} }
} }
static void ta_dbg_check_header(struct ta_header *h) static void xta_dbg_check_header(struct xta_header *h)
{ {
if (h) if (h)
assert(h->canary == CANARY); assert(h->canary == CANARY);
} }
static void ta_dbg_remove(struct ta_header *h) static void xta_dbg_remove(struct xta_header *h)
{ {
ta_dbg_check_header(h); xta_dbg_check_header(h);
if (h->leak_next) { // assume checking for !=NULL invariant ok without lock if (h->leak_next) { // assume checking for !=NULL invariant ok without lock
pthread_mutex_lock(&ta_dbg_mutex); pthread_mutex_lock(&xta_dbg_mutex);
h->leak_next->leak_prev = h->leak_prev; h->leak_next->leak_prev = h->leak_prev;
h->leak_prev->leak_next = h->leak_next; h->leak_prev->leak_next = h->leak_next;
pthread_mutex_unlock(&ta_dbg_mutex); pthread_mutex_unlock(&xta_dbg_mutex);
h->leak_next = h->leak_prev = NULL; h->leak_next = h->leak_prev = NULL;
} }
h->canary = 0; h->canary = 0;
} }
static size_t get_children_size(struct ta_header *h) static size_t get_children_size(struct xta_header *h)
{ {
size_t size = 0; size_t size = 0;
if (h->ext) { if (h->ext) {
struct ta_header *s; struct xta_header *s;
for (s = h->ext->children.next; s != &h->ext->children; s = s->next) for (s = h->ext->children.next; s != &h->ext->children; s = s->next)
size += s->size + get_children_size(s); size += s->size + get_children_size(s);
} }
return size; return size;
} }
void ta_print_leak_report(void) void xta_print_leak_report(void)
{ {
if (!enable_leak_check) if (!enable_leak_check)
return; return;
pthread_mutex_lock(&ta_dbg_mutex); pthread_mutex_lock(&xta_dbg_mutex);
if (leak_node.leak_next && leak_node.leak_next != &leak_node) { if (leak_node.leak_next && leak_node.leak_next != &leak_node) {
size_t size = 0;