summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pmempool.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/pmempool.h')
-rw-r--r--src/lib/netlist/plib/pmempool.h238
1 files changed, 129 insertions, 109 deletions
diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h
index 69de70000d9..29712601237 100644
--- a/src/lib/netlist/plib/pmempool.h
+++ b/src/lib/netlist/plib/pmempool.h
@@ -28,127 +28,38 @@ namespace plib {
//============================================================
template <typename BASEARENA, std::size_t MINALIGN = PALIGN_MIN_SIZE>
- class mempool_arena : public arena_base<mempool_arena<BASEARENA, MINALIGN>, false, false>
+ class mempool_arena : public arena_base<mempool_arena<BASEARENA, MINALIGN>, MINALIGN, false, false>
{
public:
using size_type = typename BASEARENA::size_type;
- using base_type = arena_base<mempool_arena<BASEARENA, MINALIGN>, false, false>;
+ using base_type = arena_base<mempool_arena<BASEARENA, MINALIGN>, MINALIGN, false, false>;
+
template <class T>
using base_allocator_type = typename BASEARENA::template allocator_type<T>;
+ using block_align = std::integral_constant<size_t, 1024>;
- mempool_arena(size_t min_align = MINALIGN, size_t min_alloc = (1<<21))
- : m_min_alloc(min_alloc)
- , m_min_align(min_align)
- , m_block_align(1024)
- , m_blocks(base_allocator_type<block *>(m_arena))
- {
- }
+ mempool_arena(size_t min_alloc = (1<<21));
PCOPYASSIGNMOVE(mempool_arena, delete)
- ~mempool_arena()
- {
- for (auto & b : m_blocks)
- {
- if (b->m_num_alloc != 0)
- {
- plib::perrlogger("Found {} info blocks\n", m_info.size());
- plib::perrlogger("Found block with {} dangling allocations\n", b->m_num_alloc);
- }
- detail::free(m_arena, b);
- }
- if (!m_info.empty())
- plib::perrlogger("Still found {} info blocks after mempool deleted\n", m_info.size());
- }
+ ~mempool_arena();
- void *allocate(size_t align, size_t size)
- {
- block *b = nullptr;
-
- if (align < m_min_align)
- align = m_min_align;
+ void *allocate(size_t align, size_t size);
- size_t rs = size + align;
-
- for (auto &bs : m_blocks)
- {
- if (bs->m_free > rs)
- {
- b = bs;
- break;
- }
- }
- if (b == nullptr)
- {
- b = new_block(rs);
- }
- b->m_free -= rs;
- b->m_num_alloc++;
- void *ret = reinterpret_cast<void *>(b->m_data + b->m_cur); // NOLINT(cppcoreguidelines-pro-type-reinterpret
- auto capacity(rs);
- ret = std::align(align, size, ret, capacity);
- m_info.insert({ ret, info(b, b->m_cur)});
- rs -= (capacity - size);
- b->m_cur += rs;
- this->inc_alloc_stat(size);
-
- return ret;
- }
-
- void deallocate(void *ptr, size_t size) noexcept
- {
- auto it = m_info.find(ptr);
- if (it == m_info.end())
- plib::terminate("mempool::free - pointer not found");
- block *b = it->second.m_block;
- if (b->m_num_alloc == 0)
- plib::terminate("mempool::free - double free was called");
- else
- {
- mempool_arena &mp = b->m_mempool;
- b->m_num_alloc--;
- mp.dec_alloc_stat(size);
- if (b->m_num_alloc == 0)
- {
- auto itb = std::find(mp.m_blocks.begin(), mp.m_blocks.end(), b);
- if (itb == mp.m_blocks.end())
- plib::terminate("mempool::free - block not found");
-
- mp.m_blocks.erase(itb);
- detail::free(mp.base_arena(), b);
- }
- m_info.erase(it);
- }
- }
+ void deallocate(void *ptr, std::size_t alignment, size_t size) noexcept;
bool operator ==(const mempool_arena &rhs) const noexcept { return this == &rhs; }
- BASEARENA &base_arena() noexcept { return m_arena; }
private:
struct block
{
- block(mempool_arena &mp, size_type min_bytes)
- : m_num_alloc(0)
- , m_cur(0)
- , m_data(nullptr)
- , m_mempool(mp)
- {
- min_bytes = std::max(mp.m_min_alloc, min_bytes);
- m_free = min_bytes;
- m_bytes_allocated = (min_bytes + mp.m_block_align); // - 1); // & ~(mp.m_min_align - 1);
- // NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
- //m_data_allocated = new std::uint8_t[alloc_bytes];
- m_data_allocated = static_cast<std::uint8_t *>(mp.base_arena().allocate(mp.m_block_align, m_bytes_allocated));
- void *r = m_data_allocated;
- std::align(mp.m_block_align, min_bytes, r, m_bytes_allocated);
- m_data = reinterpret_cast<std::uint8_t *>(r); // NOLINT(cppcoreguidelines-pro-type-reinterpret
- }
+ block(mempool_arena &mp, size_type min_bytes);
~block()
{
//::operator delete(m_data_allocated);
//delete [] m_data_allocated;
- m_mempool.base_arena().deallocate(m_data_allocated, m_bytes_allocated);
+ m_mempool.base_arena().deallocate(m_data_allocated, mempool_arena::block_align(), m_bytes_allocated);
}
block(const block &) = delete;
@@ -167,7 +78,7 @@ namespace plib {
struct info
{
- info(block *b, size_type p) : m_block(b), m_pos(p) { }
+ info(block *b, size_type p, size_type orig_size) : m_block(b), m_pos(p), m_orig_size(orig_size) { }
info(const info &) = default;
info &operator=(const info &) = default;
info(info &&) noexcept = default;
@@ -176,28 +87,137 @@ namespace plib {
block * m_block;
size_type m_pos;
+ size_type m_orig_size;
};
block * new_block(size_type min_bytes)
{
- auto *b = detail::alloc<block>(m_arena, *this, min_bytes);
+ auto *b = detail::alloc<block, 0>(base_arena(), *this, min_bytes);
m_blocks.push_back(b);
return b;
}
size_t m_min_alloc;
- size_t m_min_align;
- size_t m_block_align;
- BASEARENA m_arena;
+ static BASEARENA &base_arena()
+ {
+ static BASEARENA s_arena;
+ return s_arena;
+ }
+
+ using info_type = std::pair<void * const, info>;
- using base_allocator_typex = typename BASEARENA::template allocator_type<std::pair<void * const, info>>;
- std::unordered_map<void *, info, std::hash<void *>, std::equal_to<void *>,
- base_allocator_typex> m_info;
-// std::unordered_map<void *, info> m_info;
- std::vector<block *, typename BASEARENA::template allocator_type<block *>> m_blocks;
+ using info_allocator_type = typename BASEARENA::template allocator_type<info_type>;
+ std::unordered_map<void *, info, std::hash<void *>, std::equal_to<>,
+ info_allocator_type> m_info;
+
+ plib::arena_vector<BASEARENA, block *> m_blocks;
};
+ template <typename BASEARENA, std::size_t MINALIGN>
+ mempool_arena<BASEARENA, MINALIGN>::mempool_arena(size_t min_alloc)
+ : m_min_alloc(min_alloc)
+ //, m_blocks(base_allocator_type<block *>(base_arena()))
+ , m_blocks(base_arena())
+ {
+ }
+
+ template <typename BASEARENA, std::size_t MINALIGN>
+ mempool_arena<BASEARENA, MINALIGN>::~mempool_arena()
+ {
+ for (auto & b : m_blocks)
+ {
+ if (b->m_num_alloc != 0)
+ {
+ plib::perrlogger("Found {} info blocks\n", m_info.size());
+ plib::perrlogger("Found block with {} dangling allocations\n", b->m_num_alloc);
+ }
+ detail::free<0>(base_arena(), b);
+ }
+ if (!m_info.empty())
+ plib::perrlogger("Still found {} info blocks after mempool deleted\n", m_info.size());
+ }
+
+ template <typename BASEARENA, std::size_t MINALIGN>
+ void * mempool_arena<BASEARENA, MINALIGN>::allocate(size_t align, size_t size)
+ {
+ block *b = nullptr;
+
+ if (align < MINALIGN)
+ align = MINALIGN;
+
+ size_t rs = size + align;
+
+ for (auto &bs : m_blocks)
+ {
+ if (bs->m_free > rs)
+ {
+ b = bs;
+ break;
+ }
+ }
+ if (b == nullptr)
+ {
+ b = new_block(rs);
+ }
+ b->m_free -= rs;
+ b->m_num_alloc++;
+ void *ret = reinterpret_cast<void *>(b->m_data + b->m_cur); // NOLINT(cppcoreguidelines-pro-type-reinterpret
+ auto capacity(rs);
+ ret = std::align(align, size, ret, capacity);
+ m_info.insert({ ret, info(b, b->m_cur, size)});
+ rs -= (capacity - size);
+ b->m_cur += rs;
+ this->inc_alloc_stat(size);
+
+ return ret;
+ }
+
+ template <typename BASEARENA, std::size_t MINALIGN>
+ void mempool_arena<BASEARENA, MINALIGN>::deallocate(void *ptr, [[maybe_unused]] std::size_t alignment, size_t size) noexcept
+ {
+ auto it = m_info.find(ptr);
+ if (it == m_info.end())
+ plib::terminate("mempool::free - pointer not found");
+ block *b = it->second.m_block;
+ if (b->m_num_alloc == 0)
+ plib::terminate("mempool::free - double free was called");
+ if (it->second.m_orig_size != size)
+ plib::perrlogger("Size mismatch original {} vs {}\n", it->second.m_orig_size, size);
+
+ mempool_arena &mp = b->m_mempool;
+ b->m_num_alloc--;
+ mp.dec_alloc_stat(size);
+ if (b->m_num_alloc == 0)
+ {
+ auto itb = std::find(mp.m_blocks.begin(), mp.m_blocks.end(), b);
+ if (itb == mp.m_blocks.end())
+ plib::terminate("mempool::free - block not found");
+
+ mp.m_blocks.erase(itb);
+ detail::free<0>(mp.base_arena(), b);
+ }
+ m_info.erase(it);
+ }
+
+ template <typename BASEARENA, std::size_t MINALIGN>
+ mempool_arena<BASEARENA, MINALIGN>::block::block(mempool_arena &mp, size_type min_bytes)
+ : m_num_alloc(0)
+ , m_cur(0)
+ , m_data(nullptr)
+ , m_mempool(mp)
+ {
+ min_bytes = std::max(mp.m_min_alloc, min_bytes);
+ m_free = min_bytes;
+ m_bytes_allocated = (min_bytes + mempool_arena::block_align()); // - 1); // & ~(mp.m_min_align - 1);
+ // NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
+ //m_data_allocated = new std::uint8_t[alloc_bytes];
+ m_data_allocated = static_cast<std::uint8_t *>(mp.base_arena().allocate(mempool_arena::block_align(), m_bytes_allocated));
+ void *r = m_data_allocated;
+ std::align(mempool_arena::block_align(), min_bytes, r, m_bytes_allocated);
+ m_data = reinterpret_cast<std::uint8_t *>(r); // NOLINT(cppcoreguidelines-pro-type-reinterpret
+ }
+
} // namespace plib
#endif // PMEMPOOL_H_