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.h102
1 files changed, 95 insertions, 7 deletions
diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h
index 2e15076b477..f5691aa2c43 100644
--- a/src/lib/netlist/plib/pmempool.h
+++ b/src/lib/netlist/plib/pmempool.h
@@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
- * palloc.h
+ * pmempool.h
*
*/
@@ -89,25 +89,28 @@ namespace plib {
{
}
-
COPYASSIGNMOVE(mempool, delete)
~mempool()
{
+
for (auto & b : m_blocks)
{
if (b->m_num_alloc != 0)
{
+ plib::perrlogger("Found {} info blocks\n", sinfo().size());
plib::perrlogger("Found block with {} dangling allocations\n", b->m_num_alloc);
}
::operator delete(b->m_data);
}
}
-
- void *alloc(size_t size)
+ void *alloc(size_t size, size_t align)
{
- size_t rs = (size + m_min_align - 1) & ~(m_min_align - 1);
+ if (align < m_min_align)
+ align = m_min_align;
+
+ size_t rs = (size + align - 1) & ~(align - 1);
for (auto &b : m_blocks)
{
if (b->m_free > rs)
@@ -115,8 +118,11 @@ namespace plib {
b->m_free -= rs;
b->m_num_alloc++;
auto ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
+ auto capacity(rs);
+ std::align(align, size, ret, capacity);
sinfo().insert({ ret, info(b, b->m_cur)});
b->m_cur += rs;
+
return ret;
}
}
@@ -125,15 +131,20 @@ namespace plib {
b->m_num_alloc = 1;
b->m_free = m_min_alloc - rs;
auto ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
+ auto capacity(rs);
+ std::align(align, size, ret, capacity);
sinfo().insert({ ret, info(b, b->m_cur)});
b->m_cur += rs;
return ret;
}
}
- void free(void *ptr)
+ static void free(void *ptr)
{
- info i = sinfo().find(ptr)->second;
+ auto it = sinfo().find(ptr);
+ if (it == sinfo().end())
+ printf("pointer not found\n");
+ info i = it->second;
block *b = i.m_block;
if (b->m_num_alloc == 0)
throw plib::pexception("mempool::free - double free was called\n");
@@ -143,11 +154,88 @@ namespace plib {
//b->cur_ptr = b->data;
}
b->m_num_alloc--;
+ //printf("Freeing in block %p %lu\n", b, b->m_num_alloc);
+ sinfo().erase(it);
}
+ template <typename T>
+ struct pool_deleter
+ {
+ constexpr pool_deleter() noexcept = default;
+
+ template<typename U, typename = typename
+ std::enable_if<std::is_convertible< U*, T*>::value>::type>
+ pool_deleter(const pool_deleter<U>&) noexcept { }
+
+ void operator()(T *p) const
+ {
+ p->~T();
+ mempool::free(p);
+ }
+ };
+
+ template <typename T>
+ using poolptr = plib::owned_ptr<T, pool_deleter<T>>;
+
+ template<typename T, typename... Args>
+ poolptr<T> make_poolptr(Args&&... args)
+ {
+ auto mem = this->alloc(sizeof(T), alignof(T));
+ auto *obj = new (mem) T(std::forward<Args>(args)...);
+ poolptr<T> a(obj, true);
+ return std::move(a);
+ }
};
+ class mempool_default
+ {
+ private:
+
+ size_t m_min_alloc;
+ size_t m_min_align;
+
+ public:
+
+ mempool_default(size_t min_alloc, size_t min_align)
+ : m_min_alloc(min_alloc), m_min_align(min_align)
+ {
+ }
+
+ COPYASSIGNMOVE(mempool_default, delete)
+
+ ~mempool_default()
+ {
+ }
+
+ void *alloc(size_t size)
+ {
+ plib::unused_var(m_min_alloc); // -Wunused-private-field fires without
+ plib::unused_var(m_min_align);
+
+ return ::operator new(size);
+ }
+
+ static void free(void *ptr)
+ {
+ ::operator delete(ptr);
+ }
+
+ template <typename T>
+ using poolptr = plib::owned_ptr<T>;
+
+ template<typename T, typename... Args>
+ poolptr<T> make_poolptr(Args&&... args)
+ {
+ auto mem(alloc(sizeof(T)));
+ auto *obj = new (mem) T(std::forward<Args>(args)...);
+ poolptr<T> a(obj, true);
+ return std::move(a);
+ }
+
+ };
+
+
} // namespace plib
#endif /* PMEMPOOL_H_ */