2 * Licensed under a two-clause BSD-style license.
3 * See LICENSE for details.
11 #include <sys/types.h>
17 * The obj_pool_gen() macro generates a type-specific memory pool
22 * pre : Prefix for generated functions (ex: string_).
23 * obj_t : Type for treap data structure (ex: char).
24 * intial_capacity : The initial size of the memory pool (ex: 4096).
27 #define obj_pool_gen(pre, obj_t, initial_capacity) \
33 } pre##_pool = { 0, 0, NULL, NULL}; \
34 static void pre##_init(void) \
37 size_t ps = sysconf (_SC_PAGESIZE); \
38 /* Touch binary file before opening read/write */ \
39 pre##_pool.file = fopen(#pre ".bin", "a"); \
40 fclose(pre##_pool.file); \
41 /* Open, check size, compute capacity */ \
42 pre##_pool.file = fopen(#pre ".bin", "r+"); \
43 fstat(fileno(pre##_pool.file), &st); \
44 pre##_pool.size = st.st_size / sizeof(obj_t); \
45 pre##_pool.capacity = ((st.st_size + ps - 1) & ~(ps - 1)) / sizeof(obj_t); \
46 if (pre##_pool.capacity < initial_capacity) \
47 pre##_pool.capacity = initial_capacity; \
48 /* Truncate to calculated capacity and map to VM */ \
49 ftruncate(fileno(pre##_pool.file), pre##_pool.capacity * sizeof(obj_t)); \
50 pre##_pool.base = mmap(0, pre##_pool.capacity * sizeof(obj_t), \
51 PROT_READ | PROT_WRITE, MAP_SHARED, \
52 fileno(pre##_pool.file), 0); \
54 static uint32_t pre##_alloc(uint32_t count) \
57 if (pre##_pool.size + count > pre##_pool.capacity) { \
58 if (NULL == pre##_pool.base) \
60 fsync(fileno(pre##_pool.file)); \
61 munmap(pre##_pool.base, \
62 pre##_pool.capacity * sizeof(obj_t)); \
63 pre##_pool.base = NULL; \
64 while (pre##_pool.size + count > pre##_pool.capacity) \
65 if (pre##_pool.capacity) \
66 pre##_pool.capacity *= 2; \
68 pre##_pool.capacity = initial_capacity; \
69 ftruncate(fileno(pre##_pool.file), \
70 pre##_pool.capacity * sizeof(obj_t)); \
72 mmap(0, pre##_pool.capacity * sizeof(obj_t), \
73 PROT_READ | PROT_WRITE, MAP_SHARED, \
74 fileno(pre##_pool.file), 0); \
76 offset = pre##_pool.size; \
77 pre##_pool.size += count; \
80 static void pre##_free(uint32_t count) \
82 pre##_pool.size -= count; \
84 static uint32_t pre##_offset(obj_t *obj) \
86 return obj == NULL ? ~0 : obj - pre##_pool.base; \
88 static obj_t *pre##_pointer(uint32_t offset) \
90 return offset >= pre##_pool.size ? NULL : &pre##_pool.base[offset]; \
92 static void pre##_reset(void) \
94 if (pre##_pool.base) { \
95 fsync(fileno(pre##_pool.file)); \
96 munmap(pre##_pool.base, \
97 pre##_pool.capacity * sizeof(obj_t)); \
98 ftruncate(fileno(pre##_pool.file), \
99 pre##_pool.size * sizeof(obj_t)); \
100 fclose(pre##_pool.file); \
102 pre##_pool.base = NULL; \
103 pre##_pool.size = 0; \
104 pre##_pool.capacity = 0; \
105 pre##_pool.file = NULL; \