summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--commit-slab-decl.h30
-rw-r--r--commit-slab-impl.h91
-rw-r--r--commit-slab.h115
3 files changed, 127 insertions, 109 deletions
diff --git a/commit-slab-decl.h b/commit-slab-decl.h
new file mode 100644
index 0000000000..fb5220fb7d
--- /dev/null
+++ b/commit-slab-decl.h
@@ -0,0 +1,30 @@
+#ifndef COMMIT_SLAB_HDR_H
+#define COMMIT_SLAB_HDR_H
+
+/* allocate ~512kB at once, allowing for malloc overhead */
+#ifndef COMMIT_SLAB_SIZE
+#define COMMIT_SLAB_SIZE (512*1024-32)
+#endif
+
+#define declare_commit_slab(slabname, elemtype) \
+ \
+struct slabname { \
+ unsigned slab_size; \
+ unsigned stride; \
+ unsigned slab_count; \
+ elemtype **slab; \
+}
+
+/*
+ * Statically initialize a commit slab named "var". Note that this
+ * evaluates "stride" multiple times! Example:
+ *
+ * struct indegree indegrees = COMMIT_SLAB_INIT(1, indegrees);
+ *
+ */
+#define COMMIT_SLAB_INIT(stride, var) { \
+ COMMIT_SLAB_SIZE / sizeof(**((var).slab)) / (stride), \
+ (stride), 0, NULL \
+}
+
+#endif /* COMMIT_SLAB_HDR_H */
diff --git a/commit-slab-impl.h b/commit-slab-impl.h
new file mode 100644
index 0000000000..234d9ee5f0
--- /dev/null
+++ b/commit-slab-impl.h
@@ -0,0 +1,91 @@
+#ifndef COMMIT_SLAB_IMPL_H
+#define COMMIT_SLAB_IMPL_H
+
+#define MAYBE_UNUSED __attribute__((__unused__))
+
+#define implement_commit_slab(slabname, elemtype) \
+ \
+static int stat_ ##slabname## realloc; \
+ \
+static MAYBE_UNUSED void init_ ##slabname## _with_stride(struct slabname *s, \
+ unsigned stride) \
+{ \
+ unsigned int elem_size; \
+ if (!stride) \
+ stride = 1; \
+ s->stride = stride; \
+ elem_size = sizeof(elemtype) * stride; \
+ s->slab_size = COMMIT_SLAB_SIZE / elem_size; \
+ s->slab_count = 0; \
+ s->slab = NULL; \
+} \
+ \
+static MAYBE_UNUSED void init_ ##slabname(struct slabname *s) \
+{ \
+ init_ ##slabname## _with_stride(s, 1); \
+} \
+ \
+static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s) \
+{ \
+ unsigned int i; \
+ for (i = 0; i < s->slab_count; i++) \
+ free(s->slab[i]); \
+ s->slab_count = 0; \
+ FREE_AND_NULL(s->slab); \
+} \
+ \
+static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s, \
+ const struct commit *c, \
+ int add_if_missing) \
+{ \
+ unsigned int nth_slab, nth_slot; \
+ \
+ nth_slab = c->index / s->slab_size; \
+ nth_slot = c->index % s->slab_size; \
+ \
+ if (s->slab_count <= nth_slab) { \
+ unsigned int i; \
+ if (!add_if_missing) \
+ return NULL; \
+ REALLOC_ARRAY(s->slab, nth_slab + 1); \
+ stat_ ##slabname## realloc++; \
+ for (i = s->slab_count; i <= nth_slab; i++) \
+ s->slab[i] = NULL; \
+ s->slab_count = nth_slab + 1; \
+ } \
+ if (!s->slab[nth_slab]) { \
+ if (!add_if_missing) \
+ return NULL; \
+ s->slab[nth_slab] = xcalloc(s->slab_size, \
+ sizeof(**s->slab) * s->stride); \
+ } \
+ return &s->slab[nth_slab][nth_slot * s->stride]; \
+} \
+ \
+static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \
+ const struct commit *c) \
+{ \
+ return slabname##_at_peek(s, c, 1); \
+} \
+ \
+static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s, \
+ const struct commit *c) \
+{ \
+ return slabname##_at_peek(s, c, 0); \
+} \
+ \
+struct slabname
+
+/*
+ * Note that this redundant forward declaration is required
+ * to allow a terminating semicolon, which makes instantiations look
+ * like function declarations. I.e., the expansion of
+ *
+ * implement_commit_slab(indegree, int);
+ *
+ * ends in 'struct indegree;'. This would otherwise
+ * be a syntax error according (at least) to ISO C. It's hard to
+ * catch because GCC silently parses it by default.
+ */
+
+#endif /* COMMIT_SLAB_IMPL_H */
diff --git a/commit-slab.h b/commit-slab.h
index dcaab8ca04..32aa2c0e46 100644
--- a/commit-slab.h
+++ b/commit-slab.h
@@ -1,6 +1,9 @@
#ifndef COMMIT_SLAB_H
#define COMMIT_SLAB_H
+#include "commit-slab-decl.h"
+#include "commit-slab-impl.h"
+
/*
* define_commit_slab(slabname, elemtype) creates boilerplate code to define
* a new struct (struct slabname) that is used to associate a piece of data
@@ -41,114 +44,8 @@
* leaking memory.
*/
-/* allocate ~512kB at once, allowing for malloc overhead */
-#ifndef COMMIT_SLAB_SIZE
-#define COMMIT_SLAB_SIZE (512*1024-32)
-#endif
-
-#define MAYBE_UNUSED __attribute__((__unused__))
-
-#define define_commit_slab(slabname, elemtype) \
- \
-struct slabname { \
- unsigned slab_size; \
- unsigned stride; \
- unsigned slab_count; \
- elemtype **slab; \
-}; \
-static int stat_ ##slabname## realloc; \
- \
-static MAYBE_UNUSED void init_ ##slabname## _with_stride(struct slabname *s, \
- unsigned stride) \
-{ \
- unsigned int elem_size; \
- if (!stride) \
- stride = 1; \
- s->stride = stride; \
- elem_size = sizeof(elemtype) * stride; \
- s->slab_size = COMMIT_SLAB_SIZE / elem_size; \
- s->slab_count = 0; \
- s->slab = NULL; \
-} \
- \
-static MAYBE_UNUSED void init_ ##slabname(struct slabname *s) \
-{ \
- init_ ##slabname## _with_stride(s, 1); \
-} \
- \
-static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s) \
-{ \
- unsigned int i; \
- for (i = 0; i < s->slab_count; i++) \
- free(s->slab[i]); \
- s->slab_count = 0; \
- FREE_AND_NULL(s->slab); \
-} \
- \
-static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s, \
- const struct commit *c, \
- int add_if_missing) \
-{ \
- unsigned int nth_slab, nth_slot; \
- \
- nth_slab = c->index / s->slab_size; \
- nth_slot = c->index % s->slab_size; \
- \
- if (s->slab_count <= nth_slab) { \
- unsigned int i; \
- if (!add_if_missing) \
- return NULL; \
- REALLOC_ARRAY(s->slab, nth_slab + 1); \
- stat_ ##slabname## realloc++; \
- for (i = s->slab_count; i <= nth_slab; i++) \
- s->slab[i] = NULL; \
- s->slab_count = nth_slab + 1; \
- } \
- if (!s->slab[nth_slab]) { \
- if (!add_if_missing) \
- return NULL; \
- s->slab[nth_slab] = xcalloc(s->slab_size, \
- sizeof(**s->slab) * s->stride); \
- } \
- return &s->slab[nth_slab][nth_slot * s->stride]; \
-} \
- \
-static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \
- const struct commit *c) \
-{ \
- return slabname##_at_peek(s, c, 1); \
-} \
- \
-static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s, \
- const struct commit *c) \
-{ \
- return slabname##_at_peek(s, c, 0); \
-} \
- \
-struct slabname
-
-/*
- * Note that this redundant forward declaration is required
- * to allow a terminating semicolon, which makes instantiations look
- * like function declarations. I.e., the expansion of
- *
- * define_commit_slab(indegree, int);
- *
- * ends in 'struct indegree;'. This would otherwise
- * be a syntax error according (at least) to ISO C. It's hard to
- * catch because GCC silently parses it by default.
- */
-
-/*
- * Statically initialize a commit slab named "var". Note that this
- * evaluates "stride" multiple times! Example:
- *
- * struct indegree indegrees = COMMIT_SLAB_INIT(1, indegrees);
- *
- */
-#define COMMIT_SLAB_INIT(stride, var) { \
- COMMIT_SLAB_SIZE / sizeof(**((var).slab)) / (stride), \
- (stride), 0, NULL \
-}
+#define define_commit_slab(slabname, elemtype) \
+ declare_commit_slab(slabname, elemtype); \
+ implement_commit_slab(slabname, elemtype)
#endif /* COMMIT_SLAB_H */