68 namespace memory_block {
79 #define EMPTY_ARRAY_DIM 81 #define EMPTY_ARRAY_DIM 0 117 typedef uint64_t bitmap;
120 MAX_CHIPS = 8 *
sizeof(bitmap)
123 block_bits(
size_t chip_count);
125 size_t acquire_contiguous(
size_t chip_count);
128 bool release_contiguous(
size_t idx,
size_t chip_count);
130 static bitmap create_mask(
size_t bits_set);
132 size_t usable_count()
const {
133 return _popc(_usable_chips);
136 size_t zombie_count()
const {
137 return _popc(_zombie_chips);
142 static size_t _popc(bitmap bm);
144 bitmap _usable_chips;
145 bitmap _zombie_chips;
166 block(
size_t chip_size,
size_t chip_count,
size_t block_size);
168 void* acquire_chip(
size_t chip_size,
size_t chip_count,
size_t block_size);
172 static bool release_chip(
void* ptr,
size_t chip_size,
size_t chip_count,
size_t block_size);
175 static void release(
void* ptr,
size_t chip_size,
size_t chip_count,
size_t block_size);
181 char* _get(
size_t idx,
size_t chip_size);
195 block* acquire_block(block_list* owner);
197 block* release_block(block* b);
200 virtual bool validate_pointer(
void* ptr) = 0;
202 virtual ~block_pool() {}
206 virtual block* _acquire_block() = 0;
209 virtual void _release_block(block* b) = 0;
213 block_list(block_pool* pool,
size_t chip_size,
size_t chip_count,
218 void* acquire(
size_t chip_size,
size_t chip_count,
size_t block_size);
220 block* acquire_block(
size_t block_size);
222 void* _slow_acquire(
size_t chip_size,
size_t chip_count,
size_t block_size);
224 void _change_blocks(
size_t chip_size,
size_t chip_count,
size_t block_size);
232 double _avg_hit_rate;
238 block* block_pool::acquire_block(block_list* owner) {
239 block* b = _acquire_block();
247 block* block_pool::release_block(block* b) {
248 assert(validate_pointer(b));
249 block* next = b->_next;
264 struct fail_unless<true> {
265 static bool valid() {
274 template<
int N,
int L,
int U>
275 struct bounds_check :
public fail_unless<(L <= N) && (N <= U)> {
276 static bool valid() {
287 struct meta_log2 : public fail_unless<(N > 2)> {
289 VALUE = 1 + meta_log2<N / 2>::VALUE
294 struct meta_log2<2> {
301 struct meta_log2<1> {
307 template<int A, int B>
310 VALUE = (A < B) ? A : B
323 template<int ChipSize, int OverheadBytes = sizeof(memory_block::block), int MaxChips = block_bits::MAX_CHIPS>
324 struct meta_block_size : public fail_unless<(ChipSize > 0 && OverheadBytes >= 0)> {
329 OVERHEAD = OverheadBytes
335 MIN_CHIPS = MAX_CHIPS / 2 + 1
338 BYTES_NEEDED = MIN_CHIPS * ChipSize + OverheadBytes
341 LOG2 = meta_log2<2 * BYTES_NEEDED - 1>::VALUE
347 fail_unless<((BYTES & -BYTES) == BYTES)> power_of_two;
359 REAL_COUNT = (BYTES - OverheadBytes) / ChipSize
361 fail_unless<((OVERHEAD + MIN_CHIPS * ChipSize) > (int)BYTES / 2)> sane_chip_count;
364 COUNT = meta_min<MAX_CHIPS, REAL_COUNT>::VALUE
366 bounds_check<COUNT, MIN_CHIPS, MAX_CHIPS> bounds;
372 #endif // __MEM_BLOCK_H