1 /* CC0 (Public domain) - see LICENSE file for details */
2 #include <ccan/take/take.h>
3 #include <ccan/likely/likely.h>
8 static const void **takenarr;
9 static const char **labelarr;
10 static size_t max_taken, num_taken;
11 static size_t allocfail;
12 static void (*allocfailfn)(const void *p);
14 void *take_(const void *p, const char *label)
16 /* Overallocate: it's better than risking calloc returning NULL! */
17 if (unlikely(label && !labelarr))
18 labelarr = calloc(max_taken+1, sizeof(*labelarr));
20 if (unlikely(num_taken == max_taken)) {
23 new = realloc(takenarr, sizeof(*takenarr) * (max_taken+1));
30 /* Otherwise we leak p. */
34 /* Once labelarr is set, we maintain it. */
36 const char **labelarr_new;
37 labelarr_new = realloc(labelarr,
38 sizeof(*labelarr) * (max_taken+1));
40 labelarr = labelarr_new;
42 /* num_taken will be out of sync with the size of
43 * labelarr after realloc failure.
44 * Just pretend that we never had labelarr allocated. */
51 if (unlikely(labelarr))
52 labelarr[num_taken] = label;
53 takenarr[num_taken++] = p;
58 static size_t find_taken(const void *p)
62 for (i = 0; i < num_taken; i++) {
69 bool taken(const void *p)
73 if (!p && unlikely(allocfail)) {
82 memmove(&takenarr[i-1], &takenarr[i],
83 (--num_taken - (i - 1))*sizeof(takenarr[0]));
87 bool is_taken(const void *p)
89 if (!p && unlikely(allocfail))
92 return find_taken(p) > 0;
95 const char *taken_any(void)
97 static char pointer_buf[32];
102 /* We're *allowed* to have some with labels, some without. */
105 for (i = 0; i < num_taken; i++)
110 sprintf(pointer_buf, "%p", takenarr[0]);
114 void take_cleanup(void)
116 max_taken = num_taken = 0;
123 void take_allocfail(void (*fn)(const void *p))