summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/palloc.h
diff options
context:
space:
mode:
author andreasnaive <andreasnaive@gmail.com>2019-03-25 23:13:40 +0100
committer andreasnaive <andreasnaive@gmail.com>2019-03-25 23:13:40 +0100
commitb380514764cf857469bae61c11143a19f79a74c5 (patch)
tree63c8012e262618f08a332da31dd714281aa2c5ed /src/lib/netlist/plib/palloc.h
parentc24473ddff715ecec2e258a6eb38960cf8c8e98e (diff)
Revert "conflict resolution (nw)"
This reverts commit c24473ddff715ecec2e258a6eb38960cf8c8e98e, reversing changes made to 009cba4fb8102102168ef32870892438327f3705.
Diffstat (limited to 'src/lib/netlist/plib/palloc.h')
-rw-r--r--src/lib/netlist/plib/palloc.h513
1 files changed, 129 insertions, 384 deletions
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h
index 15fede3a99b..a35bc50ff17 100644
--- a/src/lib/netlist/plib/palloc.h
+++ b/src/lib/netlist/plib/palloc.h
@@ -8,427 +8,172 @@
#ifndef PALLOC_H_
#define PALLOC_H_
-#include "pconfig.h"
#include "pstring.h"
-#include "ptypes.h"
-#include <cstddef>
-#include <cstdlib>
-#include <memory>
-#include <type_traits>
-#include <utility>
#include <vector>
-
-#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
-#include <malloc.h>
-#endif
+#include <memory>
namespace plib {
- //============================================================
- // Standard arena_deleter
- //============================================================
-
- template <typename P, typename T>
- struct arena_deleter
- {
- //using arena_storage_type = P *;
- using arena_storage_type = typename std::conditional<P::is_stateless, P, P *>::type;
- template <typename X, typename Y = void>
- typename std::enable_if<!X::is_stateless, X&>::type getref(X *x) { return *x;}
- template <typename X, typename Y = void *>
- typename std::enable_if<std::remove_pointer<X>::type::is_stateless, X&>::type
- getref(X &x, Y y = nullptr)
- {
- unused_var(y);
- return x;
- }
-
- constexpr arena_deleter(arena_storage_type a = arena_storage_type()) noexcept
- : m_a(a) { }
-
- template<typename PU, typename U, typename = typename
- std::enable_if<std::is_convertible< U*, T*>::value>::type>
- arena_deleter(const arena_deleter<PU, U> &rhs) noexcept : m_a(rhs.m_a) { }
-
- void operator()(T *p) //const
- {
- /* call destructor */
- p->~T();
- getref(m_a).deallocate(p);
- }
- //private:
- arena_storage_type m_a;
- };
-
- //============================================================
- // owned_ptr: smart pointer with ownership information
- //============================================================
-
- template <typename SC, typename D>
- class owned_ptr
- {
- public:
-
- using pointer = SC *;
- using element_type = SC;
- using deleter_type = D;
-
- owned_ptr()
- : m_ptr(nullptr), m_deleter(), m_is_owned(true) { }
-
- template <typename, typename>
- friend class owned_ptr;
-
- owned_ptr(pointer p, bool owned) noexcept
- : m_ptr(p), m_deleter(), m_is_owned(owned)
- { }
-
- owned_ptr(pointer p, bool owned, D deleter) noexcept
- : m_ptr(p), m_deleter(deleter), m_is_owned(owned)
- { }
-
-
- owned_ptr(const owned_ptr &r) = delete;
- owned_ptr & operator =(owned_ptr &r) = delete;
-
- template<typename DC, typename DC_D>
- owned_ptr & operator =(owned_ptr<DC, DC_D> &&r)
- {
- if (m_is_owned && (m_ptr != nullptr))
- //delete m_ptr;
- m_deleter(m_ptr);
- m_is_owned = r.m_is_owned;
- m_ptr = r.m_ptr;
- m_deleter = r.m_deleter;
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- return *this;
- }
-
- owned_ptr(owned_ptr &&r) noexcept
- : m_ptr(r.m_ptr)
- , m_deleter(r.m_deleter)
- , m_is_owned(r.m_is_owned)
- {
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- }
-
- owned_ptr &operator=(owned_ptr &&r) noexcept
- {
- if (m_is_owned && (m_ptr != nullptr))
- //delete m_ptr;
- m_deleter(m_ptr);
- m_is_owned = r.m_is_owned;
- m_ptr = r.m_ptr;
- m_deleter = std::move(r.m_deleter);
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- return *this;
- }
-
- template<typename DC, typename DC_D>
- owned_ptr(owned_ptr<DC, DC_D> &&r) noexcept
- : m_ptr(static_cast<pointer >(r.get()))
- , m_deleter(r.m_deleter)
- , m_is_owned(r.is_owned())
- {
- r.release();
- }
-
- ~owned_ptr() noexcept
- {
- if (m_is_owned && (m_ptr != nullptr))
- {
- //delete m_ptr;
- m_deleter(m_ptr);
- }
- m_is_owned = false;
- m_ptr = nullptr;
- }
-
- /**
- * \brief Return @c true if the stored pointer is not null.
- */
- explicit operator bool() const noexcept { return m_ptr != nullptr; }
-
- pointer release()
- {
- pointer tmp = m_ptr;
- m_is_owned = false;
- m_ptr = nullptr;
- return tmp;
- }
-
- bool is_owned() const { return m_is_owned; }
-
- pointer operator ->() const noexcept { return m_ptr; }
- typename std::add_lvalue_reference<element_type>::type operator *() const noexcept { return *m_ptr; }
- pointer get() const noexcept { return m_ptr; }
-
- deleter_type& get_deleter() noexcept { return m_deleter; }
- const deleter_type& get_deleter() const noexcept { return m_deleter; }
-
- private:
- pointer m_ptr;
- D m_deleter;
- bool m_is_owned;
- };
-
- //============================================================
- // Arena allocator for use with containers
- //============================================================
-
- template <class ARENA, class T, std::size_t ALIGN = alignof(T)>
- class arena_allocator
+//============================================================
+// Memory allocation
+//============================================================
+
+template<typename T, typename... Args>
+T *palloc(Args&&... args)
+{
+ return new T(std::forward<Args>(args)...);
+}
+
+template<typename T>
+void pfree(T *ptr)
+{
+ delete ptr;
+}
+
+template<typename T>
+T* palloc_array(const std::size_t num)
+{
+ return new T[num]();
+}
+
+template<typename T>
+void pfree_array(T *ptr)
+{
+ delete [] ptr;
+}
+
+template<typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args&&... args)
+{
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template<typename BC, typename DC, typename... Args>
+static std::unique_ptr<BC> make_unique_base(Args&&... args)
+{
+ std::unique_ptr<BC> ret(new DC(std::forward<Args>(args)...));
+ return ret;
+}
+
+template <typename SC>
+class owned_ptr
+{
+private:
+ owned_ptr()
+ : m_ptr(nullptr), m_is_owned(true) { }
+public:
+ owned_ptr(SC *p, bool owned) noexcept
+ : m_ptr(p), m_is_owned(owned)
+ { }
+
+ owned_ptr(const owned_ptr &r) = delete;
+ owned_ptr & operator =(owned_ptr &r) = delete;
+
+ template<typename DC>
+ owned_ptr & operator =(owned_ptr<DC> &&r)
{
- public:
- using value_type = T;
- static constexpr const std::size_t align_size = ALIGN;
- using arena_type = ARENA;
-
- static_assert(align_size >= alignof(T) && (align_size % alignof(T)) == 0,
- "ALIGN must be greater than alignof(T) and a multiple");
-
- arena_allocator() noexcept
- : m_a(arena_type::instance())
- { }
-
- ~arena_allocator() noexcept = default;
-
- arena_allocator(const arena_allocator &rhs) noexcept = default;
- arena_allocator& operator=(const arena_allocator&) noexcept = delete;
-
- arena_allocator(arena_allocator&&) noexcept = default;
- arena_allocator& operator=(arena_allocator&&) = delete;
-
- arena_allocator(arena_type & a) noexcept : m_a(a)
- {
- }
-
- template <class U>
- arena_allocator(const arena_allocator<ARENA, U, ALIGN>& rhs) noexcept
- : m_a(rhs.m_a)
- {
- }
-
- template <class U> struct rebind
- {
- using other = arena_allocator<ARENA, U, ALIGN>;
- };
-
- T* allocate(std::size_t n)
- {
- return reinterpret_cast<T *>(m_a.allocate(ALIGN, sizeof(T) * n));
- }
-
- void deallocate(T* p, std::size_t n) noexcept
- {
- unused_var(n);
- m_a.deallocate(p);
- }
-
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- friend bool operator==(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept;
-
- template <class AU, class U, std::size_t A> friend class arena_allocator;
- private:
- arena_type &m_a;
- };
-
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- inline bool operator==(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept
- {
- return A1 == A2 && rhs.m_a == lhs.m_a;
- }
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- inline bool operator!=(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept
- {
- return !(lhs == rhs);
+ if (m_is_owned && (m_ptr != nullptr))
+ delete m_ptr;
+ m_is_owned = r.m_is_owned;
+ m_ptr = r.m_ptr;
+ r.m_is_owned = false;
+ r.m_ptr = nullptr;
+ return *this;
}
- //============================================================
- // Memory allocation
- //============================================================
-
- struct aligned_arena
+ owned_ptr(owned_ptr &&r) noexcept
{
- static constexpr const bool is_stateless = true;
- template <class T, std::size_t ALIGN = alignof(T)>
- using allocator_type = arena_allocator<aligned_arena, T, ALIGN>;
-
- template <typename T>
- using owned_pool_ptr = plib::owned_ptr<T, arena_deleter<aligned_arena, T>>;
-
- static inline aligned_arena &instance()
- {
- static aligned_arena s_arena;
- return s_arena;
- }
-
- static inline void *allocate( size_t alignment, size_t size )
- {
- #if (USE_ALIGNED_ALLOCATION)
- #if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
- return _aligned_malloc(size, alignment);
- #elif defined(__APPLE__)
- void* p;
- if (::posix_memalign(&p, alignment, size) != 0) {
- p = nullptr;
- }
- return p;
- #else
- return aligned_alloc(alignment, size);
- #endif
- #else
- unused_var(alignment);
- return ::operator new(size);
- #endif
- }
-
- static inline void deallocate( void *ptr )
- {
- #if (USE_ALIGNED_ALLOCATION)
- // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
- free(ptr);
- #else
- ::operator delete(ptr);
- #endif
- }
-
- template<typename T, typename... Args>
- owned_pool_ptr<T> make_poolptr(Args&&... args)
- {
- auto *mem = allocate(alignof(T), sizeof(T));
- return owned_pool_ptr<T>(new (mem) T(std::forward<Args>(args)...), true, arena_deleter<aligned_arena, T>(*this));
- }
-
- };
-
- template <typename T, std::size_t ALIGN>
- /*inline */ C14CONSTEXPR T *assume_aligned_ptr(T *p) noexcept
- {
- static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
- static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
- //auto t = reinterpret_cast<std::uintptr_t>(p);
- //if (t & (ALIGN-1))
- // printf("alignment error!");
-#if (USE_ALIGNED_HINTS)
- return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN));
-#else
- return p;
-#endif
+ m_is_owned = r.m_is_owned;
+ m_ptr = r.m_ptr;
+ r.m_is_owned = false;
+ r.m_ptr = nullptr;
}
- template <typename T, std::size_t ALIGN>
- constexpr const T *assume_aligned_ptr(const T *p) noexcept
+ template<typename DC>
+ owned_ptr(owned_ptr<DC> &&r) noexcept
{
- static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
- static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
-#if (USE_ALIGNED_HINTS)
- return reinterpret_cast<const T *>(__builtin_assume_aligned(p, ALIGN));
-#else
- return p;
-#endif
+ m_ptr = static_cast<SC *>(r.get());
+ m_is_owned = r.is_owned();
+ r.release();
}
- // FIXME: remove
- template<typename T, typename... Args>
- inline T *pnew(Args&&... args)
+ ~owned_ptr()
{
- auto *p = aligned_arena::allocate(alignof(T), sizeof(T));
- return new(p) T(std::forward<Args>(args)...);
+ if (m_is_owned && (m_ptr != nullptr))
+ delete m_ptr;
+ m_is_owned = false;
+ m_ptr = nullptr;
}
-
- template<typename T>
- inline void pdelete(T *ptr)
+ template<typename DC, typename... Args>
+ static owned_ptr Create(Args&&... args)
{
- ptr->~T();
- aligned_arena::deallocate(ptr);
+ owned_ptr a;
+ DC *x = new DC(std::forward<Args>(args)...);
+ a.m_ptr = static_cast<SC *>(x);
+ return std::move(a);
}
-
- template <typename T>
- using unique_ptr = std::unique_ptr<T, arena_deleter<aligned_arena, T>>;
-
- template<typename T, typename... Args>
- plib::unique_ptr<T> make_unique(Args&&... args)
+ template<typename... Args>
+ static owned_ptr Create(Args&&... args)
{
- return plib::unique_ptr<T>(pnew<T>(std::forward<Args>(args)...));
+ owned_ptr a;
+ a.m_ptr = new SC(std::forward<Args>(args)...);
+ return std::move(a);
}
-
-#if 0
- template<typename T, typename... Args>
- static owned_ptr<T> make_owned(Args&&... args)
+ SC * release()
{
- return owned_ptr<T>(pnew<T>(std::forward<Args>(args)...), true);
+ SC *tmp = m_ptr;
+ m_is_owned = false;
+ m_ptr = nullptr;
+ return tmp;
}
-#endif
-
-
- template <class T, std::size_t ALIGN = alignof(T)>
- using aligned_allocator = aligned_arena::allocator_type<T, ALIGN>;
-
- //============================================================
- // traits to determine alignment size and stride size
- // from types supporting alignment
- //============================================================
- PDEFINE_HAS_MEMBER(has_align, align_size);
+ bool is_owned() const { return m_is_owned; }
- template <typename T, typename X = void>
- struct align_traits
- {
- static constexpr const std::size_t align_size = alignof(std::max_align_t);
- static constexpr const std::size_t value_size = sizeof(typename T::value_type);
- static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
- };
+ SC * operator ->() const { return m_ptr; }
+ SC & operator *() const { return *m_ptr; }
+ SC * get() const { return m_ptr; }
+private:
+ SC *m_ptr;
+ bool m_is_owned;
+};
- template <typename T>
- struct align_traits<T, typename std::enable_if<has_align<T>::value, void>::type>
+class mempool
+{
+private:
+ struct block
{
- static constexpr const std::size_t align_size = T::align_size;
- static constexpr const std::size_t value_size = sizeof(typename T::value_type);
- static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
+ block() : m_num_alloc(0), m_free(0), cur_ptr(nullptr), data(nullptr) { }
+ std::size_t m_num_alloc;
+ std::size_t m_free;
+ char *cur_ptr;
+ char *data;
};
- //============================================================
- // Aligned vector
- //============================================================
+ size_t new_block();
+ size_t mininfosize();
- // FIXME: needs a separate file
- template <class T, std::size_t ALIGN = alignof(T)>
- class aligned_vector : public std::vector<T, aligned_allocator<T, ALIGN>>
+ struct info
{
- public:
- using base = std::vector<T, aligned_allocator<T, ALIGN>>;
+ info() : m_block(0) { }
+ size_t m_block;
+ };
- using reference = typename base::reference;
- using const_reference = typename base::const_reference;
- using pointer = typename base::pointer;
- using const_pointer = typename base::const_pointer;
- using size_type = typename base::size_type;
+ size_t m_min_alloc;
+ size_t m_min_align;
- using base::base;
+ std::vector<block> m_blocks;
- C14CONSTEXPR reference operator[](size_type i) noexcept
- {
- return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
- }
- constexpr const_reference operator[](size_type i) const noexcept
- {
- return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
- }
+public:
+ mempool(size_t min_alloc, size_t min_align);
+ ~mempool();
- pointer data() noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
- const_pointer data() const noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
+ void *alloc(size_t size);
+ void free(void *ptr);
- };
+};
-} // namespace plib
+}
#endif /* PALLOC_H_ */