1 #ifndef COMMIT_SLAB_IMPL_H
2 #define COMMIT_SLAB_IMPL_H
4 #define implement_static_commit_slab(slabname, elemtype) \
5 implement_commit_slab(slabname, elemtype, MAYBE_UNUSED static)
7 #define implement_shared_commit_slab(slabname, elemtype) \
8 implement_commit_slab(slabname, elemtype, )
10 #define implement_commit_slab(slabname, elemtype, scope) \
12 scope void init_ ##slabname## _with_stride(struct slabname *s, \
15 unsigned int elem_size; \
19 elem_size = sizeof(elemtype) * stride; \
20 s->slab_size = COMMIT_SLAB_SIZE / elem_size; \
25 scope void init_ ##slabname(struct slabname *s) \
27 init_ ##slabname## _with_stride(s, 1); \
30 scope void clear_ ##slabname(struct slabname *s) \
33 for (i = 0; i < s->slab_count; i++) \
36 FREE_AND_NULL(s->slab); \
39 scope void deep_clear_ ##slabname(struct slabname *s, void (*free_fn)(elemtype *)) \
42 for (i = 0; i < s->slab_count; i++) { \
46 for (j = 0; j < s->slab_size; j++) \
47 free_fn(&s->slab[i][j * s->stride]); \
49 clear_ ##slabname(s); \
52 scope elemtype *slabname## _at_peek(struct slabname *s, \
53 const struct commit *c, \
56 unsigned int nth_slab, nth_slot; \
58 nth_slab = c->index / s->slab_size; \
59 nth_slot = c->index % s->slab_size; \
61 if (s->slab_count <= nth_slab) { \
63 if (!add_if_missing) \
65 REALLOC_ARRAY(s->slab, nth_slab + 1); \
66 for (i = s->slab_count; i <= nth_slab; i++) \
68 s->slab_count = nth_slab + 1; \
70 if (!s->slab[nth_slab]) { \
71 if (!add_if_missing) \
73 s->slab[nth_slab] = xcalloc(s->slab_size, \
74 sizeof(**s->slab) * s->stride); \
76 return &s->slab[nth_slab][nth_slot * s->stride]; \
79 scope elemtype *slabname## _at(struct slabname *s, \
80 const struct commit *c) \
82 return slabname##_at_peek(s, c, 1); \
85 scope elemtype *slabname## _peek(struct slabname *s, \
86 const struct commit *c) \
88 return slabname##_at_peek(s, c, 0); \
94 * Note that this redundant forward declaration is required
95 * to allow a terminating semicolon, which makes instantiations look
96 * like function declarations. I.e., the expansion of
98 * implement_commit_slab(indegree, int, static);
100 * ends in 'struct indegree;'. This would otherwise
101 * be a syntax error according (at least) to ISO C. It's hard to
102 * catch because GCC silently parses it by default.
105 #endif /* COMMIT_SLAB_IMPL_H */