mem: Fix allocate_at

This commit is contained in:
sunho 2021-06-01 08:46:45 +02:00 committed by Nicolas Jallamion
parent 2f11285f07
commit 636f5da54c
3 changed files with 25 additions and 13 deletions

View File

@ -18,6 +18,7 @@ public:
void set_maximum(const std::size_t total_bits);
int allocate_from(const std::uint32_t start_offset, int &size, const bool best_fit = false);
int allocate_at(const std::uint32_t start_offset, int size);
void free(const std::uint32_t offset, const int size);
void reset();

View File

@ -33,7 +33,7 @@ int BitmapAllocator::force_fill(const std::uint32_t offset, const int size, cons
if (end_bit <= 32) {
// The bit we need to allocate is in single word
const std::uint32_t mask = ((~(0xFFFFFFFFU >> size)) >> set_bit);
const std::uint32_t mask = size == 32 ? 0xFFFFFFFFU : ((~(0xFFFFFFFFU >> size)) >> set_bit);
if (or_mode) {
*word = wval | mask;
@ -162,6 +162,13 @@ int BitmapAllocator::allocate_from(const std::uint32_t start_offset, int &size,
return -1;
}
int BitmapAllocator::allocate_at(const std::uint32_t start_offset, int size) {
if (free_slot_count(start_offset, start_offset + size) != size) {
return -1;
}
force_fill(start_offset, size, false);
}
static int number_of_set_bits(std::uint32_t i) {
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
@ -176,12 +183,12 @@ int BitmapAllocator::free_slot_count(const std::uint32_t offset, const std::uint
const std::uint32_t beg_off = (offset >> 5);
const std::uint32_t end_off = (offset_end >> 5);
if ((beg_off >= words.size()) || (end_off > words.size())) {
if (beg_off >= words.size()) {
return -1;
}
std::uint32_t start_bit = offset;
const std::uint32_t end_bit = offset_end;
const std::uint32_t end_bit = end_off >= words.size() ? max_offset : offset_end;
std::uint32_t free_count = 0;
@ -189,8 +196,8 @@ int BitmapAllocator::free_slot_count(const std::uint32_t offset, const std::uint
const std::uint32_t next_end_bit = std::min<std::uint32_t>(((start_bit + 32) >> 5) << 5, end_bit);
const int left_shift = start_bit & 31;
const int right_shift = left_shift + (31 - (next_end_bit - 1) & 31);
std::uint32_t word_to_scan = words[start_bit >> 5] << left_shift >> right_shift;
const int right_shift = (31 - (next_end_bit - 1) & 31);
std::uint32_t word_to_scan = words[start_bit >> 5] << left_shift >> right_shift >> left_shift;
free_count += number_of_set_bits(word_to_scan);
start_bit = next_end_bit;

View File

@ -125,13 +125,17 @@ bool is_valid_addr(const MemState &state, Address addr) {
}
static Address alloc_inner(MemState &state, uint32_t start_page, int page_count, const char *name, const bool force) {
// Try to find and allocate page
int page_num = state.allocator.allocate_from(start_page, page_count, !force);
if (page_num < 0) {
LOG_CRITICAL("Failed to allocate page");
}
if (force && page_num != start_page) {
LOG_CRITICAL("Failed to allocate at specific page");
int page_num;
if (force) {
if (state.allocator.allocate_at(start_page, page_count) < 0) {
LOG_CRITICAL("Failed to allocate at specific page");
}
page_num = start_page;
} else {
page_num = state.allocator.allocate_from(start_page, page_count, false);
if (page_num < 0) {
LOG_CRITICAL("Failed to allocate page");
}
}
const int size = page_count * state.page_size;
@ -312,7 +316,7 @@ Address alloc(MemState &state, size_t size, const char *name) {
Address alloc_at(MemState &state, Address address, size_t size, const char *name) {
const std::lock_guard<std::mutex> lock(state.generation_mutex);
const uint32_t wanted_page = address / state.page_size;
size += address - wanted_page * state.page_size;
size += address % state.page_size;
const size_t page_count = align(size, state.page_size) / state.page_size;
alloc_inner(state, wanted_page, page_count, name, true);
return address;