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)
_create_internal(reserve_at_beginning, alignment);
if (ba_trace_file != nullptr) {
fprintf(ba_trace_file, "ba_trace_create %p\n", this);
fflush(ba_trace_file);
}
}
......@@ -161,6 +162,7 @@ void block_allocator::destroy() {
if (ba_trace_file != nullptr) {
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) {
switch (_strategy) {
case BA_STRATEGY_FIRST_FIT:
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:
abort();
}
......@@ -287,6 +291,7 @@ done:
if (ba_trace_file != nullptr) {
fprintf(ba_trace_file, "ba_trace_alloc %p %lu %lu\n",
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) {
if (ba_trace_file != nullptr) {
fprintf(ba_trace_file, "ba_trace_free %p %lu\n",
this, static_cast<unsigned long>(offset));
fflush(ba_trace_file);
}
}
......
......@@ -125,7 +125,8 @@ public:
static const size_t BLOCK_ALLOCATOR_TOTAL_HEADER_RESERVE = BLOCK_ALLOCATOR_HEADER_RESERVE * 2;
enum allocation_strategy {
BA_STRATEGY_FIRST_FIT = 1
BA_STRATEGY_FIRST_FIT = 1,
BA_STRATEGY_BEST_FIT
};
struct blockpair {
......
......@@ -102,3 +102,25 @@ block_allocator_strategy::first_fit(struct block_allocator::blockpair *blocks_ar
}
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:
first_fit(struct block_allocator::blockpair *blocks_array,
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:
// Effect: align a value by rounding up.
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) {
switch (strategy) {
case block_allocator::allocation_strategy::BA_STRATEGY_FIRST_FIT:
return "first-fit";
case block_allocator::allocation_strategy::BA_STRATEGY_BEST_FIT:
return "best-fit";
default:
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