blob: 4a414ee905d5de4498d1fcca2da53e7c6a07b50e [file] [log] [blame]
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +02001#ifndef COMMIT_SLAB_IMPL_H
2#define COMMIT_SLAB_IMPL_H
3
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +02004#define implement_static_commit_slab(slabname, elemtype) \
Carlo Marcelo Arenas Belónbbd8eb32018-10-23 14:50:19 -07005 implement_commit_slab(slabname, elemtype, MAYBE_UNUSED static)
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +02006
7#define implement_shared_commit_slab(slabname, elemtype) \
8 implement_commit_slab(slabname, elemtype, )
9
10#define implement_commit_slab(slabname, elemtype, scope) \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020011 \
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +020012scope void init_ ##slabname## _with_stride(struct slabname *s, \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020013 unsigned stride) \
14{ \
15 unsigned int elem_size; \
16 if (!stride) \
17 stride = 1; \
18 s->stride = stride; \
19 elem_size = sizeof(elemtype) * stride; \
20 s->slab_size = COMMIT_SLAB_SIZE / elem_size; \
21 s->slab_count = 0; \
22 s->slab = NULL; \
23} \
24 \
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +020025scope void init_ ##slabname(struct slabname *s) \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020026{ \
27 init_ ##slabname## _with_stride(s, 1); \
28} \
29 \
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +020030scope void clear_ ##slabname(struct slabname *s) \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020031{ \
32 unsigned int i; \
33 for (i = 0; i < s->slab_count; i++) \
34 free(s->slab[i]); \
35 s->slab_count = 0; \
36 FREE_AND_NULL(s->slab); \
37} \
38 \
SZEDER Gábor1df15f82020-06-05 13:00:26 +000039scope void deep_clear_ ##slabname(struct slabname *s, void (*free_fn)(elemtype *)) \
40{ \
41 unsigned int i; \
42 for (i = 0; i < s->slab_count; i++) { \
43 unsigned int j; \
44 if (!s->slab[i]) \
45 continue; \
46 for (j = 0; j < s->slab_size; j++) \
47 free_fn(&s->slab[i][j * s->stride]); \
48 } \
49 clear_ ##slabname(s); \
50} \
51 \
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +020052scope elemtype *slabname## _at_peek(struct slabname *s, \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020053 const struct commit *c, \
54 int add_if_missing) \
55{ \
56 unsigned int nth_slab, nth_slot; \
57 \
58 nth_slab = c->index / s->slab_size; \
59 nth_slot = c->index % s->slab_size; \
60 \
61 if (s->slab_count <= nth_slab) { \
62 unsigned int i; \
63 if (!add_if_missing) \
64 return NULL; \
65 REALLOC_ARRAY(s->slab, nth_slab + 1); \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020066 for (i = s->slab_count; i <= nth_slab; i++) \
67 s->slab[i] = NULL; \
68 s->slab_count = nth_slab + 1; \
69 } \
70 if (!s->slab[nth_slab]) { \
71 if (!add_if_missing) \
72 return NULL; \
73 s->slab[nth_slab] = xcalloc(s->slab_size, \
74 sizeof(**s->slab) * s->stride); \
75 } \
76 return &s->slab[nth_slab][nth_slot * s->stride]; \
77} \
78 \
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +020079scope elemtype *slabname## _at(struct slabname *s, \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020080 const struct commit *c) \
81{ \
82 return slabname##_at_peek(s, c, 1); \
83} \
84 \
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +020085scope elemtype *slabname## _peek(struct slabname *s, \
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020086 const struct commit *c) \
87{ \
88 return slabname##_at_peek(s, c, 0); \
89} \
90 \
91struct slabname
92
93/*
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
97 *
Nguyễn Thái Ngọc Duy878f0bb2018-05-19 07:28:18 +020098 * implement_commit_slab(indegree, int, static);
Nguyễn Thái Ngọc Duya9f1f1f2018-05-19 07:28:17 +020099 *
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.
103 */
104
105#endif /* COMMIT_SLAB_IMPL_H */