1 /* Licensed under BSD-MIT - see LICENSE file for details */
2 #include <ccan/tal/tal.h>
3 #include <ccan/compiler/compiler.h>
4 #include <ccan/hash/hash.h>
5 #include <ccan/list/list.h>
15 /* How large should grouips get? */
16 #define GROUP_NODE_AVERAGE 32
18 /* 32-bit type field, first byte 0 in either endianness. */
20 CHILDREN = 0x00c1d500,
22 DESTRUCTOR = 0x00de5700,
28 struct prop_hdr *prop;
33 struct prop_hdr *next;
36 /* Unlike other properties, this is owned by parent, not child! */
38 struct prop_hdr hdr; /* GROUP */
39 struct list_head list; /* Head for child->group, node for others. */
40 /* We point to parent's children property, as it doesn't move! */
41 struct children *parent_child;
42 struct tal_hdr *first_child;
46 struct prop_hdr hdr; /* CHILDREN */
47 struct tal_hdr *parent;
48 /* We always have one group. Others may be added. */
53 struct prop_hdr hdr; /* DESTRUCTOR */
54 void (*destroy)(void *me);
58 struct prop_hdr hdr; /* NAME */
65 } null_parent = { { NULL, &null_parent.c.hdr },
69 { { &null_parent.c.group.list.n,
70 &null_parent.c.group.list.n } },
71 &null_parent.c, NULL } }
75 static void *(*allocfn)(size_t size) = malloc;
76 static void *(*resizefn)(void *, size_t size) = realloc;
77 static void (*freefn)(void *) = free;
78 static void (*errorfn)(const char *msg) = (void *)abort;
80 static inline void COLD call_error(const char *msg)
85 static bool get_destroying_bit(struct tal_hdr *next)
87 return (size_t)next & 1;
90 static void set_destroying_bit(struct tal_hdr **next)
92 *next = (void *)((size_t)next | 1);
95 static struct tal_hdr *ignore_destroying_bit(struct tal_hdr *next)
97 return (void *)((size_t)next & ~(size_t)1);
100 static struct group *next_group(struct group *group)
102 return list_entry(group->list.n.next, struct group, list.n);
105 static bool atexit_set = false;
106 /* This means valgrind can see leaks. */
107 static void unlink_null(void)
109 struct group *i, *next;
111 for (i = next_group(&null_parent.c.group);
112 i != &null_parent.c.group;
114 next = next_group(i);
117 null_parent.c.group.first_child = NULL;
121 static const void *bounds_start, *bounds_end;
123 static void update_bounds(const void *new)
125 if (unlikely(!bounds_start))
126 bounds_start = bounds_end = new;
127 else if (new < bounds_start)
129 else if (new > bounds_end)
133 static bool in_bounds(const void *p)
135 return !p || (p >= bounds_start && p <= bounds_end);
138 static void update_bounds(const void *new)
142 static bool in_bounds(const void *p)
148 static void check_bounds(const void *p)
151 call_error("Not a valid header");
154 static struct tal_hdr *to_tal_hdr(const void *ctx)
158 t = (struct tal_hdr *)((char *)ctx - sizeof(struct tal_hdr));
160 check_bounds(ignore_destroying_bit(t->next));
164 static struct tal_hdr *to_tal_hdr_or_null(const void *ctx)
167 return &null_parent.hdr;
168 return to_tal_hdr(ctx);
171 static void *from_tal_hdr(struct tal_hdr *hdr)
177 static void *from_tal_hdr_or_null(struct tal_hdr *hdr)
179 if (hdr == &null_parent.hdr)
181 return from_tal_hdr(hdr);
184 static struct tal_hdr *debug_tal(struct tal_hdr *tal)
186 tal_check(from_tal_hdr_or_null(tal), "TAL_DEBUG ");
190 static struct tal_hdr *debug_tal(struct tal_hdr *tal)
196 static void *allocate(size_t size)
200 /* Don't hand silly sizes to malloc. */
201 if (size >> (CHAR_BIT*sizeof(size) - 1)) {
202 call_error("allocation size overflow");
208 call_error("allocation failed");
214 /* We carefully start all real properties with a zero byte. */
215 static bool is_literal(const struct prop_hdr *prop)
217 return ((char *)prop)[0] != 0;
220 static struct prop_hdr **find_property_ptr(const struct tal_hdr *t,
225 for (p = (struct prop_hdr **)&t->prop; *p; p = &(*p)->next) {
226 if (is_literal(*p)) {
231 if ((*p)->type == type)
237 static void *find_property(const struct tal_hdr *parent, enum prop_type type)
239 struct prop_hdr **p = find_property_ptr(parent, type);
246 static void init_property(struct prop_hdr *hdr,
247 struct tal_hdr *parent,
251 hdr->next = parent->prop;
255 static struct destructor *add_destructor_property(struct tal_hdr *t,
256 void (*destroy)(void *))
258 struct destructor *prop = allocate(sizeof(*prop));
260 init_property(&prop->hdr, t, DESTRUCTOR);
261 prop->destroy = destroy;
266 static struct name *add_name_property(struct tal_hdr *t, const char *name)
270 prop = allocate(sizeof(*prop) + strlen(name) + 1);
272 init_property(&prop->hdr, t, NAME);
273 strcpy(prop->name, name);
278 static void init_group_property(struct group *group,
279 struct children *parent_child,
280 struct tal_hdr *child)
282 init_property(&group->hdr, child, GROUP);
283 group->parent_child = parent_child;
284 group->first_child = child;
287 static struct children *add_child_property(struct tal_hdr *parent,
288 struct tal_hdr *child)
290 struct children *prop = allocate(sizeof(*prop));
292 init_property(&prop->hdr, parent, CHILDREN);
293 prop->parent = parent;
295 init_group_property(&prop->group, prop, child);
296 list_head_init(&prop->group.list);
297 update_bounds(&prop->group);
302 static struct group *add_group_property(struct tal_hdr *child,
303 struct children *parent_child)
305 struct group *prop = allocate(sizeof(*prop));
307 init_group_property(prop, parent_child, child);
311 static bool add_child(struct tal_hdr *parent, struct tal_hdr *child)
314 struct children *children = find_property(parent, CHILDREN);
317 children = add_child_property(parent, child);
320 list_head_init(&children->group.list);
322 /* Child links to itself. */
327 /* Last one (may be children->group itself). */
328 group = next_group(&children->group);
330 /* Empty group can happen: null_parent, or all children freed. */
331 if (unlikely(!group->first_child)) {
332 assert(group == &children->group);
333 /* This hits on first child appended to null parent. */
334 if (unlikely(!atexit_set)) {
338 /* Link group into this child, make it the first one. */
339 group->hdr.next = child->prop;
340 child->prop = &group->hdr;
341 group->first_child = child;
343 /* Child links to itself. */
348 if (unlikely(hash_pointer(child, 0) % GROUP_NODE_AVERAGE == 0)) {
349 struct group *newgroup;
351 newgroup = add_group_property(child, children);
352 if (likely(newgroup)) {
353 list_add(&children->group.list, &newgroup->list.n);
355 /* Child links to itself. */
359 /* Fall through: on allocation failure reuse old group. */
362 /* We insert after head, otherwise we'd need to find end. */
363 child->next = group->first_child->next;
364 group->first_child->next = child;
368 static void del_tree(struct tal_hdr *t)
370 struct prop_hdr **prop, *p, *next;
372 /* Already being destroyed? Don't loop. */
373 if (unlikely(get_destroying_bit(t->next)))
376 set_destroying_bit(&t->next);
378 /* Carefully call destructors, removing as we go. */
379 while ((prop = find_property_ptr(t, DESTRUCTOR))) {
380 struct destructor *d = (struct destructor *)*prop;
381 d->destroy(from_tal_hdr(t));
386 /* Now free children and groups. */
387 prop = find_property_ptr(t, CHILDREN);
389 struct children *c = (struct children *)*prop;
390 struct group *group, *next;
394 next = next_group(group);
395 if (group->first_child) {
396 struct tal_hdr *i, *nextc;
398 i = group->first_child;
403 } while (i != group->first_child);
405 if (group != &c->group)
408 } while (group != &c->group);
411 /* Finally free our properties (groups are freed by parent). */
412 for (p = t->prop; p && !is_literal(p); p = next) {
414 if (p->type != GROUP)
420 void *tal_alloc_(const tal_t *ctx, size_t size, bool clear, const char *label)
422 struct tal_hdr *child, *parent = debug_tal(to_tal_hdr_or_null(ctx));
424 child = allocate(sizeof(struct tal_hdr) + size);
428 memset(from_tal_hdr(child), 0, size);
429 child->prop = (void *)label;
430 if (!add_child(parent, child)) {
435 return from_tal_hdr(debug_tal(child));
438 /* Update back ptrs, etc, as required.
439 * May return pointer to parent. */
440 static struct tal_hdr *remove_node(struct tal_hdr *t)
442 struct prop_hdr **prop;
443 struct tal_hdr *prev;
445 /* Loop around to find previous node. */
446 for (prev = t->next; prev->next != t; prev = prev->next);
448 /* Unlink ourselves. */
449 prev->next = t->next;
451 /* Are we the node with the group property? */
452 prop = find_property_ptr(t, GROUP);
454 struct group *group = (struct group *)*prop;
456 /* Are we the only one? */
458 struct children *c = group->parent_child;
459 /* Is this the group embedded in the child property? */
460 if (group == &c->group) {
461 group->first_child = NULL;
463 /* Empty group, so free it. */
464 list_del_from(&c->group.list, &group->list.n);
465 *prop = group->hdr.next;
470 /* Move property to next node. */
471 group->first_child = t->next;
473 *prop = group->hdr.next;
474 group->hdr.next = t->next->prop;
475 t->next->prop = &group->hdr;
481 void tal_free(const tal_t *ctx)
488 t = debug_tal(to_tal_hdr(ctx));
493 void *tal_steal_(const tal_t *new_parent, const tal_t *ctx)
496 struct tal_hdr *newpar, *t, *old_next, *old_parent;
498 newpar = debug_tal(to_tal_hdr_or_null(new_parent));
499 t = debug_tal(to_tal_hdr(ctx));
501 /* Save enough data to get us back if we fail! */
504 /* Unlink it from old parent. */
505 old_parent = remove_node(t);
506 if (unlikely(!add_child(newpar, t))) {
507 /* If we were last child, parent returned by
508 * remove_node, otherwise search old siblings
512 while (!(g = find_property(old_next, GROUP)))
513 old_next = old_next->next;
514 old_parent = g->parent_child->parent;
516 /* We can always add to old parent, becuase it has one
518 if (!add_child(old_parent, t))
527 bool tal_add_destructor_(tal_t *ctx, void (*destroy)(void *me))
529 return add_destructor_property(debug_tal(to_tal_hdr(ctx)), destroy);
532 bool tal_set_name_(tal_t *ctx, const char *name, bool literal)
534 struct tal_hdr *t = debug_tal(to_tal_hdr(ctx));
535 struct prop_hdr **prop = find_property_ptr(t, NAME);
537 /* Get rid of any old name */
539 struct name *name = (struct name *)*prop;
540 if (is_literal(&name->hdr))
543 *prop = name->hdr.next;
548 if (literal && name[0]) {
551 /* Append literal. */
552 for (p = &t->prop; *p && !is_literal(*p); p = &(*p)->next);
553 *p = (struct prop_hdr *)name;
556 if (!add_name_property(t, name))
562 const char *tal_name(const tal_t *t)
566 n = find_property(debug_tal(to_tal_hdr(t)), NAME);
570 if (is_literal(&n->hdr))
571 return (const char *)n;
575 /* Start one past first child: make stopping natural in circ. list. */
576 static struct tal_hdr *first_child(struct tal_hdr *parent)
578 struct children *child;
581 child = find_property(parent, CHILDREN);
585 /* Careful of empty group embedded in child property. */
586 if (child->group.first_child)
587 return child->group.first_child->next;
589 /* There could still be another group! */
590 group = next_group(&child->group);
591 if (group == &child->group)
594 return group->first_child->next;
597 tal_t *tal_first(const tal_t *root)
599 struct tal_hdr *c, *t = debug_tal(to_tal_hdr_or_null(root));
604 return from_tal_hdr(c);
607 tal_t *tal_next(const tal_t *root, const tal_t *prev)
609 struct tal_hdr *c, *t = debug_tal(to_tal_hdr(prev)), *top;
615 return from_tal_hdr(c);
617 top = to_tal_hdr_or_null(root);
621 /* Are we back to first child in group? */
622 group = find_property(t, GROUP);
624 return from_tal_hdr(t->next);
626 /* Last group is one inside children property. */
627 next = next_group(group);
628 if (next != &group->parent_child->group)
629 return from_tal_hdr(next->first_child->next);
631 /* OK, go back to parent. */
632 t = group->parent_child->parent;
638 tal_t *tal_parent(const tal_t *ctx)
646 t = debug_tal(to_tal_hdr(ctx));
648 while (!(group = find_property(t, GROUP)))
651 if (group->parent_child->parent == &null_parent.hdr)
653 return from_tal_hdr(group->parent_child->parent);
656 void *tal_realloc_(tal_t *ctx, size_t size)
658 struct tal_hdr *old_t, *t, **prev;
660 struct children *child;
662 old_t = debug_tal(to_tal_hdr(ctx));
664 t = resizefn(old_t, size + sizeof(struct tal_hdr));
666 call_error("Reallocation failure");
674 /* Fix up linked list pointer. */
675 for (prev = &t->next; *prev != old_t; prev = &(*prev)->next);
678 /* Fix up group pointer, if any. */
679 group = find_property(t, GROUP);
681 assert(group->first_child == old_t);
682 group->first_child = t;
685 /* Fix up child propertie's parent pointer. */
686 child = find_property(t, CHILDREN);
688 assert(child->parent == old_t);
692 return from_tal_hdr(debug_tal(t));
695 char *tal_strdup(const tal_t *ctx, const char *p)
697 return tal_memdup(ctx, p, strlen(p)+1);
700 char *tal_strndup(const tal_t *ctx, const char *p, size_t n)
706 ret = tal_memdup(ctx, p, n+1);
712 void *tal_memdup(const tal_t *ctx, const void *p, size_t n)
719 ret = tal_arr(ctx, char, n);
725 char *tal_asprintf(const tal_t *ctx, const char *fmt, ...)
731 ret = tal_vasprintf(ctx, fmt, ap);
737 char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
739 size_t max = strlen(fmt) * 2;
744 buf = tal_arr(tal_parent(fmt), char, max);
746 buf = tal_arr(ctx, char, max);
752 ret = vsnprintf(buf, max, fmt, ap2);
757 buf = tal_resize(buf, max *= 2);
764 void tal_set_backend(void *(*alloc_fn)(size_t size),
765 void *(*resize_fn)(void *, size_t size),
766 void (*free_fn)(void *),
767 void (*error_fn)(const char *msg))
772 resizefn = resize_fn;
779 #ifdef CCAN_TAL_DEBUG
780 static void dump_node(unsigned int indent, const struct tal_hdr *t)
783 const struct prop_hdr *p;
785 for (i = 0; i < indent; i++)
788 for (p = t->prop; p; p = p->next) {
791 struct destructor *d;
794 printf(" \"%s\"", (const char *)p);
799 c = (struct children *)p;
800 printf(" CHILDREN(%p):parent=%p,group=%p\n",
801 p, c->parent, &c->group);
803 printf(" GROUP(%p):list={%p,%p},parent_ch=%p,first=%p",
804 g, g->list.n.next, g->list.n.next,
805 g->parent_child, g->first_child);
808 g = (struct group *)p;
809 printf(" GROUP(%p):list={%p,%p},,parent_ch=%p,first=%p",
810 p, g->list.n.next, g->list.n.next,
811 g->parent_child, g->first_child);
814 d = (struct destructor *)p;
815 printf(" DESTRUCTOR(%p):fn=%p", p, d->destroy);
818 n = (struct name *)p;
819 printf(" NAME(%p):%s", p, n->name);
822 printf(" **UNKNOWN(%p):%i**", p, p->type);
828 static void tal_dump_(unsigned int level, const struct tal_hdr *t)
830 struct children *children;
835 children = find_property(t, CHILDREN);
839 group = &children->group;
843 i = group->first_child;
846 tal_dump_(level+1, i);
848 } while (i != group->first_child);
850 group = next_group(group);
851 } while (group != &children->group);
856 tal_dump_(0, &null_parent.hdr);
858 #endif /* CCAN_TAL_DEBUG */
861 static bool check_err(struct tal_hdr *t, const char *errorstr,
865 /* Try not to malloc: it may be corrupted. */
866 char msg[strlen(errorstr) + 20 + strlen(errmsg) + 1];
867 sprintf(msg, "%s:%p %s", errorstr, from_tal_hdr(t), errmsg);
873 static bool check_group(struct group *group,
874 struct tal_hdr *t, const char *errorstr);
876 static bool check_node(struct group *group,
877 struct tal_hdr *t, const char *errorstr)
880 struct name *name = NULL;
881 struct children *children = NULL;
882 struct group *gr = NULL;
884 if (t != &null_parent.hdr && !in_bounds(t))
885 return check_err(t, errorstr, "invalid pointer");
887 for (p = t->prop; p; p = p->next) {
890 return check_err(t, errorstr,
891 "has extra literal");
892 name = (struct name *)p;
895 if (p != &null_parent.c.hdr && p != &null_parent.c.group.hdr
897 return check_err(t, errorstr,
898 "has bad property pointer");
903 return check_err(t, errorstr,
905 gr = (struct group *)p;
909 return check_err(t, errorstr,
910 "has two child nodes");
911 children = (struct children *)p;
917 return check_err(t, errorstr,
919 name = (struct name *)p;
922 return check_err(t, errorstr, "has unknown property");
925 if (group && gr != group)
926 return check_err(t, errorstr, "has bad group");
929 if (!list_check(&children->group.list, errorstr))
931 gr = &children->group;
933 if (gr->first_child) {
934 if (!check_group(gr, gr->first_child, errorstr))
936 } else if (gr != &children->group) {
937 /* Empty groups should be deleted! */
938 return check_err(t, errorstr,
942 } while (gr != &children->group);
947 static bool check_group(struct group *group,
948 struct tal_hdr *t, const char *errorstr)
954 if (!check_node(group, i, errorstr))
962 bool tal_check(const tal_t *ctx, const char *errorstr)
964 struct tal_hdr *t = to_tal_hdr_or_null(ctx);
966 return check_node(NULL, t, errorstr);
969 bool tal_check(const tal_t *ctx, const char *errorstr)