From b113d0c26d8214b8820a152f5bc20496c564b7d3 Mon Sep 17 00:00:00 2001 From: couriersud Date: Thu, 14 Feb 2019 21:34:30 +0100 Subject: [PATCH] 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. --- src/devices/machine/netlist.cpp | 30 +++--- src/devices/machine/netlist.h | 3 +- src/lib/netlist/build/makefile | 2 +- src/lib/netlist/devices/nlid_system.h | 4 +- src/lib/netlist/devices/nlid_truthtable.cpp | 4 +- src/lib/netlist/netlist_types.h | 45 ++++++-- src/lib/netlist/nl_base.cpp | 50 ++++----- src/lib/netlist/nl_base.h | 32 +++--- src/lib/netlist/nl_factory.cpp | 4 +- src/lib/netlist/nl_factory.h | 9 +- src/lib/netlist/nl_lists.h | 2 +- src/lib/netlist/nl_setup.cpp | 30 +++--- src/lib/netlist/nl_setup.h | 16 ++- src/lib/netlist/plib/gmres.h | 12 ++- src/lib/netlist/plib/mat_cr.h | 2 +- src/lib/netlist/plib/palloc.h | 83 ++++++++------- src/lib/netlist/plib/parray.h | 5 +- src/lib/netlist/plib/pconfig.h | 14 +++ src/lib/netlist/plib/pmempool.h | 102 +++++++++++++++++-- src/lib/netlist/prg/nltool.cpp | 18 ++-- src/lib/netlist/solver/nld_matrix_solver.cpp | 2 +- src/lib/netlist/solver/nld_matrix_solver.h | 2 +- src/lib/netlist/solver/nld_ms_gmres.h | 2 +- src/lib/netlist/solver/nld_solver.cpp | 14 +-- src/lib/netlist/solver/nld_solver.h | 4 +- 25 files changed, 322 insertions(+), 169 deletions(-) diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index d702bd5b6b6..fcfa246910f 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -239,7 +239,7 @@ public: std::unique_ptr netlist_source_memregion_t::stream(const pstring &name) { memory_region *mem = static_cast(setup().exec()).machine().root_device().memregion(m_name.c_str()); - return plib::make_unique_base(mem->base(), mem->bytes()); + return plib::make_unique(mem->base(), mem->bytes()); } netlist_data_memregions_t::netlist_data_memregions_t(netlist::setup_t &setup) @@ -252,7 +252,7 @@ std::unique_ptr netlist_data_memregions_t::stream(const pstring memory_region *mem = static_cast(setup().exec()).parent().memregion(name.c_str()); if (mem != nullptr) { - return plib::make_unique_base(mem->base(), mem->bytes()); + return plib::make_unique(mem->base(), mem->bytes()); } else { @@ -367,9 +367,9 @@ public: for (int i = 0; i < MAX_INPUT_CHANNELS; i++) { - m_channels[i].m_param_name = std::make_unique(*this, plib::pfmt("CHAN{1}")(i), ""); - m_channels[i].m_param_mult = std::make_unique(*this, plib::pfmt("MULT{1}")(i), 1.0); - m_channels[i].m_param_offset = std::make_unique(*this, plib::pfmt("OFFSET{1}")(i), 0.0); + m_channels[i].m_param_name = netlist::pool().make_poolptr(*this, plib::pfmt("CHAN{1}")(i), ""); + m_channels[i].m_param_mult = netlist::pool().make_poolptr(*this, plib::pfmt("MULT{1}")(i), 1.0); + m_channels[i].m_param_offset = netlist::pool().make_poolptr(*this, plib::pfmt("OFFSET{1}")(i), 0.0); } } @@ -416,11 +416,11 @@ public: struct channel { - std::unique_ptr m_param_name; + netlist::poolptr m_param_name; netlist::param_double_t *m_param; stream_sample_t *m_buffer; - std::unique_ptr m_param_mult; - std::unique_ptr m_param_offset; + netlist::poolptr m_param_mult; + netlist::poolptr m_param_offset; }; channel m_channels[MAX_INPUT_CHANNELS]; netlist::netlist_time m_inc; @@ -456,7 +456,7 @@ netlist::setup_t &netlist_mame_device::setup() void netlist_mame_device::register_memregion_source(netlist::setup_t &setup, const char *name) { - setup.register_source(plib::make_unique_base(setup, pstring(name))); + setup.register_source(plib::make_unique(setup, pstring(name))); } void netlist_mame_analog_input_device::write(const double val) @@ -584,7 +584,7 @@ void netlist_mame_analog_output_device::custom_netlist_additions(netlist::setup_ pstring dfqn = setup.build_fqn(dname); m_delegate.bind_relative_to(owner()->machine().root_device()); - plib::owned_ptr dev = plib::owned_ptr::Create(setup.netlist(), dfqn); + auto dev = netlist::pool().make_poolptr(setup.netlist(), dfqn); static_cast(dev.get())->register_callback(std::move(m_delegate)); setup.netlist().add_dev(dfqn, std::move(dev)); setup.register_link(dname + ".IN", pin); @@ -621,7 +621,7 @@ void netlist_mame_logic_output_device::custom_netlist_additions(netlist::setup_t m_delegate.bind_relative_to(owner()->machine().root_device()); - plib::owned_ptr dev = plib::owned_ptr::Create(setup.netlist(), dfqn); + auto dev = netlist::pool().make_poolptr(setup.netlist(), dfqn); static_cast(dev.get())->register_callback(std::move(m_delegate)); setup.netlist().add_dev(dfqn, std::move(dev)); setup.register_link(dname + ".IN", pin); @@ -817,7 +817,6 @@ netlist_mame_device::netlist_mame_device(const machine_config &mconfig, device_t : device_t(mconfig, type, tag, owner, clock) , m_icount(0) , m_old(netlist::netlist_time::zero()) - , m_netlist(nullptr) , m_setup_func(nullptr) { } @@ -850,7 +849,7 @@ void netlist_mame_device::device_start() //printf("clock is %d\n", clock()); - m_netlist = global_alloc(netlist_mame_t(*this, "netlist")); + m_netlist = netlist::pool().make_poolptr(*this, "netlist"); // register additional devices @@ -868,7 +867,7 @@ void netlist_mame_device::device_start() } /* add default data provider for roms */ - setup().register_source(plib::make_unique_base(setup())); + setup().register_source(plib::make_unique(setup())); m_setup_func(setup()); @@ -916,9 +915,6 @@ void netlist_mame_device::device_stop() { LOGDEVCALLS("device_stop\n"); netlist().stop(); - - global_free(m_netlist); - m_netlist = nullptr; } ATTR_COLD void netlist_mame_device::device_post_load() diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index 06edb4beaa4..630bbabe42c 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -12,6 +12,7 @@ #define MAME_MACHINE_NETLIST_H #include "netlist/nl_time.h" +#include "netlist/netlist_types.h" class nld_sound_out; class nld_sound_in; @@ -141,7 +142,7 @@ private: netlist::netlist_time m_rem; netlist::netlist_time m_old; - netlist_mame_t * m_netlist; + netlist::poolptr m_netlist; void (*m_setup_func)(netlist::setup_t &); }; diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index c382d2fe2ab..213d6ffb8e7 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -235,7 +235,7 @@ native: $(MAKE) CEXTRAFLAGS="-march=native -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter" clang: - $(MAKE) CC=clang++-9 LD=clang++-9 CEXTRAFLAGS="-march=native -Wno-unused-parameter -Weverything -Werror -Wno-non-virtual-dtor -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors" + $(MAKE) CC=clang++-9 LD=clang++-9 CEXTRAFLAGS="-march=native -Wno-unused-parameter -Weverything -Werror -Wno-unused-template -Wno-non-virtual-dtor -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors" clang-5: $(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 2a1e4b3e66c..e58b15ed03b 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -317,7 +317,7 @@ namespace netlist for (int i=0; i < m_N(); i++) { pstring n = plib::pfmt("A{1}")(i); - m_I.push_back(plib::make_unique(*this, n)); + m_I.push_back(pool().make_poolptr(*this, n)); inps.push_back(n); m_vals.push_back(0.0); } @@ -334,7 +334,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 f67a0d1d2bb..346a013d680 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) { } - plib::owned_ptr Create(netlist_state_t &anetlist, const pstring &name) override + poolptr 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, @@ -232,7 +232,7 @@ namespace netlist m_ttbl.m_timing_index.data(), m_ttbl.m_timing_nt.data()); desc_s.parse(m_desc); - return plib::owned_ptr::Create(anetlist, name, m_family, m_ttbl, m_desc); + return pool().make_poolptr(anetlist, name, m_family, m_ttbl, m_desc); } private: typename nld_truthtable_t::truthtable_t m_ttbl; diff --git a/src/lib/netlist/netlist_types.h b/src/lib/netlist/netlist_types.h index 3aa7f3436ee..5aec827491b 100644 --- a/src/lib/netlist/netlist_types.h +++ b/src/lib/netlist/netlist_types.h @@ -16,6 +16,7 @@ #include "plib/pchrono.h" #include "plib/pfmtlog.h" #include "plib/pstring.h" +#include "plib/pmempool.h" namespace netlist @@ -69,19 +70,43 @@ namespace netlist // Types needed by various includes //============================================================ + /*! The memory pool for netlist objects + * + * \note This is not the right location yet. + * + */ + +#if (USE_MEMPOOL) + using nlmempool = plib::mempool; +#else + using nlmempool = plib::mempool_default; +#endif + + /*! Owned pointer type for pooled allocations. + * + */ + template + using poolptr = nlmempool::poolptr; + + inline nlmempool &pool() + { + static nlmempool static_pool(655360, 16); + return static_pool; + } + namespace detail { - /*! Enum specifying the type of object */ - enum terminal_type { - TERMINAL = 0, /*!< object is an analog terminal */ - INPUT = 1, /*!< object is an input */ - OUTPUT = 2, /*!< object is an output */ - }; + /*! Enum specifying the type of object */ + enum terminal_type { + TERMINAL = 0, /*!< object is an analog terminal */ + INPUT = 1, /*!< object is an input */ + OUTPUT = 2, /*!< object is an output */ + }; - /*! Type of the model map used. - * This is used to hold all #Models in an unordered map - */ - using model_map_t = std::unordered_map; + /*! Type of the model map used. + * This is used to hold all #Models in an unordered map + */ + using model_map_t = std::unordered_map; } // namespace detail } // namespace netlist diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 8ef16e58bcb..f78731e883f 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -28,12 +28,13 @@ namespace netlist namespace detail { - static plib::mempool *pool() - { - static plib::mempool s_pool(655360, 32); - return &s_pool; - } + //static plib::mempool *pool() + //{ + // static plib::mempool s_pool(655360, 32); + // return &s_pool; + //} +#if 0 void * object_t::operator new (size_t size) { void *ret = nullptr; @@ -43,14 +44,14 @@ namespace detail ret = ::operator new(size); return ret; } - +#endif void object_t::operator delete (void * mem) { if (mem) { - if ((USE_MEMPOOL)) - pool()->free(mem); - else + //if ((USE_MEMPOOL)) + // pool()->free(mem); + //else ::operator delete(mem); } } @@ -81,17 +82,17 @@ public: m_R_low = 1.0; m_R_high = 130.0; } - plib::owned_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - plib::owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + 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; }; -plib::owned_ptr logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const +poolptr logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { - return plib::owned_ptr::Create(anetlist, name, proxied); + return pool().make_poolptr(anetlist, name, proxied); } -plib::owned_ptr logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const +poolptr logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { - return plib::owned_ptr::Create(anetlist, name, proxied); + return pool().make_poolptr(anetlist, name, proxied); } class logic_family_cd4xxx_t : public logic_family_desc_t @@ -108,17 +109,18 @@ public: m_R_low = 10.0; m_R_high = 10.0; } - plib::owned_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - plib::owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + 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; }; -plib::owned_ptr logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const +poolptr logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { - return plib::owned_ptr::Create(anetlist, name, proxied); + return pool().make_poolptr(anetlist, name, proxied); } -plib::owned_ptr logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const + +poolptr logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { - return plib::owned_ptr::Create(anetlist, name, proxied); + return pool().make_poolptr(anetlist, name, proxied); } const logic_family_desc_t *family_TTL() @@ -576,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(), plib::owned_ptr(this, false)); + state().add_dev(this->name(), poolptr(this, false)); } void core_device_t::set_default_delegate(detail::core_terminal_t &term) @@ -892,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(plib::owned_ptr(&m_my_net, false)); + state().register_net(poolptr(&m_my_net, false)); set_logic_family(dev.logic_family()); state().setup().register_term(*this); } @@ -921,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(plib::owned_ptr(&m_my_net, false)); + state().register_net(poolptr(&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 62a5104a021..10df59029b8 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -22,6 +22,7 @@ #include "plib/ppmf.h" #include "plib/pstate.h" #include "plib/pstream.h" +#include "plib/pmempool.h" #include "netlist_types.h" #include "nl_errstr.h" @@ -138,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) std::unique_ptr< ns :: nld_ ## chip > +#define NETLIB_SUBXX(ns, chip) poolptr< ns :: nld_ ## chip > #define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() NL_NOEXCEPT #define NETLIB_UPDATE(chip) NETLIB_HANDLER(chip, update) @@ -242,9 +243,9 @@ namespace netlist virtual ~logic_family_desc_t() noexcept = default; - virtual plib::owned_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, + virtual poolptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const = 0; - virtual plib::owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, + virtual poolptr 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; } @@ -419,7 +420,8 @@ namespace netlist void * operator new (size_t size, void *ptr) { plib::unused_var(size); return ptr; } void operator delete (void *ptr, void *) { plib::unused_var(ptr); } - void * operator new (size_t size); + + void * operator new (size_t size) = delete; void operator delete (void * mem); protected: ~object_t() noexcept = default; // only childs should be destructible @@ -1186,9 +1188,10 @@ namespace netlist const setup_t &setup() const; template - void register_sub(const pstring &name, std::unique_ptr &dev, const Args&... args) + void register_sub(const pstring &name, poolptr &dev, const Args&... args) { - dev.reset(plib::palloc(*this, name, args...)); + //dev.reset(plib::palloc(*this, name, args...)); + dev = pool().make_poolptr(*this, name, args...); } void register_subalias(const pstring &name, detail::core_terminal_t &term); @@ -1263,13 +1266,14 @@ namespace netlist // netlist_state__t // ----------------------------------------------------------------------------- - class netlist_state_t : private plib::nocopyassignmove + class netlist_state_t { 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, std::unique_ptr &&callbacks, std::unique_ptr &&setup); @@ -1302,7 +1306,6 @@ namespace netlist plib::dynlib &lib() { return *m_lib; } /* state handling */ - plib::state_manager_t &run_state_manager() { return m_state; } template @@ -1322,7 +1325,7 @@ namespace netlist std::size_t find_net_id(const detail::net_t *net) const; template - void register_net(plib::owned_ptr &&net) { m_nets.push_back(std::move(net)); } + void register_net(poolptr &&net) { m_nets.push_back(std::move(net)); } template inline std::vector get_device_list() @@ -1338,7 +1341,7 @@ namespace netlist } template - void add_dev(const pstring &name, plib::owned_ptr &&dev) + void add_dev(const pstring &name, poolptr &&dev) { for (auto & d : m_devices) if (d.first == name) @@ -1393,6 +1396,8 @@ namespace netlist /* sole use is to manage lifetime of net objects */ devices_collection_type m_devices; + + }; // ----------------------------------------------------------------------------- @@ -1451,7 +1456,10 @@ namespace netlist /* mostly rw */ netlist_time m_time; devices::NETLIB_NAME(mainclock) * m_mainclock; + + PALIGNAS_CACHELINE() std::unique_ptr m_state; + PALIGNAS_CACHELINE() detail::queue_t m_queue; devices::NETLIB_NAME(solver) * m_solver; diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index 10fb54bdec0..49e567543bd 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -76,9 +76,9 @@ namespace netlist { namespace factory // factory_lib_entry_t: factory class to wrap macro based chips/elements // ----------------------------------------------------------------------------- - plib::owned_ptr library_element_t::Create(netlist_state_t &anetlist, const pstring &name) + poolptr library_element_t::Create(netlist_state_t &anetlist, const pstring &name) { - return plib::owned_ptr::Create(anetlist, name); + return pool().make_poolptr(anetlist, name); } void library_element_t::macro_actions(netlist_state_t &anetlist, const pstring &name) diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index aca31d4c649..533ad4452f2 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -13,6 +13,7 @@ #include "plib/palloc.h" #include "plib/ptypes.h" +#include "netlist_types.h" #define NETLIB_DEVICE_IMPL_ALIAS(p_alias, chip, p_name, p_def_param) \ NETLIB_DEVICE_IMPL_BASE(devices, p_alias, chip, p_name, p_def_param) \ @@ -53,7 +54,7 @@ namespace factory { COPYASSIGNMOVE(element_t, default) - virtual plib::owned_ptr Create(netlist_state_t &anetlist, const pstring &name) = 0; + virtual poolptr Create(netlist_state_t &anetlist, const pstring &name) = 0; virtual void macro_actions(netlist_state_t &anetlist, const pstring &name) { plib::unused_var(anetlist); @@ -83,9 +84,9 @@ namespace factory { const pstring &def_param, const pstring &sourcefile) : element_t(name, classname, def_param, sourcefile) { } - plib::owned_ptr Create(netlist_state_t &anetlist, const pstring &name) override + poolptr Create(netlist_state_t &anetlist, const pstring &name) override { - return plib::owned_ptr::Create(anetlist, name); + return pool().make_poolptr(anetlist, name); } }; @@ -147,7 +148,7 @@ namespace factory { plib::unused_var(setup); } - plib::owned_ptr Create(netlist_state_t &anetlist, const pstring &name) override; + poolptr Create(netlist_state_t &anetlist, const pstring &name) override; void macro_actions(netlist_state_t &anetlist, const pstring &name) override; diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index 0c5b25c1a1b..7dfe8139e19 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -96,7 +96,7 @@ namespace netlist /* Use TS = true for a threadsafe queue */ template - class timed_queue_linear : plib::nocopyassignmove + class PALIGNAS_CACHELINE() timed_queue_linear : plib::nocopyassignmove { public: diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 829bfde1b1a..3cdc598afbc 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -80,7 +80,7 @@ void setup_t::namespace_pop() void setup_t::register_lib_entry(const pstring &name, const pstring &sourcefile) { - factory().register_device(plib::make_unique_base(*this, name, name, "", sourcefile)); + factory().register_device(plib::make_unique(*this, name, name, "", sourcefile)); } void setup_t::register_dev(const pstring &classname, const pstring &name) @@ -593,7 +593,7 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin { log().debug("adding analog net ...\n"); // FIXME: Nets should have a unique name - auto anet = plib::owned_ptr::Create(netlist(),"net." + t1.name()); + auto anet = pool().make_poolptr(netlist(),"net." + t1.name()); auto anetp = anet.get(); netlist().register_net(std::move(anet)); t1.set_net(anetp); @@ -890,19 +890,19 @@ class logic_family_std_proxy_t : public logic_family_desc_t { public: logic_family_std_proxy_t() = default; - plib::owned_ptr create_d_a_proxy(netlist_state_t &anetlist, + poolptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - plib::owned_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + poolptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; -plib::owned_ptr logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist, +poolptr logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { - return plib::owned_ptr::Create(anetlist, name, proxied); + return pool().make_poolptr(anetlist, name, proxied); } -plib::owned_ptr logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const +poolptr logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { - return plib::owned_ptr::Create(anetlist, name, proxied); + return pool().make_poolptr(anetlist, name, proxied); } @@ -920,7 +920,7 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model) if (e.first == model) return e.second.get(); - auto ret = plib::make_unique_base(); + auto ret = plib::make_unique(); ret->m_fixed_V = model_value(map, "FV"); ret->m_low_thresh_PCNT = model_value(map, "IVL"); @@ -994,7 +994,7 @@ void setup_t::delete_empty_nets() { netlist().nets().erase( std::remove_if(netlist().nets().begin(), netlist().nets().end(), - [](plib::owned_ptr &x) + [](poolptr &x) { if (x->num_cons() == 0) { @@ -1024,7 +1024,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, plib::owned_ptr(e.second->Create(netlist(), e.first))); + m_netlist.nlstate().add_dev(e.first, poolptr(e.second->Create(netlist(), e.first))); } } @@ -1041,7 +1041,7 @@ void setup_t::prepare_to_run() if ( !factory().is_class(e.second) && !factory().is_class(e.second)) { - auto dev = plib::owned_ptr(e.second->Create(netlist(), e.first)); + auto dev = poolptr(e.second->Create(netlist(), e.first)); m_netlist.nlstate().add_dev(dev->name(), std::move(dev)); } } @@ -1135,19 +1135,19 @@ bool source_t::parse(const pstring &name) std::unique_ptr source_string_t::stream(const pstring &name) { plib::unused_var(name); - return plib::make_unique_base(m_str.c_str(), std::strlen(m_str.c_str())); + return plib::make_unique(m_str.c_str(), std::strlen(m_str.c_str())); } std::unique_ptr source_mem_t::stream(const pstring &name) { plib::unused_var(name); - return plib::make_unique_base(m_str.c_str(), std::strlen(m_str.c_str())); + return plib::make_unique(m_str.c_str(), std::strlen(m_str.c_str())); } std::unique_ptr source_file_t::stream(const pstring &name) { plib::unused_var(name); - return plib::make_unique_base(m_filename); + return plib::make_unique(m_filename); } bool source_proc_t::parse(const pstring &name) diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 55e335234d2..9cc4cdb22a4 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -69,7 +69,7 @@ void NETLIST_NAME(name)(netlist::setup_t &setup) \ #define NETLIST_END() } #define LOCAL_SOURCE(name) \ - setup.register_source(plib::make_unique_base(setup, # name, &NETLIST_NAME(name))); + setup.register_source(plib::make_unique(setup, # name, &NETLIST_NAME(name))); #define LOCAL_LIB_ENTRY(name) \ LOCAL_SOURCE(name) \ @@ -208,6 +208,20 @@ namespace netlist // setup_t // ---------------------------------------------------------------------------------------- + // setup.register_alias(# alias, # name); + // setup.register_model(model); + // setup.register_dippins_arr( # pin1 ", " # __VA_ARGS__); + // setup.register_dev(# type, # name); + // setup.register_link(# name "." # input, # output); + // setup.register_link_arr( # term1 ", " # __VA_ARGS__); + // setup.register_param(# name, val); + // setup.register_lib_entry(# name, __FILE__); + // setup.include(# name); + // setup.namespace_push(# name); + // NETLIST_NAME(model)(setup); + // setup.namespace_pop(); + // setup.register_frontier(# attach, r_in, r_out); + // setup.tt_factory_create(desc, __FILE__); class setup_t { diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h index 9be0dd99a96..ecdc093ff17 100644 --- a/src/lib/netlist/plib/gmres.h +++ b/src/lib/netlist/plib/gmres.h @@ -75,11 +75,13 @@ namespace plib } } - mat_type m_mat; - mat_type m_LU; - bool m_use_iLU_preconditioning; - std::size_t m_ILU_scale; - std::size_t m_band_width; + PALIGNAS_VECTOROPT() + mat_type m_mat; + PALIGNAS_VECTOROPT() + mat_type m_LU; + bool m_use_iLU_preconditioning; + std::size_t m_ILU_scale; + std::size_t m_band_width; }; template diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h index be2d730b215..3cf2570b725 100644 --- a/src/lib/netlist/plib/mat_cr.h +++ b/src/lib/netlist/plib/mat_cr.h @@ -72,7 +72,7 @@ namespace plib ~matrix_compressed_rows_t() = default; - constexpr index_type size() const { return (N>0) ? N : m_size; } + constexpr index_type size() const { return static_cast((N>0) ? N : m_size); } void set_scalar(const T scalar) { diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index da404be279f..793ad1ce553 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -46,40 +46,37 @@ namespace plib { delete [] ptr; } - template - std::unique_ptr make_unique(Args&&... args) - { - return std::unique_ptr(new T(std::forward(args)...)); - } - - template - std::unique_ptr make_unique_base(Args&&... args) - { - std::unique_ptr ret(new DC(std::forward(args)...)); - return ret; - } - - template + template > class owned_ptr { - private: + public: owned_ptr() : m_ptr(nullptr), m_is_owned(true) { } - public: + + template + friend class owned_ptr; + owned_ptr(SC *p, bool owned) noexcept - : m_ptr(p), m_is_owned(owned) + : m_ptr(p), m_deleter(), m_is_owned(owned) { } + owned_ptr(SC *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 - owned_ptr & operator =(owned_ptr &&r) + template + owned_ptr & operator =(owned_ptr &&r) { if (m_is_owned && (m_ptr != nullptr)) - delete m_ptr; + //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; @@ -89,50 +86,43 @@ namespace plib { { 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; } 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 = r.m_deleter; r.m_is_owned = false; r.m_ptr = nullptr; return *this; } - template - owned_ptr(owned_ptr &&r) noexcept + template + owned_ptr(owned_ptr &&r) noexcept { m_ptr = static_cast(r.get()); m_is_owned = r.is_owned(); + m_deleter = r.m_deleter; r.release(); } ~owned_ptr() { if (m_is_owned && (m_ptr != nullptr)) - delete m_ptr; + { + //delete m_ptr; + m_deleter(m_ptr); + } m_is_owned = false; m_ptr = nullptr; } - template - static owned_ptr Create(Args&&... args) - { - owned_ptr a; - auto *x = new DC(std::forward(args)...); - a.m_ptr = static_cast(x); - return std::move(a); - } - - template - static owned_ptr Create(Args&&... args) - { - owned_ptr a; - a.m_ptr = new SC(std::forward(args)...); - return std::move(a); - } SC * release() { SC *tmp = m_ptr; @@ -148,9 +138,24 @@ namespace plib { SC * get() const { return m_ptr; } private: SC *m_ptr; + D m_deleter; bool m_is_owned; }; + + template + std::unique_ptr make_unique(Args&&... args) + { + return std::unique_ptr(new T(std::forward(args)...)); + } + + template + static owned_ptr make_owned(Args&&... args) + { + owned_ptr a(new T(std::forward(args)...), true); + return std::move(a); + } + } // namespace plib #endif /* PALLOC_H_ */ diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h index e3e15df5539..5fded97d1e9 100644 --- a/src/lib/netlist/plib/parray.h +++ b/src/lib/netlist/plib/parray.h @@ -109,8 +109,9 @@ namespace plib { const FT * data() const noexcept { return m_a.data(); } private: - base_type m_a; - size_type m_size; + PALIGNAS_VECTOROPT() + base_type m_a; + size_type m_size; }; } // namespace plib diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 71a5f25e0e8..cc92a42c827 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -33,6 +33,20 @@ #define PHAS_INT128 (0) #endif +/* + * Standard alignment macros + */ + +#define PALIGNAS_CACHELINE() PALIGNAS(64) +#define PALIGNAS_VECTOROPT() PALIGNAS(64) + +/* Breaks mame build on windows due to -Wattribute */ +#if defined(_WIN32) && defined(__GNUC__) +#define PALIGNAS(x) +#else +#define PALIGNAS(x) alignas(x) +#endif + /*============================================================ * Check for CPP Version * 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(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(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 + struct pool_deleter + { + constexpr pool_deleter() noexcept = default; + + template::value>::type> + pool_deleter(const pool_deleter&) noexcept { } + + void operator()(T *p) const + { + p->~T(); + mempool::free(p); + } + }; + + template + using poolptr = plib::owned_ptr>; + + template + poolptr make_poolptr(Args&&... args) + { + auto mem = this->alloc(sizeof(T), alignof(T)); + auto *obj = new (mem) T(std::forward(args)...); + poolptr 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 + using poolptr = plib::owned_ptr; + + template + poolptr make_poolptr(Args&&... args) + { + auto mem(alloc(sizeof(T))); + auto *obj = new (mem) T(std::forward(args)...); + poolptr a(obj, true); + return std::move(a); + } + + }; + + } // namespace plib #endif /* PMEMPOOL_H_ */ diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 81ef785daee..9d8f3af001a 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -138,7 +138,7 @@ std::unique_ptr netlist_data_folder_t::stream(const pstring &fil pstring name = m_folder + "/" + file; try { - auto strm = plib::make_unique_base(name); + auto strm = plib::make_unique(name); return strm; } catch (const plib::pexception &e) @@ -189,10 +189,9 @@ public: setup().add_define(d); for (auto & r : roms) - setup().register_source(plib::make_unique_base(setup(), r)); + setup().register_source(plib::make_unique(setup(), r)); - setup().register_source(plib::make_unique_base(setup(), filename)); + setup().register_source(plib::make_unique(setup(), filename)); setup().include(name); create_dynamic_logs(logs); @@ -525,8 +524,7 @@ void tool_app_t::create_header() nt.log().verbose.set_enabled(false); nt.log().warning.set_enabled(false); - nt.setup().register_source(plib::make_unique_base(nt.setup(), "dummy", &netlist_dummy)); + nt.setup().register_source(plib::make_unique(nt.setup(), "dummy", &netlist_dummy)); nt.setup().include("dummy"); pout("// license:GPL-2.0+\n"); @@ -570,8 +568,7 @@ void tool_app_t::create_docheader() nt.log().verbose.set_enabled(false); nt.log().warning.set_enabled(false); - nt.setup().register_source(plib::make_unique_base(nt.setup(), "dummy", &netlist_dummy)); + nt.setup().register_source(plib::make_unique(nt.setup(), "dummy", &netlist_dummy)); nt.setup().include("dummy"); std::vector devs; @@ -623,14 +620,13 @@ void tool_app_t::listdevices() netlist::factory::list_t &list = nt.setup().factory(); - nt.setup().register_source(plib::make_unique_base(nt.setup(), "dummy", &netlist_dummy)); + nt.setup().register_source(plib::make_unique(nt.setup(), "dummy", &netlist_dummy)); nt.setup().include("dummy"); 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.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index 3bd55a40d35..36c8f2fb551 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -143,7 +143,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) { pstring nname = this->name() + "." + pstring(plib::pfmt("m{1}")(m_inps.size())); nl_assert(p->net().is_analog()); - auto net_proxy_output_u = plib::make_unique(*this, nname, static_cast(&p->net())); + auto net_proxy_output_u = pool().make_poolptr(*this, nname, static_cast(&p->net())); net_proxy_output = net_proxy_output_u.get(); m_inps.push_back(std::move(net_proxy_output_u)); } diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 0d34499f56e..97ca20448f9 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -205,7 +205,7 @@ protected: 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_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index 16dec115934..3cd88dea429 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -105,7 +105,7 @@ namespace devices { const std::size_t iN = this->size(); - alignas(128) plib::parray RHS(iN); + plib::parray RHS(iN); //float_type new_V[storage_N]; m_ops.m_mat.set_scalar(0.0); diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 3982f88b4c0..9ed380020f4 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -122,13 +122,13 @@ NETLIB_UPDATE(solver) } template -std::unique_ptr create_it(netlist_state_t &nl, pstring name, solver_parameters_t ¶ms, std::size_t size) +poolptr create_it(netlist_state_t &nl, pstring name, solver_parameters_t ¶ms, std::size_t size) { - return plib::make_unique(nl, name, ¶ms, size); + return pool().make_poolptr(nl, name, ¶ms, size); } template -std::unique_ptr NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername) +poolptr NETLIB_NAME(solver)::create_solver(std::size_t size, const pstring &solvername) { if (m_method() == "SOR_MAT") { @@ -172,7 +172,7 @@ std::unique_ptr NETLIB_NAME(solver)::create_solver(std::size_t else { log().fatal(MF_1_UNKNOWN_SOLVER_TYPE, m_method()); - return nullptr; + return poolptr(); } } @@ -276,7 +276,7 @@ void NETLIB_NAME(solver)::post_start() log().verbose("Found {1} net groups in {2} nets\n", splitter.groups.size(), state().nets().size()); for (auto & grp : splitter.groups) { - std::unique_ptr ms; + poolptr ms; std::size_t net_count = grp.size(); pstring sname = plib::pfmt("Solver_{1}")(m_mat_solvers.size()); @@ -285,13 +285,13 @@ void NETLIB_NAME(solver)::post_start() #if 1 case 1: if (use_specific) - ms = plib::make_unique>(state(), sname, &m_params); + ms = pool().make_poolptr>(state(), sname, &m_params); else ms = create_solver(1, sname); break; case 2: if (use_specific) - ms = plib::make_unique>(state(), sname, &m_params); + ms = pool().make_poolptr>(state(), sname, &m_params); else ms = create_solver(2, sname); break; diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index 4bc4aea3d60..1ba15fed64a 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -97,14 +97,14 @@ protected: param_logic_t m_log_stats; private: - 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 - std::unique_ptr create_solver(std::size_t size, const pstring &solvername); + poolptr create_solver(std::size_t size, const pstring &solvername); }; } //namespace devices