Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 236 lines (205 sloc) 9.407 kB
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
3 #if !defined(_memory_pool_h_)
4 #define _memory_pool_h_
5
6 #include <stdlib.h>
7
8 typedef enum memory_pool_e {
9 #define MEMORY_POOL(pool_enum, pool_counter, pool_string) pool_enum,
10 #include "memory_pool_classes.h"
11 } memory_pool_t;
12
13
14 typedef struct pool_prefix_s pool_prefix_t;
15 struct pool_prefix_s {
16 void* ptr;
17 size_t pool_length;
18 memory_pool_t pool;
19 uint32_t signature;
20 };
21
22 #define MEMORY_POOL_SIGNATURE 0xdeadcafe
23 // #define MEMORY_POOL_CHECKS
24 // #define MEMORY_POOL_ERROR_BREAKDOWN
25
26 #define pool_malloc(bytes, pool) pool_malloc_locking(true, bytes, pool)
27 #define pool_calloc(nmemb, size, pool) pool_calloc_locking(true, nmemb, size, pool)
28 #define pool_free(ptr, bytes, pool) pool_free_locking(true, ptr, bytes, pool)
29 #define pool_realloc(ptr, bytes, previous, pool) pool_realloc_locking(true, ptr, bytes, previous, pool)
30
31 #if defined(NDEBUG)
32 #define pool_assert(counter, assertion) \
33 if (! (assertion)) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
34 STATS_LOCK(stats); \
35 stats->counter ++; \
36 STATS_UNLOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
37 }
38 #else
39 #define pool_assert(counter, assertion) assert(assertion)
40 #endif /* #if defined(NDEBUG) */
41
42
43 static inline void* pool_malloc_locking(bool do_lock, size_t bytes, memory_pool_t pool) {
1d33e19 move stats collection in memcached to per-thread
ps authored
44 stats_t *stats = STATS_GET_TLS();
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
45 #if defined(MEMORY_POOL_CHECKS)
46 void* alloc = malloc(bytes + sizeof(pool_prefix_t));
47 pool_prefix_t* prefix = alloc;
48 void* ret = alloc + sizeof(pool_prefix_t);
49 prefix->ptr = ret;
50 prefix->pool_length = bytes;
51 prefix->pool = pool;
52 prefix->signature = MEMORY_POOL_SIGNATURE;
53 #else /* #if defined(MEMORY_POOL_CHECKS) */
54 void* ret = malloc(bytes);
55 #endif /* #if defined(MEMORY_POOL_CHECKS) */
56
57 if (ret != NULL) {
58 switch (pool) {
59 #define MEMORY_POOL(pool_enum, pool_counter, pool_string) \
60 case pool_enum: \
61 if (do_lock) \
1d33e19 move stats collection in memcached to per-thread
ps authored
62 STATS_LOCK(stats); \
63 stats->pool_counter += bytes; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
64 if (do_lock) \
1d33e19 move stats collection in memcached to per-thread
ps authored
65 STATS_UNLOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
66 break;
67 #include "memory_pool_classes.h"
68 }
69 }
70
71 return ret;
72 }
73
74
75 static inline void* pool_calloc_locking(bool do_lock, size_t nmemb, size_t size, memory_pool_t pool) {
1d33e19 move stats collection in memcached to per-thread
ps authored
76 stats_t *stats = STATS_GET_TLS();
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
77 size_t bytes = nmemb * size;
78 #if defined(MEMORY_POOL_CHECKS)
79 void* alloc = malloc(bytes + sizeof(pool_prefix_t));
80 pool_prefix_t* prefix = alloc;
81 void* ret = alloc + sizeof(pool_prefix_t);
82 prefix->ptr = ret;
83 prefix->pool_length = bytes;
84 prefix->pool = pool;
85 prefix->signature = MEMORY_POOL_SIGNATURE;
86 memset(ret, 0, bytes);
87 #else /* #if defined(MEMORY_POOL_CHECKS) */
88 void* ret = calloc(nmemb, size);
89 #endif /* #if defined(MEMORY_POOL_CHECKS) */
90
91 if (ret != NULL) {
92 switch (pool) {
93 #define MEMORY_POOL(pool_enum, pool_counter, pool_string) \
94 case pool_enum: \
95 if (do_lock) \
1d33e19 move stats collection in memcached to per-thread
ps authored
96 STATS_LOCK(stats); \
97 stats->pool_counter += bytes; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
98 if (do_lock) \
1d33e19 move stats collection in memcached to per-thread
ps authored
99 STATS_UNLOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
100 break;
101 #include "memory_pool_classes.h"
102 }
103 }
104
105 return ret;
106 }
107
108
109 static inline void pool_free_locking(bool do_lock, void* ptr, size_t previous, memory_pool_t pool) {
1d33e19 move stats collection in memcached to per-thread
ps authored
110 stats_t *stats = STATS_GET_TLS();
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
111 #if defined(MEMORY_POOL_CHECKS)
112 pool_prefix_t* prefix = ptr;
113 void* alloc;
114 #if defined(MEMORY_POOL_ERROR_BREAKDOWN)
115 size_t saved_pool_length;
116 #endif /* #if defined(MEMORY_POOL_ERROR_BREAKDOWN) */
117
118 prefix --;
119 alloc = prefix;
120
121 #if defined(MEMORY_POOL_ERROR_BREAKDOWN)
122 saved_pool_length = prefix->pool_length;
123 #endif /* #if defined(MEMORY_POOL_ERROR_BREAKDOWN) */
124
125 pool_assert(mp_blk_errors, prefix->ptr == ptr);
126 pool_assert(mp_bytecount_errors, prefix->pool_length == previous);
127 pool_assert(mp_pool_errors, prefix->pool == pool);
128 pool_assert(mp_blk_errors, prefix->signature == MEMORY_POOL_SIGNATURE);
129 free(alloc);
130 #else /* #if defined(MEMORY_POOL_CHECKS) */
131 free(ptr);
132 #endif /* #if defined(MEMORY_POOL_CHECKS) */
133
134 switch (pool) {
135 #if defined(MEMORY_POOL_ERROR_BREAKDOWN)
136 #define MEMORY_POOL(pool_enum, pool_counter, pool_string) \
137 case pool_enum: \
138 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
139 STATS_LOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
140 } \
1d33e19 move stats collection in memcached to per-thread
ps authored
141 stats->pool_counter -= previous; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
142 if (saved_pool_length != previous) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
143 stats->mp_bytecount_errors_free_split.pool_counter ++; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
144 } \
145 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
146 STATS_UNLOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
147 } \
148 break;
149 #else
150 #define MEMORY_POOL(pool_enum, pool_counter, pool_string) \
151 case pool_enum: \
152 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
153 STATS_LOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
154 } \
1d33e19 move stats collection in memcached to per-thread
ps authored
155 stats->pool_counter -= previous; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
156 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
157 STATS_UNLOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
158 } \
159 break;
160 #endif /* #if defined(MEMORY_POOL_ERROR_BREAKDOWN) */
161 #include "memory_pool_classes.h"
162 }
163 }
164
165
166 static inline void* pool_realloc_locking(bool do_lock, void* ptr, size_t bytes, size_t previous, memory_pool_t pool) {
1d33e19 move stats collection in memcached to per-thread
ps authored
167 stats_t *stats = STATS_GET_TLS();
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
168 #if defined(MEMORY_POOL_CHECKS)
169 pool_prefix_t* prefix = ptr;
170 void* alloc, * ret;
171 #if defined(MEMORY_POOL_ERROR_BREAKDOWN)
172 size_t saved_pool_length;
173 #endif /* #if defined(MEMORY_POOL_ERROR_BREAKDOWN) */
174
175 prefix --;
176 alloc = prefix;
177
178 #if defined(MEMORY_POOL_ERROR_BREAKDOWN)
179 saved_pool_length = prefix->pool_length;
180 #endif /* #if defined(MEMORY_POOL_ERROR_BREAKDOWN) */
181
182 pool_assert(mp_blk_errors, prefix->ptr == ptr);
183 pool_assert(mp_bytecount_errors, prefix->pool_length == previous);
184 pool_assert(mp_pool_errors, prefix->pool == pool);
185 pool_assert(mp_blk_errors, prefix->signature == MEMORY_POOL_SIGNATURE);
186 alloc = realloc(alloc, bytes + sizeof(pool_prefix_t));
187 if (alloc == NULL) {
188 return NULL;
189 }
190 prefix = alloc;
191 ret = alloc + sizeof(pool_prefix_t);
192 prefix->ptr = ret;
193 prefix->pool_length = bytes;
194 #else /* #if defined(MEMORY_POOL_CHECKS) */
195 void* ret = realloc(ptr, bytes);
196 #endif /* #if defined(MEMORY_POOL_CHECKS) */
197
198 if (ret != NULL) {
199 switch (pool) {
200 #if defined(MEMORY_POOL_ERROR_BREAKDOWN)
201 #define MEMORY_POOL(pool_enum, pool_counter, pool_string) \
202 case pool_enum: \
203 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
204 STATS_LOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
205 } \
1d33e19 move stats collection in memcached to per-thread
ps authored
206 stats->pool_counter -= previous; \
207 stats->pool_counter += bytes; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
208 if (saved_pool_length != previous) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
209 stats->mp_bytecount_errors_realloc_split.pool_counter ++; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
210 } \
211 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
212 STATS_UNLOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
213 } \
214 break;
215 #else
216 #define MEMORY_POOL(pool_enum, pool_counter, pool_string) \
217 case pool_enum: \
218 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
219 STATS_LOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
220 } \
1d33e19 move stats collection in memcached to per-thread
ps authored
221 stats->pool_counter -= previous; \
222 stats->pool_counter += bytes; \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
223 if (do_lock) { \
1d33e19 move stats collection in memcached to per-thread
ps authored
224 STATS_UNLOCK(stats); \
7a1f4fa fixes to flat allocator, merge from trunk
ttung authored
225 } \
226 break;
227 #endif /* #if defined(MEMORY_POOL_ERROR_BREAKDOWN) */
228 #include "memory_pool_classes.h"
229 }
230 }
231
232 return ret;
233 }
234
235 #endif /* #if !defined(_memory_pool_h_) */
Something went wrong with that request. Please try again.