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)
|
chunked::chunked (std::size_t initial_size, std::size_t _chunk_size)
|
||||||
: m_chunk (_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);
|
auto const initial_arenas = cruft::divup (initial_size, m_chunk);
|
||||||
m_data.resize (initial_arenas);
|
m_data.resize (initial_arenas);
|
||||||
|
|
||||||
for (auto &i: m_data) {
|
for (auto &i: m_data) {
|
||||||
i.data = new std::byte[m_chunk];
|
i.head = i.remain.data = new std::byte[m_chunk];
|
||||||
*i.node = {
|
*i.remain.node = {
|
||||||
.size = m_chunk,
|
.size = m_chunk,
|
||||||
.next = nullptr
|
.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*
|
void*
|
||||||
chunked::do_allocate (std::size_t size, std::size_t alignment)
|
chunked::do_allocate (std::size_t size, std::size_t alignment)
|
||||||
{
|
{
|
||||||
// Find a chunk that can service this allocation.
|
// Find a chunk that can service this allocation.
|
||||||
for (auto &i: m_data) {
|
for (auto &i: m_data) {
|
||||||
if (i.node->size < size + alignment)
|
if (i.remain.node->size < size + alignment)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto base = cruft::align::up (i.data, alignment);
|
auto base = cruft::align::up (i.remain.data, alignment);
|
||||||
std::byte* newbase = base + size;
|
std::byte* newbase = base + size;
|
||||||
if (newbase > i.data + i.node->size)
|
if (newbase > i.remain.data + i.remain.node->size)
|
||||||
continue;
|
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.remain.data = newbase;
|
||||||
i.node->size = newsize;
|
i.remain.node->size = newsize;
|
||||||
|
|
||||||
return base;
|
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.
|
// 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::size_t allocation_size = cruft::max (size + alignment, m_chunk);
|
||||||
std::unique_ptr<std::byte[]> ptr (new std::byte[allocation_size]);
|
std::unique_ptr<std::byte[]> ptr (new std::byte[allocation_size]);
|
||||||
m_data.push_back (arena { ptr.get () });
|
m_data.push_back (
|
||||||
m_data.back ().node->size = allocation_size;
|
::cruft::alloc::chunked::arena {
|
||||||
m_data.back ().node->next = m_data.back ().node;
|
.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 ();
|
ptr.release ();
|
||||||
return do_allocate (size, alignment);
|
return do_allocate (size, alignment);
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ namespace cruft::alloc {
|
|||||||
|
|
||||||
explicit chunked (std::size_t initial_size);
|
explicit chunked (std::size_t initial_size);
|
||||||
chunked (std::size_t initial_size, std::size_t chunk_size);
|
chunked (std::size_t initial_size, std::size_t chunk_size);
|
||||||
|
~chunked () noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* do_allocate (
|
void* do_allocate (
|
||||||
@ -82,14 +83,19 @@ namespace cruft::alloc {
|
|||||||
|
|
||||||
std::size_t m_chunk;
|
std::size_t m_chunk;
|
||||||
|
|
||||||
struct node_t {
|
struct allocation_t {
|
||||||
std::size_t size;
|
std::size_t size;
|
||||||
node_t* next;
|
allocation_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
union arena {
|
union node {
|
||||||
std::byte *data;
|
std::byte *data;
|
||||||
node_t *node;
|
allocation_t *node;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arena {
|
||||||
|
std::byte *head;
|
||||||
|
node remain;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<arena> m_data;
|
std::vector<arena> m_data;
|
||||||
|
Loading…
Reference in New Issue
Block a user