[kutil] Rename 'size' to 'order' when meaning 2^N

Heap allocator is a buddy allocator that deals with power-of-two block
sizes. Previously it referred to both a number of bytes and an order of
magnitude as a 'size'. Rename functions and variables referring to
orders of magnitude to 'order'.

Tags: pedantry
This commit is contained in:
2020-07-30 19:41:41 -07:00
parent 4ffd4949ca
commit 73221dfe34
2 changed files with 55 additions and 54 deletions

View File

@@ -7,15 +7,15 @@ namespace kutil {
struct heap_allocator::mem_header
{
mem_header(mem_header *prev, mem_header *next, uint8_t size) :
mem_header(mem_header *prev, mem_header *next, uint8_t order) :
m_prev(prev), m_next(next)
{
set_size(size);
set_order(order);
}
inline void set_size(uint8_t size) {
inline void set_order(uint8_t order) {
m_prev = reinterpret_cast<mem_header *>(
reinterpret_cast<uintptr_t>(prev()) | (size & 0x3f));
reinterpret_cast<uintptr_t>(prev()) | (order & 0x3f));
}
inline void set_used(bool used) {
@@ -30,9 +30,9 @@ struct heap_allocator::mem_header
}
inline void set_prev(mem_header *prev) {
uint8_t s = size();
uint8_t s = order();
m_prev = prev;
set_size(s);
set_order(s);
}
void remove() {
@@ -47,12 +47,12 @@ struct heap_allocator::mem_header
inline mem_header * buddy() const {
return reinterpret_cast<mem_header *>(
reinterpret_cast<uintptr_t>(this) ^ (1 << size()));
reinterpret_cast<uintptr_t>(this) ^ (1 << order()));
}
inline bool eldest() const { return this < buddy(); }
inline uint8_t size() const { return reinterpret_cast<uintptr_t>(m_prev) & 0x3f; }
inline uint8_t order() const { return reinterpret_cast<uintptr_t>(m_prev) & 0x3f; }
inline bool used() const { return reinterpret_cast<uintptr_t>(m_next) & 0x1; }
private:
@@ -73,16 +73,17 @@ void *
heap_allocator::allocate(size_t length)
{
size_t total = length + sizeof(mem_header);
unsigned size = min_size;
while (total > (1 << size)) size++;
kassert(size <= max_size, "Tried to allocate a block bigger than max_size");
if (size > max_size)
unsigned order = min_order;
while (total > (1 << order)) order++;
kassert(order <= max_order, "Tried to allocate a block bigger than max_order");
if (order > max_order)
return nullptr;
mem_header *header = pop_free(size);
mem_header *header = pop_free(order);
header->set_used(true);
m_allocated_size += (1 << size);
m_allocated_size += (1 << order);
return header + 1;
}
@@ -94,66 +95,66 @@ heap_allocator::free(void *p)
mem_header *header = reinterpret_cast<mem_header *>(p);
header -= 1; // p points after the header
header->set_used(false);
m_allocated_size -= (1 << header->size());
m_allocated_size -= (1 << header->order());
while (header->size() != max_size) {
auto size = header->size();
while (header->order() != max_order) {
auto order = header->order();
mem_header *buddy = header->buddy();
if (buddy->used() || buddy->size() != size)
if (buddy->used() || buddy->order() != order)
break;
if (get_free(size) == buddy)
get_free(size) = buddy->next();
if (get_free(order) == buddy)
get_free(order) = buddy->next();
buddy->remove();
header = header->eldest() ? header : buddy;
header->set_size(size + 1);
header->set_order(order + 1);
}
uint8_t size = header->size();
header->set_next(get_free(size));
get_free(size) = header;
uint8_t order = header->order();
header->set_next(get_free(order));
get_free(order) = header;
if (header->next())
header->next()->set_prev(header);
}
void
heap_allocator::ensure_block(unsigned size)
heap_allocator::ensure_block(unsigned order)
{
if (get_free(size) != nullptr)
if (get_free(order) != nullptr)
return;
if (size == max_size) {
size_t bytes = (1 << max_size);
if (order == max_order) {
size_t bytes = (1 << max_order);
if (bytes <= m_size) {
mem_header *next = reinterpret_cast<mem_header *>(m_next);
new (next) mem_header(nullptr, nullptr, size);
get_free(size) = next;
new (next) mem_header(nullptr, nullptr, order);
get_free(order) = next;
m_next += bytes;
m_size -= bytes;
}
} else {
mem_header *orig = pop_free(size + 1);
mem_header *orig = pop_free(order + 1);
if (orig) {
mem_header *next = kutil::offset_pointer(orig, 1 << size);
new (next) mem_header(orig, nullptr, size);
mem_header *next = kutil::offset_pointer(orig, 1 << order);
new (next) mem_header(orig, nullptr, order);
orig->set_next(next);
orig->set_size(size);
get_free(size) = orig;
orig->set_order(order);
get_free(order) = orig;
}
}
}
heap_allocator::mem_header *
heap_allocator::pop_free(unsigned size)
heap_allocator::pop_free(unsigned order)
{
ensure_block(size);
mem_header *block = get_free(size);
ensure_block(order);
mem_header *block = get_free(order);
if (block) {
get_free(size) = block->next();
get_free(order) = block->next();
block->remove();
}
return block;