From 0e07f9ac34ec82066792fb9fdaaf04546b582fab Mon Sep 17 00:00:00 2001 From: couriersud Date: Sun, 24 Feb 2019 13:58:47 +0100 Subject: netlist: more alignment related refactoring. (nw) --- src/lib/netlist/plib/pmatrix2d.h | 82 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/lib/netlist/plib/pmatrix2d.h (limited to 'src/lib/netlist/plib/pmatrix2d.h') diff --git a/src/lib/netlist/plib/pmatrix2d.h b/src/lib/netlist/plib/pmatrix2d.h new file mode 100644 index 00000000000..f0439105e5c --- /dev/null +++ b/src/lib/netlist/plib/pmatrix2d.h @@ -0,0 +1,82 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * pmatrix2d.h + * + * NxM regular matrix + * + */ + +#ifndef PMATRIX2D_H_ +#define PMATRIX2D_H_ + +#include "palloc.h" + +#include +#include +#include +#include +#include + +namespace plib +{ + + + template> + class pmatrix2d + { + public: + using value_type = T; + + static constexpr const std::size_t align_size = align_traits::align_size; + static constexpr const std::size_t stride_size = align_traits::stride_size; + pmatrix2d() + : m_N(0), m_M(0), m_stride(8) + { + } + + pmatrix2d(std::size_t N, std::size_t M) + : m_N(N), m_M(M), m_stride((M+stride_size-1) & ~(stride_size-1)), m_v(N * m_stride) + { + } + + void resize(std::size_t N, std::size_t M) + { + m_N = N; + m_M = M; + m_stride = (M+stride_size-1) & ~(stride_size-1); + m_v.resize(N * m_stride); + } + + C14CONSTEXPR T * operator[] (std::size_t row) noexcept + { + return assume_aligned_ptr(&m_v[m_stride * row]); + } + + constexpr const T * operator[] (std::size_t row) const noexcept + { + return assume_aligned_ptr(&m_v[m_stride * row]); + } + + T & operator()(std::size_t r, std::size_t c) noexcept + { + return (*this)[r][c]; + } + + const T & operator()(std::size_t r, std::size_t c) const noexcept + { + return (*this)[r][c]; + } + + private: + + std::size_t m_N; + std::size_t m_M; + std::size_t m_stride; + + std::vector m_v; + }; + +} // namespace plib + +#endif /* MAT_CR_H_ */ -- cgit v1.2.3-70-g09d2 From 6a3efe52d6dbd2b8dfb4a5fa38e2a855b6353fb9 Mon Sep 17 00:00:00 2001 From: couriersud Date: Mon, 25 Feb 2019 21:17:59 +0100 Subject: netlist: fix bugs in the alignment code. (nw) --- src/lib/netlist/nl_base.h | 6 ++-- src/lib/netlist/plib/palloc.h | 52 ++++++++++++----------------- src/lib/netlist/plib/pconfig.h | 2 +- src/lib/netlist/plib/pmatrix2d.h | 6 ++-- src/lib/netlist/plib/ptypes.h | 53 ++++++++++++++++++++++++++++++ src/lib/netlist/solver/nld_matrix_solver.h | 20 +++++++---- src/lib/netlist/solver/nld_ms_gcr.h | 14 ++++---- src/lib/netlist/solver/nld_ms_gmres.h | 13 ++++---- 8 files changed, 107 insertions(+), 59 deletions(-) (limited to 'src/lib/netlist/plib/pmatrix2d.h') diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index e54d3b1abae..3d2b8cd1364 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -13,9 +13,6 @@ #error "nl_base.h included. Please correct." #endif -#include -#include - #include "plib/palloc.h" // owned_ptr #include "plib/pdynlib.h" #include "plib/pfmtlog.h" @@ -29,6 +26,9 @@ #include "nltypes.h" #include "plib/ptime.h" +#include +#include + //============================================================ // MACROS / New Syntax //============================================================ diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index d8e4ffbb5d7..d7b00262f7f 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -28,8 +28,6 @@ namespace plib { // Memory allocation //============================================================ - static constexpr bool is_pow2(std::size_t v) noexcept { return !(v & (v-1)); } - #if (USE_ALIGNED_ALLOCATION) static inline void *paligned_alloc( size_t alignment, size_t size ) { @@ -52,24 +50,6 @@ namespace plib { free(ptr); } - static constexpr bool is_pow2(std::size_t v) noexcept { return !(v & (v-1)); } - - template - 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(p); - //if (t & (ALIGN-1)) - // printf("alignment error!"); - return reinterpret_cast(__builtin_assume_aligned(p, ALIGN)); - } - - template - inline C14CONSTEXPR const T *assume_aligned_ptr(const T *p) noexcept - { - return reinterpret_cast(__builtin_assume_aligned(p, ALIGN)); - } #else static inline void *paligned_alloc( size_t alignment, size_t size ) { @@ -84,7 +64,7 @@ namespace plib { #endif template - inline C14CONSTEXPR T *assume_aligned_ptr(T *p) noexcept + /*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"); @@ -99,7 +79,7 @@ namespace plib { } template - inline C14CONSTEXPR const T *assume_aligned_ptr(const T *p) noexcept + constexpr const T *assume_aligned_ptr(const 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"); @@ -272,7 +252,7 @@ namespace plib { { public: using value_type = T; - static constexpr const std::size_t align_size = (USE_ALIGNED_ALLOCATION) ? ALIGN : alignof(std::max_align_t); + static constexpr const std::size_t align_size = ALIGN; static_assert(align_size >= alignof(T) && (align_size % alignof(T)) == 0, "ALIGN must be greater than alignof(T) and a multiple"); @@ -340,20 +320,30 @@ namespace plib { 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); +#if 0 static constexpr const std::size_t stride_size = - (sizeof(T) % align_size == 0 ? 1 //T is a multiple of align_size - : (align_size % sizeof(T) != 0 ? align_size // align_size is not a multiple of T - : align_size / sizeof(T))); + ((value_size % align_size) == 0 ? 1 //T is a multiple of align_size + : ((align_size % value_size) != 0 ? align_size // align_size is not a multiple of T + : align_size / value_size)); +#else + static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size; +#endif }; template struct align_traits::value, void>::type> { static constexpr const std::size_t align_size = T::align_size; + static constexpr const std::size_t value_size = sizeof(typename T::value_type); +#if 0 static constexpr const std::size_t stride_size = - (sizeof(T) % align_size == 0 ? 1 //T is a multiple of align_size - : (align_size % sizeof(T) != 0 ? align_size // align_size is not a multiple of T - : align_size / sizeof(T))); + ((value_size % align_size) == 0 ? 1 //T is a multiple of align_size + : ((align_size % value_size) != 0 ? align_size // align_size is not a multiple of T + : align_size / value_size)); +#else + static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size; +#endif }; //============================================================ @@ -377,11 +367,11 @@ namespace plib { C14CONSTEXPR reference operator[](size_type i) noexcept { - return assume_aligned_ptr(&((*this)[0]))[i]; + return assume_aligned_ptr(&(base::operator[](0)))[i]; } constexpr const_reference operator[](size_type i) const noexcept { - return assume_aligned_ptr(&((*this)[0]))[i]; + return assume_aligned_ptr(&(base::operator[](0)))[i]; } pointer data() noexcept { return assume_aligned_ptr(base::data()); } diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 158fb3faae7..c521f24e5f8 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -48,7 +48,7 @@ */ #define PALIGN_CACHELINE (64) -#define PALIGN_VECTOROPT (8) +#define PALIGN_VECTOROPT (32) #define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE) #define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT) diff --git a/src/lib/netlist/plib/pmatrix2d.h b/src/lib/netlist/plib/pmatrix2d.h index f0439105e5c..52228548cbf 100644 --- a/src/lib/netlist/plib/pmatrix2d.h +++ b/src/lib/netlist/plib/pmatrix2d.h @@ -36,15 +36,17 @@ namespace plib } pmatrix2d(std::size_t N, std::size_t M) - : m_N(N), m_M(M), m_stride((M+stride_size-1) & ~(stride_size-1)), m_v(N * m_stride) + : m_N(N), m_M(M) { + m_stride = ((M + stride_size-1) / stride_size) * stride_size; + m_v.resize(N * m_stride); } void resize(std::size_t N, std::size_t M) { m_N = N; m_M = M; - m_stride = (M+stride_size-1) & ~(stride_size-1); + m_stride = ((M + stride_size-1) / stride_size) * stride_size; m_v.resize(N * m_stride); } diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index 99bc5715a05..6b4a4af2f75 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -81,6 +81,59 @@ namespace plib template inline void unused_var(Ts&&...) {} + //============================================================ + // is_pow2 + //============================================================ + template + constexpr bool is_pow2(T v) noexcept + { + static_assert(is_integral::value, "is_pow2 needs integer arguments"); + return !(v & (v-1)); + } + + + //============================================================ + // abs, lcd, gcm + //============================================================ + + template + constexpr + typename std::enable_if::value && std::is_signed::value, T>::type + abs(T v) + { + return v < 0 ? -v : v; + } + + template + constexpr + typename std::enable_if::value && std::is_unsigned::value, T>::type + abs(T v) + { + return v; + } + + template + constexpr typename std::common_type::type + gcd(M m, N n) + { + static_assert(std::is_integral::value, "gcd: M must be an integer"); + static_assert(std::is_integral::value, "gcd: N must be an integer"); + + return m == 0 ? plib::abs(n) + : n == 0 ? plib::abs(m) + : gcd(n, m % n); + } + + template + constexpr typename std::common_type::type + lcm(M m, N n) + { + static_assert(std::is_integral::value, "lcm: M must be an integer"); + static_assert(std::is_integral::value, "lcm: N must be an integer"); + + return (m != 0 && n != 0) ? (plib::abs(m) / gcd(m, n)) * plib::abs(n) : 0; + } + } // namespace plib //============================================================ diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 88d4dbb4bb0..efd60a0c5fa 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -172,14 +172,19 @@ namespace devices { const std::size_t iN = this->m_nets.size(); - std::size_t max_col = 0; + std::size_t max_count = 0; + std::size_t max_rail = 0; for (std::size_t k = 0; k < iN; k++) - max_col = std::max(max_col, m_terms[k]->count()); + { + max_count = std::max(max_count, m_terms[k]->count()); + max_rail = std::max(max_rail, m_terms[k]->m_railstart); + } - m_gtn.resize(iN, max_col); - m_gon.resize(iN, max_col); - m_Idrn.resize(iN, max_col); - m_connected_net_Vn.resize(iN, max_col); + m_mat_ptr.resize(iN, max_rail+1); + m_gtn.resize(iN, max_count); + m_gon.resize(iN, max_count); + m_Idrn.resize(iN, max_count); + m_connected_net_Vn.resize(iN, max_count); for (std::size_t k = 0; k < iN; k++) { @@ -199,7 +204,7 @@ namespace devices for (std::size_t k = 0; k < N; k++) { auto *net = m_terms[k].get(); - auto **tcr_r = tcr[k].data(); + auto **tcr_r = &(tcr[k][0]); const std::size_t term_count = net->count(); const std::size_t railstart = net->m_railstart; @@ -243,6 +248,7 @@ namespace devices plib::pmatrix2d> m_gon; plib::pmatrix2d> m_gtn; plib::pmatrix2d> m_Idrn; + plib::pmatrix2d> m_mat_ptr; plib::pmatrix2d> m_connected_net_Vn; plib::pmatrix2d m_test; diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index c9ab4a535a9..19dea107bc9 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -66,9 +66,6 @@ private: plib::parray RHS; plib::parray new_V; - std::array, storage_N> m_term_cr; - // std::array, storage_N> m_term_cr; - mat_type mat; //extsolver m_proc; @@ -163,7 +160,7 @@ void matrix_solver_GCR_t::vsetup(analog_net_t::list_t &nets) for (mat_index_type k=0; km_terms[k]->m_railstart;j++) { @@ -171,12 +168,13 @@ void matrix_solver_GCR_t::vsetup(analog_net_t::list_t &nets) for (auto i = mat.row_idx[k]; i < mat.row_idx[k+1]; i++) if (other == static_cast(mat.col_idx[i])) { - m_term_cr[k].push_back(&mat.A[i]); + m_mat_ptr[k][j] = &mat.A[i]; + cnt++; break; } } - nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart); - m_term_cr[k].push_back(&mat.A[mat.diag[k]]); + nl_assert(cnt == this->m_terms[k]->m_railstart); + m_mat_ptr[k][this->m_terms[k]->m_railstart] = &mat.A[mat.diag[k]]; } this->log().verbose("maximum fill: {1}", gr.first); @@ -297,7 +295,7 @@ unsigned matrix_solver_GCR_t::vsolve_non_dynamic(const bool newton_rap /* populate matrix */ - this->fill_matrix(iN, m_term_cr, RHS); + this->fill_matrix(iN, m_mat_ptr, RHS); /* now solve it */ diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index f3d894881e2..2ff515ebda7 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -37,7 +37,6 @@ namespace devices */ matrix_solver_GMRES_t(netlist_state_t &anetlist, const pstring &name, const solver_parameters_t *params, const std::size_t size) : matrix_solver_direct_t(anetlist, name, matrix_solver_t::PREFER_BAND_MATRIX, params, size) - , m_term_cr(size) //, m_ops(size, 2) , m_ops(size, 4) , m_gmres(size) @@ -51,9 +50,7 @@ namespace devices using mattype = typename plib::matrix_compressed_rows_t::index_type; - plib::parray, SIZE> m_term_cr; plib::mat_precondition_ILU m_ops; - //plib::mat_precondition_diag m_ops; plib::gmres_t m_gmres; }; @@ -86,17 +83,19 @@ namespace devices for (std::size_t k=0; km_terms[k]->m_railstart;j++) { for (std::size_t i = m_ops.m_mat.row_idx[k]; im_terms[k]->m_connected_net_idx[j] == static_cast(m_ops.m_mat.col_idx[i])) { - m_term_cr[k].push_back(&m_ops.m_mat.A[i]); + this->m_mat_ptr[k][j] = &m_ops.m_mat.A[i]; + cnt++; break; } } - nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart); - m_term_cr[k].push_back(&m_ops.m_mat.A[m_ops.m_mat.diag[k]]); + nl_assert(cnt == this->m_terms[k]->m_railstart); + this->m_mat_ptr[k][this->m_terms[k]->m_railstart] = &m_ops.m_mat.A[m_ops.m_mat.diag[k]]; } } @@ -111,7 +110,7 @@ namespace devices m_ops.m_mat.set_scalar(0.0); /* populate matrix and V for first estimate */ - this->fill_matrix(iN, m_term_cr, RHS); + this->fill_matrix(iN, this->m_mat_ptr, RHS); for (std::size_t k = 0; k < iN; k++) { -- cgit v1.2.3-70-g09d2 From 17fcc38a25415059e6b20d5d9b1f8c5e4ef81333 Mon Sep 17 00:00:00 2001 From: couriersud Date: Fri, 1 Mar 2019 07:47:51 +0100 Subject: netlist: memory code refactoring. (nw) --- src/devices/machine/netlist.cpp | 6 +- src/devices/machine/netlist.h | 2 +- src/lib/netlist/devices/nlid_system.h | 2 +- src/lib/netlist/devices/nlid_truthtable.cpp | 2 +- src/lib/netlist/nl_base.cpp | 22 +- src/lib/netlist/nl_base.h | 16 +- src/lib/netlist/nl_factory.cpp | 2 +- src/lib/netlist/nl_factory.h | 6 +- src/lib/netlist/nl_setup.cpp | 14 +- src/lib/netlist/nltypes.h | 6 +- src/lib/netlist/plib/palloc.h | 378 ++++++++++++++++------------ src/lib/netlist/plib/pconfig.h | 2 +- src/lib/netlist/plib/pdynlib.cpp | 8 +- src/lib/netlist/plib/pmatrix2d.h | 7 +- src/lib/netlist/plib/pmempool.h | 60 ++--- src/lib/netlist/plib/pstream.cpp | 44 +--- src/lib/netlist/plib/pstream.h | 22 +- src/lib/netlist/plib/ptypes.h | 4 +- src/lib/netlist/prg/nltool.cpp | 2 +- src/lib/netlist/solver/nld_matrix_solver.h | 2 +- src/lib/netlist/solver/nld_solver.cpp | 10 +- src/lib/netlist/solver/nld_solver.h | 6 +- 22 files changed, 308 insertions(+), 315 deletions(-) (limited to 'src/lib/netlist/plib/pmatrix2d.h') diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 7beb745cbf2..280973440a9 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -422,11 +422,11 @@ public: struct channel { - netlist::poolptr m_param_name; + netlist::pool_owned_ptr m_param_name; netlist::param_double_t *m_param; stream_sample_t *m_buffer; - netlist::poolptr m_param_mult; - netlist::poolptr m_param_offset; + netlist::pool_owned_ptr m_param_mult; + netlist::pool_owned_ptr m_param_offset; }; channel m_channels[MAX_INPUT_CHANNELS]; netlist::netlist_time m_inc; diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index db27b2860df..9ec58f614bc 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -159,7 +159,7 @@ private: netlist::netlist_time m_rem; netlist::netlist_time m_old; - netlist::poolptr m_netlist; + netlist::pool_owned_ptr m_netlist; func_type m_setup_func; }; diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 95712fc3416..324ceb93c38 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -335,7 +335,7 @@ namespace netlist param_int_t m_N; param_str_t m_func; analog_output_t m_Q; - std::vector> m_I; + std::vector> m_I; std::vector m_vals; plib::pfunction m_compiled; diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index 622aee0e0c7..2221d855880 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -224,7 +224,7 @@ namespace netlist : netlist_base_factory_truthtable_t(name, classname, def_param, sourcefile) { } - poolptr Create(netlist_state_t &anetlist, const pstring &name) override + pool_owned_ptr Create(netlist_state_t &anetlist, const pstring &name) override { using tt_type = nld_truthtable_t; truthtable_parser desc_s(m_NO, m_NI, &m_ttbl.m_initialized, diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 55560151e21..55e952ad723 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -82,15 +82,15 @@ public: m_R_low = 1.0; m_R_high = 130.0; } - poolptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - poolptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + pool_owned_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; + pool_owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; -poolptr logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const +pool_owned_ptr logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { return pool().make_poolptr(anetlist, name, proxied); } -poolptr logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const +pool_owned_ptr logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { return pool().make_poolptr(anetlist, name, proxied); } @@ -109,16 +109,16 @@ public: m_R_low = 10.0; m_R_high = 10.0; } - poolptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - poolptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + pool_owned_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; + pool_owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; -poolptr logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const +pool_owned_ptr logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { return pool().make_poolptr(anetlist, name, proxied); } -poolptr logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const +pool_owned_ptr logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { return pool().make_poolptr(anetlist, name, proxied); } @@ -578,7 +578,7 @@ core_device_t::core_device_t(core_device_t &owner, const pstring &name) set_logic_family(owner.logic_family()); if (logic_family() == nullptr) set_logic_family(family_TTL()); - state().add_dev(this->name(), poolptr(this, false)); + state().add_dev(this->name(), pool_owned_ptr(this, false)); } void core_device_t::set_default_delegate(detail::core_terminal_t &term) @@ -894,7 +894,7 @@ logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname) , m_my_net(dev.state(), name() + ".net", this) { this->set_net(&m_my_net); - state().register_net(poolptr(&m_my_net, false)); + state().register_net(pool_owned_ptr(&m_my_net, false)); set_logic_family(dev.logic_family()); state().setup().register_term(*this); } @@ -923,7 +923,7 @@ analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname) : analog_t(dev, aname, STATE_OUT) , m_my_net(dev.state(), name() + ".net", this) { - state().register_net(poolptr(&m_my_net, false)); + state().register_net(pool_owned_ptr(&m_my_net, false)); this->set_net(&m_my_net); //net().m_cur_Analog = NL_FCONST(0.0); diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 66fc49d7e5e..4a48dc892b3 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -139,7 +139,7 @@ class NETLIB_NAME(name) : public device_t #define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(const nl_double step) #define NETLIB_SUB(chip) nld_ ## chip -#define NETLIB_SUBXX(ns, chip) poolptr< ns :: nld_ ## chip > +#define NETLIB_SUBXX(ns, chip) pool_owned_ptr< ns :: nld_ ## chip > #define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() NL_NOEXCEPT #define NETLIB_UPDATE(chip) NETLIB_HANDLER(chip, update) @@ -243,9 +243,9 @@ namespace netlist virtual ~logic_family_desc_t() noexcept = default; - virtual poolptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, + virtual pool_owned_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const = 0; - virtual poolptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, + virtual pool_owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const = 0; double fixed_V() const { return m_fixed_V; } @@ -1187,7 +1187,7 @@ namespace netlist const setup_t &setup() const; template - void register_sub(const pstring &name, poolptr &dev, const Args&... args) + void register_sub(const pstring &name, pool_owned_ptr &dev, const Args&... args) { //dev.reset(plib::palloc(*this, name, args...)); dev = pool().make_poolptr(*this, name, args...); @@ -1275,10 +1275,10 @@ namespace netlist { public: - using nets_collection_type = std::vector>; + using nets_collection_type = std::vector>; /* need to preserve order of device creation ... */ - using devices_collection_type = std::vector>>; + using devices_collection_type = std::vector>>; netlist_state_t(const pstring &aname, plib::unique_ptr &&callbacks, plib::unique_ptr &&setup); @@ -1330,7 +1330,7 @@ namespace netlist std::size_t find_net_id(const detail::net_t *net) const; template - void register_net(poolptr &&net) { m_nets.push_back(std::move(net)); } + void register_net(pool_owned_ptr &&net) { m_nets.push_back(std::move(net)); } template inline std::vector get_device_list() @@ -1346,7 +1346,7 @@ namespace netlist } template - void add_dev(const pstring &name, poolptr &&dev) + void add_dev(const pstring &name, pool_owned_ptr &&dev) { for (auto & d : m_devices) if (d.first == name) diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index c9d5ea7e29f..1f0ac35c6c4 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -76,7 +76,7 @@ namespace netlist { namespace factory // factory_lib_entry_t: factory class to wrap macro based chips/elements // ----------------------------------------------------------------------------- - poolptr library_element_t::Create(netlist_state_t &anetlist, const pstring &name) + pool_owned_ptr library_element_t::Create(netlist_state_t &anetlist, const pstring &name) { return pool().make_poolptr(anetlist, name); } diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index 23cfe522f8a..271bf72bf90 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -55,7 +55,7 @@ namespace factory { COPYASSIGNMOVE(element_t, default) - virtual poolptr Create(netlist_state_t &anetlist, const pstring &name) = 0; + virtual pool_owned_ptr Create(netlist_state_t &anetlist, const pstring &name) = 0; virtual void macro_actions(nlparse_t &nparser, const pstring &name) { plib::unused_var(nparser); @@ -85,7 +85,7 @@ namespace factory { const pstring &def_param, const pstring &sourcefile) : element_t(name, classname, def_param, sourcefile) { } - poolptr Create(netlist_state_t &anetlist, const pstring &name) override + pool_owned_ptr Create(netlist_state_t &anetlist, const pstring &name) override { return pool().make_poolptr(anetlist, name); } @@ -147,7 +147,7 @@ namespace factory { { } - poolptr Create(netlist_state_t &anetlist, const pstring &name) override; + pool_owned_ptr Create(netlist_state_t &anetlist, const pstring &name) override; void macro_actions(nlparse_t &nparser, const pstring &name) override; diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 3ac1b604bc4..5dc9a9d2516 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -935,17 +935,17 @@ class logic_family_std_proxy_t : public logic_family_desc_t { public: logic_family_std_proxy_t() = default; - poolptr create_d_a_proxy(netlist_state_t &anetlist, + pool_owned_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - poolptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + pool_owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; -poolptr logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist, +pool_owned_ptr logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { return pool().make_poolptr(anetlist, name, proxied); } -poolptr logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const +pool_owned_ptr logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { return pool().make_poolptr(anetlist, name, proxied); } @@ -1010,7 +1010,7 @@ void setup_t::delete_empty_nets() { netlist().nets().erase( std::remove_if(netlist().nets().begin(), netlist().nets().end(), - [](poolptr &x) + [](pool_owned_ptr &x) { if (x->num_cons() == 0) { @@ -1038,7 +1038,7 @@ void setup_t::prepare_to_run() if ( factory().is_class(e.second) || factory().is_class(e.second)) { - m_netlist.nlstate().add_dev(e.first, poolptr(e.second->Create(netlist(), e.first))); + m_netlist.nlstate().add_dev(e.first, pool_owned_ptr(e.second->Create(netlist(), e.first))); } } @@ -1055,7 +1055,7 @@ void setup_t::prepare_to_run() if ( !factory().is_class(e.second) && !factory().is_class(e.second)) { - auto dev = poolptr(e.second->Create(netlist(), e.first)); + auto dev = pool_owned_ptr(e.second->Create(netlist(), e.first)); m_netlist.nlstate().add_dev(dev->name(), std::move(dev)); } } diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h index 1ddc29adfae..9abe8beebef 100644 --- a/src/lib/netlist/nltypes.h +++ b/src/lib/netlist/nltypes.h @@ -84,18 +84,18 @@ namespace netlist #if (USE_MEMPOOL) using nlmempool = plib::mempool; #else - using nlmempool = plib::mempool_default; + using nlmempool = plib::aligned_arena; #endif /*! Owned pointer type for pooled allocations. * */ template - using poolptr = nlmempool::poolptr; + using pool_owned_ptr = nlmempool::owned_pool_ptr; inline nlmempool &pool() { - static nlmempool static_pool(655360, 16); + static nlmempool static_pool; return static_pool; } diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index d7b00262f7f..f10fd548817 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -17,6 +17,7 @@ #include #include #include +#include #if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) #include @@ -25,127 +26,65 @@ namespace plib { //============================================================ - // Memory allocation + // Standard arena_deleter //============================================================ -#if (USE_ALIGNED_ALLOCATION) - static inline void *paligned_alloc( size_t alignment, size_t size ) + template + struct arena_deleter { -#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; + //using arena_storage_type = P *; + using arena_storage_type = typename std::conditional::type; + template + typename std::enable_if::type getref(X *x) { return *x;} + template + typename std::enable_if::type::is_stateless, X&>::type + getref(X &x, Y y = nullptr) + { + unused_var(y); + return x; } - return p; -#else - return aligned_alloc(alignment, size); -#endif - } - - static inline void pfree( void *ptr ) - { - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - free(ptr); - } - -#else - static inline void *paligned_alloc( size_t alignment, size_t size ) - { - unused_var(alignment); - return ::operator new(size); - } - - static inline void pfree( void *ptr ) - { - ::operator delete(ptr); - } -#endif - - template - /*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(p); - //if (t & (ALIGN-1)) - // printf("alignment error!"); -#if (USE_ALIGNED_HINTS) - return reinterpret_cast(__builtin_assume_aligned(p, ALIGN)); -#else - return p; -#endif - } - - template - constexpr const T *assume_aligned_ptr(const 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"); -#if (USE_ALIGNED_HINTS) - return reinterpret_cast(__builtin_assume_aligned(p, ALIGN)); -#else - return p; -#endif - } - - template - inline T *pnew(Args&&... args) - { - auto *p = paligned_alloc(alignof(T), sizeof(T)); - return new(p) T(std::forward(args)...); - } - template - inline void pdelete(T *ptr) - { - ptr->~T(); - pfree(ptr); - } + constexpr arena_deleter(arena_storage_type a = arena_storage_type()) noexcept + : m_a(a) { } - template - inline T* pnew_array(const std::size_t num) - { - return new T[num](); - } - - template - inline void pdelete_array(T *ptr) - { - delete [] ptr; - } - - template - struct pdefault_deleter - { - constexpr pdefault_deleter() noexcept = default; - - template::value>::type> - pdefault_deleter(const pdefault_deleter&) noexcept { } + arena_deleter(const arena_deleter &rhs) noexcept : m_a(rhs.m_a) { } - void operator()(T *p) const + void operator()(T *p) //const { - pdelete(p); + /* call destructor */ + p->~T(); + getref(m_a).deallocate(p); } + //private: + arena_storage_type m_a; }; - template > + //============================================================ + // owned_ptr: smart pointer with ownership information + //============================================================ + + template class owned_ptr { public: + + using pointer = SC *; + using element_type = SC; + using deleter_type = D; + owned_ptr() - : m_ptr(nullptr), m_is_owned(true) { } + : m_ptr(nullptr), m_deleter(), m_is_owned(true) { } template friend class owned_ptr; - owned_ptr(SC *p, bool owned) noexcept + owned_ptr(pointer p, bool owned) noexcept : m_ptr(p), m_deleter(), m_is_owned(owned) { } - owned_ptr(SC *p, bool owned, D deleter) noexcept + owned_ptr(pointer p, bool owned, D deleter) noexcept : m_ptr(p), m_deleter(deleter), m_is_owned(owned) { } @@ -168,10 +107,10 @@ namespace plib { } owned_ptr(owned_ptr &&r) noexcept + : m_ptr(r.m_ptr) + , m_deleter(r.m_deleter) + , m_is_owned(r.m_is_owned) { - 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; } @@ -183,7 +122,7 @@ namespace plib { m_deleter(m_ptr); m_is_owned = r.m_is_owned; m_ptr = r.m_ptr; - m_deleter = r.m_deleter; + m_deleter = std::move(r.m_deleter); r.m_is_owned = false; r.m_ptr = nullptr; return *this; @@ -191,10 +130,10 @@ namespace plib { template owned_ptr(owned_ptr &&r) noexcept + : m_ptr(static_cast(r.get())) + , m_deleter(r.m_deleter) + , m_is_owned(r.is_owned()) { - m_ptr = static_cast(r.get()); - m_is_owned = r.is_owned(); - m_deleter = r.m_deleter; r.release(); } @@ -208,9 +147,9 @@ namespace plib { m_is_owned = false; m_ptr = nullptr; } - SC * release() + pointer release() { - SC *tmp = m_ptr; + pointer tmp = m_ptr; m_is_owned = false; m_ptr = nullptr; return tmp; @@ -218,97 +157,216 @@ namespace plib { bool is_owned() const { return m_is_owned; } - SC * operator ->() const { return m_ptr; } - SC & operator *() const { return *m_ptr; } - SC * get() const { return m_ptr; } + pointer operator ->() const noexcept { return m_ptr; } + typename std::add_lvalue_reference::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: - SC *m_ptr; + pointer m_ptr; D m_deleter; bool m_is_owned; }; - template - using unique_ptr = std::unique_ptr>; - - template - plib::unique_ptr make_unique(Args&&... args) - { - return plib::unique_ptr(pnew(std::forward(args)...)); - } - - template - static owned_ptr make_owned(Args&&... args) - { - owned_ptr a(pnew(std::forward(args)...), true); - return std::move(a); - } - //============================================================ - // Aligned allocator for use with containers + // Arena allocator for use with containers //============================================================ - template - class aligned_allocator + template + class arena_allocator { 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"); - aligned_allocator() noexcept = default; - ~aligned_allocator() noexcept = default; + arena_allocator() noexcept + : m_a(arena_type::instance()) + { } + + ~arena_allocator() noexcept = default; - aligned_allocator(const aligned_allocator&) noexcept = default; - aligned_allocator& operator=(const aligned_allocator&) noexcept = delete; + arena_allocator(const arena_allocator &rhs) noexcept : m_a(rhs.m_a) { printf("copy called\n"); }//= default; + arena_allocator& operator=(const arena_allocator&) noexcept = delete; - aligned_allocator(aligned_allocator&&) noexcept = default; - aligned_allocator& operator=(aligned_allocator&&) = delete; + arena_allocator(arena_allocator&&) noexcept = default; + arena_allocator& operator=(arena_allocator&&) = delete; + + arena_allocator(arena_type & a) noexcept : m_a(a) + { + } template - aligned_allocator(const aligned_allocator& rhs) noexcept + arena_allocator(const arena_allocator& rhs) noexcept + : m_a(rhs.m_a) { - unused_var(rhs); } template struct rebind { - using other = aligned_allocator; + using other = arena_allocator; }; T* allocate(std::size_t n) { - return reinterpret_cast(paligned_alloc(ALIGN, sizeof(T) * n)); + return reinterpret_cast(m_a.allocate(ALIGN, sizeof(T) * n)); } void deallocate(T* p, std::size_t n) noexcept { unused_var(n); - pfree(p); + m_a.deallocate(p); } - template - friend bool operator==(const aligned_allocator& lhs, - const aligned_allocator& rhs) noexcept; + template + friend bool operator==(const arena_allocator& lhs, + const arena_allocator& rhs) noexcept; - template friend class aligned_allocator; + template friend class arena_allocator; + private: + arena_type &m_a; }; - template - /*friend*/ inline bool operator==(const aligned_allocator& lhs, - const aligned_allocator& rhs) noexcept + template + inline bool operator==(const arena_allocator& lhs, + const arena_allocator& rhs) noexcept { - unused_var(lhs, rhs); - return A1 == A2; + return A1 == A2 && rhs.m_a == lhs.m_a; } - template - /*friend*/ inline bool operator!=(const aligned_allocator& lhs, - const aligned_allocator& rhs) noexcept + template + inline bool operator!=(const arena_allocator& lhs, + const arena_allocator& rhs) noexcept { return !(lhs == rhs); } + //============================================================ + // Memory allocation + //============================================================ + + struct aligned_arena + { + static constexpr const bool is_stateless = true; + template + using allocator_type = arena_allocator; + + template + using owned_pool_ptr = plib::owned_ptr>; + + 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 + owned_pool_ptr make_poolptr(Args&&... args) + { + auto *mem = allocate(alignof(T), sizeof(T)); + return owned_pool_ptr(new (mem) T(std::forward(args)...), true, arena_deleter(*this)); + } + + }; + + template + /*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(p); + //if (t & (ALIGN-1)) + // printf("alignment error!"); +#if (USE_ALIGNED_HINTS) + return reinterpret_cast(__builtin_assume_aligned(p, ALIGN)); +#else + return p; +#endif + } + + template + constexpr const T *assume_aligned_ptr(const 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"); +#if (USE_ALIGNED_HINTS) + return reinterpret_cast(__builtin_assume_aligned(p, ALIGN)); +#else + return p; +#endif + } + + // FIXME: remove + template + inline T *pnew(Args&&... args) + { + auto *p = aligned_arena::allocate(alignof(T), sizeof(T)); + return new(p) T(std::forward(args)...); + } + + template + inline void pdelete(T *ptr) + { + ptr->~T(); + aligned_arena::deallocate(ptr); + } + + + template + using unique_ptr = std::unique_ptr>; + + template + plib::unique_ptr make_unique(Args&&... args) + { + return plib::unique_ptr(pnew(std::forward(args)...)); + } + +#if 0 + template + static owned_ptr make_owned(Args&&... args) + { + return owned_ptr(pnew(std::forward(args)...), true); + } +#endif + + + template + using aligned_allocator = aligned_arena::allocator_type; + //============================================================ // traits to determine alignment size and stride size // from types supporting alignment @@ -321,14 +379,7 @@ namespace plib { { 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); -#if 0 - static constexpr const std::size_t stride_size = - ((value_size % align_size) == 0 ? 1 //T is a multiple of align_size - : ((align_size % value_size) != 0 ? align_size // align_size is not a multiple of T - : align_size / value_size)); -#else static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size; -#endif }; template @@ -336,14 +387,7 @@ namespace plib { { static constexpr const std::size_t align_size = T::align_size; static constexpr const std::size_t value_size = sizeof(typename T::value_type); -#if 0 - static constexpr const std::size_t stride_size = - ((value_size % align_size) == 0 ? 1 //T is a multiple of align_size - : ((align_size % value_size) != 0 ? align_size // align_size is not a multiple of T - : align_size / value_size)); -#else static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size; -#endif }; //============================================================ diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index c521f24e5f8..6616669f619 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -38,7 +38,7 @@ */ #ifndef USE_ALIGNED_OPTIMIZATIONS -#define USE_ALIGNED_OPTIMIZATIONS (0) +#define USE_ALIGNED_OPTIMIZATIONS (1) #endif #define USE_ALIGNED_ALLOCATION (USE_ALIGNED_OPTIMIZATIONS) diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp index 91e1b5cf73a..0d32bead51d 100644 --- a/src/lib/netlist/plib/pdynlib.cpp +++ b/src/lib/netlist/plib/pdynlib.cpp @@ -25,7 +25,7 @@ CHAR *astring_from_utf8(const char *utf8string) // convert UTF-16 to "ANSI code page" string char_count = WideCharToMultiByte(CP_ACP, 0, wstring, -1, nullptr, 0, nullptr, nullptr); - result = pnew_array(char_count); + result = new CHAR[char_count]; if (result != nullptr) WideCharToMultiByte(CP_ACP, 0, wstring, -1, result, char_count, nullptr, nullptr); @@ -39,7 +39,7 @@ WCHAR *wstring_from_utf8(const char *utf8string) // convert MAME string (UTF-8) to UTF-16 char_count = MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, nullptr, 0); - result = pnew_array(char_count); + result = new WCHAR[char_count]; if (result != nullptr) MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, result, char_count); @@ -72,7 +72,7 @@ dynlib::dynlib(const pstring &libname) m_isLoaded = true; //else // fprintf(stderr, "win: library <%s> not found!\n", libname.c_str()); - pdelete_array(buffer); + delete [] buffer; #elif defined(EMSCRIPTEN) //no-op #else @@ -106,7 +106,7 @@ dynlib::dynlib(const pstring &path, const pstring &libname) { //printf("win: library <%s> not found!\n", libname.c_str()); } - pdelete_array(buffer); + delete [] buffer; #elif defined(EMSCRIPTEN) //no-op #else diff --git a/src/lib/netlist/plib/pmatrix2d.h b/src/lib/netlist/plib/pmatrix2d.h index 52228548cbf..eab533688d7 100644 --- a/src/lib/netlist/plib/pmatrix2d.h +++ b/src/lib/netlist/plib/pmatrix2d.h @@ -22,21 +22,22 @@ namespace plib { - template> + template> class pmatrix2d { public: using value_type = T; + using allocator_type = A; static constexpr const std::size_t align_size = align_traits::align_size; static constexpr const std::size_t stride_size = align_traits::stride_size; pmatrix2d() - : m_N(0), m_M(0), m_stride(8) + : m_N(0), m_M(0), m_stride(8), m_v() { } pmatrix2d(std::size_t N, std::size_t M) - : m_N(N), m_M(M) + : m_N(N), m_M(M), m_v() { m_stride = ((M + stride_size-1) / stride_size) * stride_size; m_v.resize(N * m_stride); diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h index 00e78b09fb6..5449595c86c 100644 --- a/src/lib/netlist/plib/pmempool.h +++ b/src/lib/netlist/plib/pmempool.h @@ -23,21 +23,6 @@ namespace plib { - template - struct pool_deleter - { - constexpr pool_deleter() noexcept = default; - - template::value>::type> - pool_deleter(const pool_deleter&) noexcept { } - - void operator()(T *p) const - { - P::free(p); - } - }; - //============================================================ // Memory pool //============================================================ @@ -100,8 +85,11 @@ namespace plib { std::vector m_blocks; public: + static constexpr const bool is_stateless = false; + template + using allocator_type = arena_allocator; - mempool(size_t min_alloc, size_t min_align) + mempool(size_t min_alloc = (1<<21), size_t min_align = 16) : m_min_alloc(min_alloc), m_min_align(min_align) { } @@ -122,10 +110,8 @@ namespace plib { } } - template - void *alloc(size_t size) + void *allocate(size_t align, size_t size) { - size_t align = ALIGN; if (align < m_min_align) align = m_min_align; @@ -164,11 +150,8 @@ namespace plib { } } - template - static void free(T *ptr) + static void deallocate(void *ptr) { - /* call destructor */ - ptr->~T(); auto it = sinfo().find(ptr); if (it == sinfo().end()) @@ -188,19 +171,18 @@ namespace plib { } template - using poolptr = plib::owned_ptr>; + using owned_pool_ptr = plib::owned_ptr>; template - poolptr make_poolptr(Args&&... args) + owned_pool_ptr make_poolptr(Args&&... args) { - auto *mem = this->alloc(sizeof(T)); - auto *obj = new (mem) T(std::forward(args)...); - poolptr a(obj, true); - return std::move(a); + auto *mem = this->allocate(alignof(T), sizeof(T)); + return owned_pool_ptr(new (mem) T(std::forward(args)...), true, arena_deleter(this)); } }; +#if 0 class mempool_default { private: @@ -210,7 +192,11 @@ namespace plib { public: - mempool_default(size_t min_alloc, size_t min_align) + static constexpr const bool is_stateless = true; + template + using allocator_type = arena_allocator; + + mempool_default(size_t min_alloc = 16, size_t min_align = (1 << 21)) : m_min_alloc(min_alloc), m_min_align(min_align) { } @@ -219,24 +205,22 @@ namespace plib { ~mempool_default() = default; -#if 0 - void *alloc(size_t size) + void *allocate(size_t alignment, size_t size) { plib::unused_var(m_min_alloc); // -Wunused-private-field fires without plib::unused_var(m_min_align); + plib::unused_var(alignment); return ::operator new(size); } -#endif - template - static void free(T *ptr) + static void deallocate(void *ptr) { - plib::pdelete(ptr); + ::operator delete(ptr); } template - using poolptr = plib::owned_ptr>; + using poolptr = plib::owned_ptr>; template poolptr make_poolptr(Args&&... args) @@ -249,7 +233,7 @@ namespace plib { return std::move(a); } }; - +#endif } // namespace plib diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp index 8f80f317f98..a7acdaafb52 100644 --- a/src/lib/netlist/plib/pstream.cpp +++ b/src/lib/netlist/plib/pstream.cpp @@ -268,55 +268,25 @@ pimemstream::pos_type pimemstream::vtell() const // ----------------------------------------------------------------------------- pomemstream::pomemstream() -: postream(FLAG_SEEKABLE), m_pos(0), m_capacity(1024), m_size(0) +: postream(FLAG_SEEKABLE), m_pos(0), m_mem(1024) { - m_mem = pnew_array(m_capacity); -} - -pomemstream::~pomemstream() -{ - if (m_mem != nullptr) - pdelete_array(m_mem); + m_mem.clear(); } void pomemstream::vwrite(const value_type *buf, const pos_type n) { - if (m_pos + n >= m_capacity) - { - while (m_pos + n >= m_capacity) - m_capacity *= 2; - char *o = m_mem; - m_mem = pnew_array(m_capacity); - if (m_mem == nullptr) - { - throw out_of_mem_e("pomemstream::vwrite"); - } - std::copy(o, o + m_pos, m_mem); - pdelete_array(o); - } + if (m_pos + n >= m_mem.size()) + m_mem.resize(m_pos + n); - std::copy(buf, buf + n, m_mem + m_pos); + std::copy(buf, buf + n, &m_mem[0] + m_pos); m_pos += n; - m_size = std::max(m_pos, m_size); } void pomemstream::vseek(const pos_type n) { m_pos = n; - m_size = std::max(m_pos, m_size); - if (m_size >= m_capacity) - { - while (m_size >= m_capacity) - m_capacity *= 2; - char *o = m_mem; - m_mem = pnew_array(m_capacity); - if (m_mem == nullptr) - { - throw out_of_mem_e("pomemstream::vseek"); - } - std::copy(o, o + m_pos, m_mem); - pdelete_array(o); - } + if (m_pos>=m_mem.size()) + m_mem.resize(m_pos); } pstream::pos_type pomemstream::vtell() const diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index ec15c0258c6..93497eb1423 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -179,18 +179,15 @@ public: pomemstream(pomemstream &&src) noexcept : postream(std::move(src)) , m_pos(src.m_pos) - , m_capacity(src.m_capacity) - , m_size(src.m_size) - , m_mem(src.m_mem) + , m_mem(std::move(src.m_mem)) { - src.m_mem = nullptr; } pomemstream &operator=(pomemstream &&src) = delete; - ~pomemstream() override; + ~pomemstream() override = default; - char *memory() const { return m_mem; } - pos_type size() const { return m_size; } + const char *memory() const { return m_mem.data(); } + pos_type size() const { return m_mem.size(); } protected: /* write n bytes to stream */ @@ -200,9 +197,7 @@ protected: private: pos_type m_pos; - pos_type m_capacity; - pos_type m_size; - char *m_mem; + std::vector m_mem; }; class postringstream : public postream @@ -626,11 +621,10 @@ public: { std::size_t sz = 0; read(sz); - auto buf = plib::pnew_array::mem_t>(sz+1); - m_strm.read(reinterpret_cast(buf), sz); + std::vector::mem_t> buf(sz+1); + m_strm.read(buf.data(), sz); buf[sz] = 0; - s = pstring(buf); - plib::pdelete_array(buf); + s = pstring(buf.data()); } template diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index 7d3c064b35d..bda62099150 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -120,8 +120,8 @@ namespace plib static_assert(std::is_integral::value, "gcd: N must be an integer"); return m == 0 ? plib::abs(n) - : n == 0 ? plib::abs(m) - : gcd(n, m % n); + : n == 0 ? plib::abs(m) + : gcd(n, m % n); } template diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index f9e25346493..784161a71a8 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -625,7 +625,7 @@ void tool_app_t::listdevices() nt.setup().prepare_to_run(); - std::vector> devs; + std::vector> devs; for (auto & f : list) { diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index a7473eb6315..f76660e1cb9 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -254,7 +254,7 @@ namespace devices std::vector> m_terms; std::vector m_nets; - std::vector> m_inps; + std::vector> m_inps; std::vector> m_rails_temp; diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 9d7b8e7dbb2..4734cc3624d 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -111,13 +111,13 @@ namespace devices } template - poolptr create_it(netlist_state_t &nl, pstring name, solver_parameters_t ¶ms, std::size_t size) + pool_owned_ptr create_it(netlist_state_t &nl, pstring name, solver_parameters_t ¶ms, std::size_t size) { return pool().make_poolptr(nl, name, ¶ms, size); } template - poolptr NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername) + pool_owned_ptr NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername) { if (m_method() == "SOR_MAT") { @@ -161,12 +161,12 @@ namespace devices else { log().fatal(MF_1_UNKNOWN_SOLVER_TYPE, m_method()); - return poolptr(); + return pool_owned_ptr(); } } template - poolptr NETLIB_NAME(solver)::create_solver_x(std::size_t size, const pstring &solvername) + pool_owned_ptr NETLIB_NAME(solver)::create_solver_x(std::size_t size, const pstring &solvername) { if (SIZE > 0) { @@ -291,7 +291,7 @@ namespace devices log().verbose("Found {1} net groups in {2} nets\n", splitter.groups.size(), state().nets().size()); for (auto & grp : splitter.groups) { - poolptr ms; + pool_owned_ptr ms; std::size_t net_count = grp.size(); pstring sname = plib::pfmt("Solver_{1}")(m_mat_solvers.size()); diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index 190ae9a9ab5..c9ec967a72a 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -102,17 +102,17 @@ namespace devices param_logic_t m_log_stats; - std::vector> m_mat_solvers; + std::vector> m_mat_solvers; std::vector m_mat_solvers_all; std::vector m_mat_solvers_timestepping; solver_parameters_t m_params; template - poolptr create_solver(std::size_t size, const pstring &solvername); + pool_owned_ptr create_solver(std::size_t size, const pstring &solvername); template - poolptr create_solver_x(std::size_t size, const pstring &solvername); + pool_owned_ptr create_solver_x(std::size_t size, const pstring &solvername); }; } //namespace devices -- cgit v1.2.3-70-g09d2