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 labelarr = realloc(labelarr,
37 sizeof(*labelarr) * (max_taken+1));
40 if (unlikely(labelarr))
41 labelarr[num_taken] = label;
42 takenarr[num_taken++] = p;
47 static size_t find_taken(const void *p)
51 for (i = 0; i < num_taken; i++) {
58 bool taken(const void *p)
62 if (!p && unlikely(allocfail)) {
71 memmove(&takenarr[i-1], &takenarr[i],
72 (--num_taken - (i - 1))*sizeof(takenarr[0]));
76 bool is_taken(const void *p)
78 if (!p && unlikely(allocfail))
81 return find_taken(p) > 0;
84 const char *taken_any(void)
86 static char pointer_buf[32];
91 /* We're *allowed* to have some with labels, some without. */
94 for (i = 0; i < num_taken; i++)
99 sprintf(pointer_buf, "%p", takenarr[0]);
103 void take_cleanup(void)
105 max_taken = num_taken = 0;
112 void take_allocfail(void (*fn)(const void *p))