|
1 | 1 | #ifndef COMMIT_SLAB_H
|
2 | 2 | #define COMMIT_SLAB_H
|
3 | 3 |
|
| 4 | +#include "commit-slab-decl.h" |
| 5 | +#include "commit-slab-impl.h" |
| 6 | + |
4 | 7 | /*
|
5 | 8 | * define_commit_slab(slabname, elemtype) creates boilerplate code to define
|
6 | 9 | * a new struct (struct slabname) that is used to associate a piece of data
|
|
41 | 44 | * leaking memory.
|
42 | 45 | */
|
43 | 46 |
|
44 |
| -/* allocate ~512kB at once, allowing for malloc overhead */ |
45 |
| -#ifndef COMMIT_SLAB_SIZE |
46 |
| -#define COMMIT_SLAB_SIZE (512*1024-32) |
47 |
| -#endif |
48 |
| - |
49 |
| -#define MAYBE_UNUSED __attribute__((__unused__)) |
50 |
| - |
51 |
| -#define define_commit_slab(slabname, elemtype) \ |
52 |
| - \ |
53 |
| -struct slabname { \ |
54 |
| - unsigned slab_size; \ |
55 |
| - unsigned stride; \ |
56 |
| - unsigned slab_count; \ |
57 |
| - elemtype **slab; \ |
58 |
| -}; \ |
59 |
| -static int stat_ ##slabname## realloc; \ |
60 |
| - \ |
61 |
| -static MAYBE_UNUSED void init_ ##slabname## _with_stride(struct slabname *s, \ |
62 |
| - unsigned stride) \ |
63 |
| -{ \ |
64 |
| - unsigned int elem_size; \ |
65 |
| - if (!stride) \ |
66 |
| - stride = 1; \ |
67 |
| - s->stride = stride; \ |
68 |
| - elem_size = sizeof(elemtype) * stride; \ |
69 |
| - s->slab_size = COMMIT_SLAB_SIZE / elem_size; \ |
70 |
| - s->slab_count = 0; \ |
71 |
| - s->slab = NULL; \ |
72 |
| -} \ |
73 |
| - \ |
74 |
| -static MAYBE_UNUSED void init_ ##slabname(struct slabname *s) \ |
75 |
| -{ \ |
76 |
| - init_ ##slabname## _with_stride(s, 1); \ |
77 |
| -} \ |
78 |
| - \ |
79 |
| -static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s) \ |
80 |
| -{ \ |
81 |
| - unsigned int i; \ |
82 |
| - for (i = 0; i < s->slab_count; i++) \ |
83 |
| - free(s->slab[i]); \ |
84 |
| - s->slab_count = 0; \ |
85 |
| - FREE_AND_NULL(s->slab); \ |
86 |
| -} \ |
87 |
| - \ |
88 |
| -static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s, \ |
89 |
| - const struct commit *c, \ |
90 |
| - int add_if_missing) \ |
91 |
| -{ \ |
92 |
| - unsigned int nth_slab, nth_slot; \ |
93 |
| - \ |
94 |
| - nth_slab = c->index / s->slab_size; \ |
95 |
| - nth_slot = c->index % s->slab_size; \ |
96 |
| - \ |
97 |
| - if (s->slab_count <= nth_slab) { \ |
98 |
| - unsigned int i; \ |
99 |
| - if (!add_if_missing) \ |
100 |
| - return NULL; \ |
101 |
| - REALLOC_ARRAY(s->slab, nth_slab + 1); \ |
102 |
| - stat_ ##slabname## realloc++; \ |
103 |
| - for (i = s->slab_count; i <= nth_slab; i++) \ |
104 |
| - s->slab[i] = NULL; \ |
105 |
| - s->slab_count = nth_slab + 1; \ |
106 |
| - } \ |
107 |
| - if (!s->slab[nth_slab]) { \ |
108 |
| - if (!add_if_missing) \ |
109 |
| - return NULL; \ |
110 |
| - s->slab[nth_slab] = xcalloc(s->slab_size, \ |
111 |
| - sizeof(**s->slab) * s->stride); \ |
112 |
| - } \ |
113 |
| - return &s->slab[nth_slab][nth_slot * s->stride]; \ |
114 |
| -} \ |
115 |
| - \ |
116 |
| -static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \ |
117 |
| - const struct commit *c) \ |
118 |
| -{ \ |
119 |
| - return slabname##_at_peek(s, c, 1); \ |
120 |
| -} \ |
121 |
| - \ |
122 |
| -static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s, \ |
123 |
| - const struct commit *c) \ |
124 |
| -{ \ |
125 |
| - return slabname##_at_peek(s, c, 0); \ |
126 |
| -} \ |
127 |
| - \ |
128 |
| -struct slabname |
129 |
| - |
130 |
| -/* |
131 |
| - * Note that this redundant forward declaration is required |
132 |
| - * to allow a terminating semicolon, which makes instantiations look |
133 |
| - * like function declarations. I.e., the expansion of |
134 |
| - * |
135 |
| - * define_commit_slab(indegree, int); |
136 |
| - * |
137 |
| - * ends in 'struct indegree;'. This would otherwise |
138 |
| - * be a syntax error according (at least) to ISO C. It's hard to |
139 |
| - * catch because GCC silently parses it by default. |
140 |
| - */ |
141 |
| - |
142 |
| -/* |
143 |
| - * Statically initialize a commit slab named "var". Note that this |
144 |
| - * evaluates "stride" multiple times! Example: |
145 |
| - * |
146 |
| - * struct indegree indegrees = COMMIT_SLAB_INIT(1, indegrees); |
147 |
| - * |
148 |
| - */ |
149 |
| -#define COMMIT_SLAB_INIT(stride, var) { \ |
150 |
| - COMMIT_SLAB_SIZE / sizeof(**((var).slab)) / (stride), \ |
151 |
| - (stride), 0, NULL \ |
152 |
| -} |
| 47 | +#define define_commit_slab(slabname, elemtype) \ |
| 48 | + declare_commit_slab(slabname, elemtype); \ |
| 49 | + implement_commit_slab(slabname, elemtype) |
153 | 50 |
|
154 | 51 | #endif /* COMMIT_SLAB_H */
|
0 commit comments