diff options
author | 2019-02-14 21:34:30 +0100 | |
---|---|---|
committer | 2019-02-16 00:05:21 +0100 | |
commit | b113d0c26d8214b8820a152f5bc20496c564b7d3 (patch) | |
tree | c4a590b84ad26f3cd82b3c26166cd71730087114 /src/lib/netlist/plib/pmempool.h | |
parent | 417dab47cb633c447ba469f7b3a6460ed774422f (diff) |
netlist: memory pool now supports aligned storage. (nw)
Set USE_MEMPOOL to 1 to try this (max 5% performance increase).
For mingw, there is no alignment support. This triggers -Wattribute
errors which due to -Werror crash the build.
Diffstat (limited to 'src/lib/netlist/plib/pmempool.h')
-rw-r--r-- | src/lib/netlist/plib/pmempool.h | 102 |
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_ */ |