alloc/chunked: actually free the memory at destructor time
This commit is contained in:
parent
8339c55baa
commit
fc2d9e77c1
@ -26,14 +26,14 @@ chunked::chunked (std::size_t initial_size)
|
||||
chunked::chunked (std::size_t initial_size, std::size_t _chunk_size)
|
||||
: m_chunk (_chunk_size)
|
||||
{
|
||||
m_chunk = cruft::max (m_chunk, sizeof (node_t));
|
||||
m_chunk = cruft::max (m_chunk, sizeof (allocation_t));
|
||||
|
||||
auto const initial_arenas = cruft::divup (initial_size, m_chunk);
|
||||
m_data.resize (initial_arenas);
|
||||
|
||||
for (auto &i: m_data) {
|
||||
i.data = new std::byte[m_chunk];
|
||||
*i.node = {
|
||||
i.head = i.remain.data = new std::byte[m_chunk];
|
||||
*i.remain.node = {
|
||||
.size = m_chunk,
|
||||
.next = nullptr
|
||||
};
|
||||
@ -41,24 +41,32 @@ chunked::chunked (std::size_t initial_size, std::size_t _chunk_size)
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
chunked::~chunked () noexcept
|
||||
{
|
||||
for (auto &i: m_data)
|
||||
delete [] i.head;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void*
|
||||
chunked::do_allocate (std::size_t size, std::size_t alignment)
|
||||
{
|
||||
// Find a chunk that can service this allocation.
|
||||
for (auto &i: m_data) {
|
||||
if (i.node->size < size + alignment)
|
||||
if (i.remain.node->size < size + alignment)
|
||||
continue;
|
||||
|
||||
auto base = cruft::align::up (i.data, alignment);
|
||||
auto base = cruft::align::up (i.remain.data, alignment);
|
||||
std::byte* newbase = base + size;
|
||||
if (newbase > i.data + i.node->size)
|
||||
if (newbase > i.remain.data + i.remain.node->size)
|
||||
continue;
|
||||
|
||||
std::size_t newsize = i.data + i.node->size - newbase;
|
||||
std::size_t newsize = i.remain.data + i.remain.node->size - newbase;
|
||||
|
||||
i.data = newbase;
|
||||
i.node->size = newsize;
|
||||
i.remain.data = newbase;
|
||||
i.remain.node->size = newsize;
|
||||
|
||||
return base;
|
||||
}
|
||||
@ -66,9 +74,14 @@ chunked::do_allocate (std::size_t size, std::size_t alignment)
|
||||
// No chunk was found. We need to allocate a new chunk of at least enough size.
|
||||
std::size_t allocation_size = cruft::max (size + alignment, m_chunk);
|
||||
std::unique_ptr<std::byte[]> ptr (new std::byte[allocation_size]);
|
||||
m_data.push_back (arena { ptr.get () });
|
||||
m_data.back ().node->size = allocation_size;
|
||||
m_data.back ().node->next = m_data.back ().node;
|
||||
m_data.push_back (
|
||||
::cruft::alloc::chunked::arena {
|
||||
.head = ptr.get (),
|
||||
.remain = { .data = ptr.get (), },
|
||||
}
|
||||
);
|
||||
m_data.back ().remain.node->size = allocation_size;
|
||||
m_data.back ().remain.node->next = m_data.back ().remain.node;
|
||||
ptr.release ();
|
||||
return do_allocate (size, alignment);
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ namespace cruft::alloc {
|
||||
|
||||
explicit chunked (std::size_t initial_size);
|
||||
chunked (std::size_t initial_size, std::size_t chunk_size);
|
||||
~chunked () noexcept;
|
||||
|
||||
private:
|
||||
void* do_allocate (
|
||||
@ -82,14 +83,19 @@ namespace cruft::alloc {
|
||||
|
||||
std::size_t m_chunk;
|
||||
|
||||
struct node_t {
|
||||
struct allocation_t {
|
||||
std::size_t size;
|
||||
node_t* next;
|
||||
allocation_t* next;
|
||||
};
|
||||
|
||||
union arena {
|
||||
union node {
|
||||
std::byte *data;
|
||||
node_t *node;
|
||||
allocation_t *node;
|
||||
};
|
||||
|
||||
struct arena {
|
||||
std::byte *head;
|
||||
node remain;
|
||||
};
|
||||
|
||||
std::vector<arena> m_data;
|
||||
|
Loading…
Reference in New Issue
Block a user