Commit d4a3c6f6 authored by John Esmet's avatar John Esmet

FT-300 Add best-fit strategy for replay testing

parent 6d2968d0
...@@ -153,6 +153,7 @@ void block_allocator::create(uint64_t reserve_at_beginning, uint64_t alignment) ...@@ -153,6 +153,7 @@ void block_allocator::create(uint64_t reserve_at_beginning, uint64_t alignment)
_create_internal(reserve_at_beginning, alignment); _create_internal(reserve_at_beginning, alignment);
if (ba_trace_file != nullptr) { if (ba_trace_file != nullptr) {
fprintf(ba_trace_file, "ba_trace_create %p\n", this); fprintf(ba_trace_file, "ba_trace_create %p\n", this);
fflush(ba_trace_file);
} }
} }
...@@ -161,6 +162,7 @@ void block_allocator::destroy() { ...@@ -161,6 +162,7 @@ void block_allocator::destroy() {
if (ba_trace_file != nullptr) { if (ba_trace_file != nullptr) {
fprintf(ba_trace_file, "ba_trace_destroy %p\n", this); fprintf(ba_trace_file, "ba_trace_destroy %p\n", this);
fflush(ba_trace_file);
} }
} }
...@@ -226,6 +228,8 @@ block_allocator::choose_block_to_alloc_after(size_t size) { ...@@ -226,6 +228,8 @@ block_allocator::choose_block_to_alloc_after(size_t size) {
switch (_strategy) { switch (_strategy) {
case BA_STRATEGY_FIRST_FIT: case BA_STRATEGY_FIRST_FIT:
return block_allocator_strategy::first_fit(_blocks_array, _n_blocks, size, _alignment); return block_allocator_strategy::first_fit(_blocks_array, _n_blocks, size, _alignment);
case BA_STRATEGY_BEST_FIT:
return block_allocator_strategy::best_fit(_blocks_array, _n_blocks, size, _alignment);
default: default:
abort(); abort();
} }
...@@ -287,6 +291,7 @@ done: ...@@ -287,6 +291,7 @@ done:
if (ba_trace_file != nullptr) { if (ba_trace_file != nullptr) {
fprintf(ba_trace_file, "ba_trace_alloc %p %lu %lu\n", fprintf(ba_trace_file, "ba_trace_alloc %p %lu %lu\n",
this, static_cast<unsigned long>(size), static_cast<unsigned long>(*offset)); this, static_cast<unsigned long>(size), static_cast<unsigned long>(*offset));
fflush(ba_trace_file);
} }
} }
...@@ -333,7 +338,7 @@ void block_allocator::free_block(uint64_t offset) { ...@@ -333,7 +338,7 @@ void block_allocator::free_block(uint64_t offset) {
if (ba_trace_file != nullptr) { if (ba_trace_file != nullptr) {
fprintf(ba_trace_file, "ba_trace_free %p %lu\n", fprintf(ba_trace_file, "ba_trace_free %p %lu\n",
this, static_cast<unsigned long>(offset)); this, static_cast<unsigned long>(offset));
fflush(ba_trace_file);
} }
} }
......
...@@ -125,7 +125,8 @@ public: ...@@ -125,7 +125,8 @@ public:
static const size_t BLOCK_ALLOCATOR_TOTAL_HEADER_RESERVE = BLOCK_ALLOCATOR_HEADER_RESERVE * 2; static const size_t BLOCK_ALLOCATOR_TOTAL_HEADER_RESERVE = BLOCK_ALLOCATOR_HEADER_RESERVE * 2;
enum allocation_strategy { enum allocation_strategy {
BA_STRATEGY_FIRST_FIT = 1 BA_STRATEGY_FIRST_FIT = 1,
BA_STRATEGY_BEST_FIT
}; };
struct blockpair { struct blockpair {
......
...@@ -102,3 +102,25 @@ block_allocator_strategy::first_fit(struct block_allocator::blockpair *blocks_ar ...@@ -102,3 +102,25 @@ block_allocator_strategy::first_fit(struct block_allocator::blockpair *blocks_ar
} }
return nullptr; return nullptr;
} }
// Best fit block allocation
struct block_allocator::blockpair *
block_allocator_strategy::best_fit(struct block_allocator::blockpair *blocks_array,
uint64_t n_blocks, uint64_t size, uint64_t alignment) {
struct block_allocator::blockpair *best_bp = nullptr;
uint64_t best_hole_size = 0;
for (uint64_t blocknum = 0; blocknum + 1 < n_blocks; blocknum++) {
// Consider the space after blocknum
struct block_allocator::blockpair *bp = &blocks_array[blocknum];
uint64_t possible_offset = _align(bp->offset + bp->size, alignment);
if (possible_offset + size <= bp[1].offset) {
// It fits here. Is it the best fit?
uint64_t hole_size = (bp[1].offset - possible_offset) + size;
if (best_bp == nullptr || hole_size < best_hole_size) {
best_hole_size = hole_size;
best_bp = bp;
}
}
}
return best_bp;
}
...@@ -100,6 +100,10 @@ public: ...@@ -100,6 +100,10 @@ public:
first_fit(struct block_allocator::blockpair *blocks_array, first_fit(struct block_allocator::blockpair *blocks_array,
uint64_t n_blocks, uint64_t size, uint64_t alignment); uint64_t n_blocks, uint64_t size, uint64_t alignment);
static struct block_allocator::blockpair *
best_fit(struct block_allocator::blockpair *blocks_array,
uint64_t n_blocks, uint64_t size, uint64_t alignment);
private: private:
// Effect: align a value by rounding up. // Effect: align a value by rounding up.
static inline uint64_t _align(uint64_t value, uint64_t ba_alignment) { static inline uint64_t _align(uint64_t value, uint64_t ba_alignment) {
......
...@@ -316,6 +316,8 @@ static const char *strategy_str(block_allocator::allocation_strategy strategy) { ...@@ -316,6 +316,8 @@ static const char *strategy_str(block_allocator::allocation_strategy strategy) {
switch (strategy) { switch (strategy) {
case block_allocator::allocation_strategy::BA_STRATEGY_FIRST_FIT: case block_allocator::allocation_strategy::BA_STRATEGY_FIRST_FIT:
return "first-fit"; return "first-fit";
case block_allocator::allocation_strategy::BA_STRATEGY_BEST_FIT:
return "best-fit";
default: default:
abort(); abort();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment