mirror of
https://github.com/Vita3K/Vita3K-Android.git
synced 2024-11-27 15:30:43 +00:00
mem: Fix allocate_at
This commit is contained in:
parent
2f11285f07
commit
636f5da54c
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user