LibC: Fix my ugly and hacked posix_memalign
This commit is contained in:
parent
ff289b25b6
commit
87f348b48e
|
@ -96,12 +96,6 @@ static bool allocate_pool(size_t pool_index)
|
||||||
node->prev_free = nullptr;
|
node->prev_free = nullptr;
|
||||||
node->next_free = nullptr;
|
node->next_free = nullptr;
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
||||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
|
||||||
node->data[-1] = 0;
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
pool.free_list = node;
|
pool.free_list = node;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -150,12 +144,6 @@ static void shrink_node_if_needed(malloc_pool_t& pool, malloc_node_t* node, size
|
||||||
next->size = node_end - (uint8_t*)next;
|
next->size = node_end - (uint8_t*)next;
|
||||||
next->last = node->last;
|
next->last = node->last;
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
||||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
|
||||||
next->data[-1] = 0;
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
node->last = false;
|
node->last = false;
|
||||||
|
|
||||||
// insert excess node to free list
|
// insert excess node to free list
|
||||||
|
@ -196,29 +184,6 @@ static void* allocate_from_pool(size_t pool_index, size_t size)
|
||||||
|
|
||||||
static malloc_node_t* node_from_data_pointer(void* data_pointer)
|
static malloc_node_t* node_from_data_pointer(void* data_pointer)
|
||||||
{
|
{
|
||||||
if (((uint8_t*)data_pointer)[-1])
|
|
||||||
{
|
|
||||||
malloc_pool_t* pool = nullptr;
|
|
||||||
for (size_t i = 0; i < s_malloc_pool_count; i++)
|
|
||||||
{
|
|
||||||
if (!s_malloc_pools[i].start)
|
|
||||||
continue;
|
|
||||||
if (data_pointer < s_malloc_pools[i].start)
|
|
||||||
continue;
|
|
||||||
if (data_pointer > s_malloc_pools[i].end())
|
|
||||||
continue;
|
|
||||||
pool = &s_malloc_pools[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(pool);
|
|
||||||
|
|
||||||
auto* node = (malloc_node_t*)pool->start;
|
|
||||||
for (; (uint8_t*)node < pool->end(); node = node->next())
|
|
||||||
if (node->data < data_pointer && data_pointer < node->next())
|
|
||||||
return node;
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (malloc_node_t*)((uint8_t*)data_pointer - sizeof(malloc_node_t));
|
return (malloc_node_t*)((uint8_t*)data_pointer - sizeof(malloc_node_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,16 +344,52 @@ int posix_memalign(void** memptr, size_t alignment, size_t size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* unaligned = (uint8_t*)malloc(size + alignment);
|
if (alignment < s_malloc_default_align)
|
||||||
|
alignment = s_malloc_default_align;
|
||||||
|
|
||||||
|
void* unaligned = malloc(size + alignment + sizeof(malloc_node_t));
|
||||||
if (unaligned == nullptr)
|
if (unaligned == nullptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (auto rem = (uintptr_t)unaligned % alignment)
|
pthread_mutex_lock(&s_malloc_mutex);
|
||||||
{
|
|
||||||
unaligned += alignment - rem;
|
|
||||||
unaligned[-1] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*memptr = unaligned;
|
auto* node = node_from_data_pointer(unaligned);
|
||||||
|
auto& pool = pool_from_node(node);
|
||||||
|
|
||||||
|
// NOTE: gcc does not like accessing the node from pointer returned by malloc
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||||
|
if (reinterpret_cast<uintptr_t>(unaligned) % alignment)
|
||||||
|
{
|
||||||
|
uintptr_t curr_data_address = reinterpret_cast<uintptr_t>(unaligned);
|
||||||
|
|
||||||
|
uintptr_t next_data_address = curr_data_address + sizeof(malloc_node_t);
|
||||||
|
if (auto rem = next_data_address % alignment)
|
||||||
|
next_data_address += alignment - rem;
|
||||||
|
|
||||||
|
auto* next = node_from_data_pointer(reinterpret_cast<void*>(next_data_address));
|
||||||
|
next->size = reinterpret_cast<uintptr_t>(node->next()) - reinterpret_cast<uintptr_t>(next);
|
||||||
|
next->allocated = true;
|
||||||
|
assert(next->data_size() >= size);
|
||||||
|
|
||||||
|
node->size = reinterpret_cast<uintptr_t>(next) - reinterpret_cast<uintptr_t>(node);
|
||||||
|
node->allocated = false;
|
||||||
|
|
||||||
|
// add node to free list
|
||||||
|
if (pool.free_list)
|
||||||
|
pool.free_list->prev_free = node;
|
||||||
|
node->prev_free = nullptr;
|
||||||
|
node->next_free = pool.free_list;
|
||||||
|
pool.free_list = node;
|
||||||
|
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
shrink_node_if_needed(pool, node, size);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&s_malloc_mutex);
|
||||||
|
|
||||||
|
*memptr = node->data;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue