diff options
31 files changed, 269 insertions, 278 deletions
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 10bc304eb98..75ba0615896 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -619,11 +619,11 @@ void netlist_mame_cpu_device_t::device_start() netlist::detail::net_t *n = netlist().m_nets[i].get(); if (n->is_logic()) { - state_add(i*2, n->name().c_str(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr()); + state_add(i*2, n->name().c_str(), *downcast<netlist::logic_net_t *>(n)->Q_state_ptr()); } else { - state_add(i*2+1, n->name().c_str(), downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s"); + state_add(i*2+1, n->name().c_str(), *downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s"); } } diff --git a/src/lib/netlist/analog/nld_twoterm.cpp b/src/lib/netlist/analog/nld_twoterm.cpp index d7b0c06392e..f676fe928ac 100644 --- a/src/lib/netlist/analog/nld_twoterm.cpp +++ b/src/lib/netlist/analog/nld_twoterm.cpp @@ -5,9 +5,10 @@ * */ -#include <solver/nld_solver.h> #include <algorithm> +#include "solver/nld_solver.h" + #include "nld_twoterm.h" namespace netlist diff --git a/src/lib/netlist/devices/nld_4020.cpp b/src/lib/netlist/devices/nld_4020.cpp index a147cf3f58f..14459fb3b62 100644 --- a/src/lib/netlist/devices/nld_4020.cpp +++ b/src/lib/netlist/devices/nld_4020.cpp @@ -5,7 +5,7 @@ * */ -#include <devices/nlid_cmos.h> +#include "devices/nlid_cmos.h" #include "nld_4020.h" namespace netlist diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index f33688b73b7..f93bad59143 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -5,7 +5,7 @@ * */ -#include <devices/nlid_cmos.h> +#include "devices/nlid_cmos.h" #include "analog/nld_twoterm.h" #include "nld_4066.h" diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp index 8b9cb0d46ad..1a3b5c77144 100644 --- a/src/lib/netlist/devices/nld_4316.cpp +++ b/src/lib/netlist/devices/nld_4316.cpp @@ -5,7 +5,7 @@ * */ -#include <devices/nlid_cmos.h> +#include "devices/nlid_cmos.h" #include "analog/nld_twoterm.h" #include "nld_4316.h" diff --git a/src/lib/netlist/devices/nld_74166.cpp b/src/lib/netlist/devices/nld_74166.cpp index 5cb7114ee0f..c9e935cb0d1 100644 --- a/src/lib/netlist/devices/nld_74166.cpp +++ b/src/lib/netlist/devices/nld_74166.cpp @@ -82,7 +82,7 @@ namespace netlist netlist_time delay = NLTIME_FROM_NS(26); if (m_CLRQ()) { - bool clear_unset = !m_last_CLRQ(); + bool clear_unset = !m_last_CLRQ; if (clear_unset) { delay = NLTIME_FROM_NS(35); diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp index 557d7fa42b6..151e407a210 100644 --- a/src/lib/netlist/devices/nld_7493.cpp +++ b/src/lib/netlist/devices/nld_7493.cpp @@ -29,8 +29,8 @@ namespace netlist logic_input_t m_I; logic_output_t m_Q; - state_var_u8 m_reset; - state_var_u8 m_state; + state_var<netlist_sig_t> m_reset; + state_var<netlist_sig_t> m_state; }; NETLIB_OBJECT(7493) @@ -99,7 +99,7 @@ namespace netlist NETLIB_UPDATE(7493ff) { - constexpr netlist_time out_delay = NLTIME_FROM_NS(18); + static constexpr netlist_time out_delay = NLTIME_FROM_NS(18); if (m_reset) { m_state ^= 1; diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp index 4ddb62af519..c45f3bb1ed2 100644 --- a/src/lib/netlist/devices/nld_9310.cpp +++ b/src/lib/netlist/devices/nld_9310.cpp @@ -158,21 +158,22 @@ namespace netlist { if (m_loadq) { - switch (m_cnt()) + if (m_cnt < MAXCNT - 1) { - case MAXCNT - 1: - m_cnt = MAXCNT; - m_RC.push(m_ent, NLTIME_FROM_NS(20)); - m_QA.push(1, NLTIME_FROM_NS(20)); - break; - case MAXCNT: - m_RC.push(0, NLTIME_FROM_NS(20)); - m_cnt = 0; - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); - break; - default: - m_cnt++; - update_outputs(m_cnt); + m_cnt++; + update_outputs(m_cnt); + } + else if (m_cnt == MAXCNT - 1) + { + m_cnt = MAXCNT; + m_RC.push(m_ent, NLTIME_FROM_NS(20)); + m_QA.push(1, NLTIME_FROM_NS(20)); + } + else // MAXCNT + { + m_RC.push(0, NLTIME_FROM_NS(20)); + m_cnt = 0; + update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); } } else diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index ea7ca9fc45c..d1a4ae7334b 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -161,22 +161,22 @@ namespace netlist { if (m_loadq) { - switch (m_cnt()) + if (m_cnt < MAXCNT - 1) { - case MAXCNT - 1: - m_cnt = MAXCNT; - m_RC.push(m_ent, NLTIME_FROM_NS(27)); - m_QA.push(1, NLTIME_FROM_NS(20)); - break; - case MAXCNT: - m_RC.push(0, NLTIME_FROM_NS(27)); - m_cnt = 0; - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); - break; - default: - m_cnt++; - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); - break; + m_cnt++; + update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); + } + else if (m_cnt == MAXCNT - 1) + { + m_cnt = MAXCNT; + m_RC.push(m_ent, NLTIME_FROM_NS(27)); + m_QA.push(1, NLTIME_FROM_NS(20)); + } + else // MAXCNT + { + m_RC.push(0, NLTIME_FROM_NS(27)); + m_cnt = 0; + update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); } } else diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp index 256ced2d2a7..6be7d717221 100644 --- a/src/lib/netlist/devices/nld_mm5837.cpp +++ b/src/lib/netlist/devices/nld_mm5837.cpp @@ -6,7 +6,7 @@ */ #include "nld_mm5837.h" -#include <solver/nld_matrix_solver.h> +#include "solver/nld_matrix_solver.h" #include "analog/nld_twoterm.h" #define R_LOW (1000.0) diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp index 3cfd120be30..67b13fd32b3 100644 --- a/src/lib/netlist/devices/nld_ne555.cpp +++ b/src/lib/netlist/devices/nld_ne555.cpp @@ -7,7 +7,7 @@ #include "nld_ne555.h" #include "analog/nld_twoterm.h" -#include <solver/nld_solver.h> +#include "solver/nld_solver.h" #define R_OFF (1E20) #define R_ON (25) // Datasheet states a maximum discharge of 200mA, R = 5V / 0.2 diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 2a403c070a3..e3585271696 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -5,8 +5,8 @@ * */ -#include <solver/nld_solver.h> -#include <solver/nld_matrix_solver.h> +#include "solver/nld_solver.h" +#include "solver/nld_matrix_solver.h" #include "nlid_system.h" namespace netlist diff --git a/src/lib/netlist/devices/nld_truthtable.cpp b/src/lib/netlist/devices/nld_truthtable.cpp index 1e786805eda..e7cedfba13f 100644 --- a/src/lib/netlist/devices/nld_truthtable.cpp +++ b/src/lib/netlist/devices/nld_truthtable.cpp @@ -8,6 +8,7 @@ #include "nld_truthtable.h" #include "plib/plists.h" #include "nl_setup.h" +#include "plib/palloc.h" namespace netlist { @@ -272,7 +273,7 @@ netlist_base_factory_truthtable_t::~netlist_base_factory_truthtable_t() #define ENTRYY(n, m, s) case (n * 100 + m): \ { using xtype = netlist_factory_truthtable_t<n, m>; \ - ret = new xtype(desc.name, desc.classname, desc.def_param, s); } break + ret = plib::palloc<xtype>(desc.name, desc.classname, desc.def_param, s); } break #define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \ ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s) diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index 3edb25f73e2..59f6f39420b 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -113,9 +113,9 @@ namespace netlist { pstring devname = out_proxied->device().name(); auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0], - detail::device_object_t::type_t::INPUT, false); + detail::core_terminal_t::type_t::INPUT, false); auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1], - detail::device_object_t::type_t::INPUT, false); + detail::core_terminal_t::type_t::INPUT, false); if (tp != nullptr && tn != nullptr) { /* alternative logic */ diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 50ef51827d8..90149f44e8e 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -25,7 +25,7 @@ namespace netlist namespace detail { #if (USE_MEMPOOL) -static plib::mempool pool(65536, 8); +static plib::mempool pool(6553600, 64); void * object_t::operator new (size_t size) { @@ -184,7 +184,7 @@ void detail::queue_t::on_post_load() detail::net_t *n = netlist().find_net(pstring(m_names[i].m_buf, pstring::UTF8)); //log().debug("Got {1} ==> {2}\n", qtemp[i].m_name, n)); //log().debug("schedule time {1} ({2})\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double())); - this->push(n, netlist_time::from_raw(m_times[i])); + this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n)); } } @@ -216,20 +216,18 @@ detail::device_object_t::device_object_t(core_device_t &dev, const pstring &anam { } -detail::device_object_t::type_t detail::device_object_t::type() const +detail::core_terminal_t::type_t detail::core_terminal_t::type() const { if (dynamic_cast<const terminal_t *>(this) != nullptr) return type_t::TERMINAL; - else if (dynamic_cast<const param_t *>(this) != nullptr) - return param_t::PARAM; else if (dynamic_cast<const logic_input_t *>(this) != nullptr) - return param_t::INPUT; + return type_t::INPUT; else if (dynamic_cast<const logic_output_t *>(this) != nullptr) - return param_t::OUTPUT; + return type_t::OUTPUT; else if (dynamic_cast<const analog_input_t *>(this) != nullptr) - return param_t::INPUT; + return type_t::INPUT; else if (dynamic_cast<const analog_output_t *>(this) != nullptr) - return param_t::OUTPUT; + return type_t::OUTPUT; else { netlist().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name()); @@ -254,19 +252,16 @@ netlist_t::netlist_t(const pstring &aname) { state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue"); state().save_item(this, m_time, "m_time"); - m_setup = new setup_t(*this); + m_setup = plib::make_unique<setup_t>(*this); /* FIXME: doesn't really belong here */ NETLIST_NAME(base)(*m_setup); } netlist_t::~netlist_t() { - if (m_setup != nullptr) - delete m_setup; m_nets.clear(); m_devices.clear(); - pfree(m_lib); pstring::resetmem(); } @@ -356,7 +351,7 @@ void netlist_t::start() } pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"})); - m_lib = plib::palloc<plib::dynlib>(libpath); + m_lib = plib::make_unique<plib::dynlib>(libpath); /* resolve inputs */ setup().resolve_inputs(); @@ -448,7 +443,7 @@ void netlist_t::process_queue(const netlist_time &delta) { netlist_time stop(m_time + delta); - m_queue.push(nullptr, stop); + m_queue.push(detail::queue_t::entry_t(stop, nullptr)); m_stat_mainloop.start(); @@ -475,17 +470,20 @@ void netlist_t::process_queue(const netlist_time &delta) while (m_queue.top().m_exec_time > mc_time) { m_time = mc_time; - mc_time += inc; mc_net.toggle_new_Q(); mc_net.update_devs(); + mc_time += inc; } const detail::queue_t::entry_t e(m_queue.pop()); m_time = e.m_exec_time; - if (e.m_object == nullptr) + if (e.m_object != nullptr) + { + e.m_object->update_devs(); + m_perf_out_processed.inc(); + } + else break; - e.m_object->update_devs(); - m_perf_out_processed.inc(); } mc_net.set_time(mc_time); } @@ -686,13 +684,6 @@ detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_ // net_t // ---------------------------------------------------------------------------------------- -// FIXME: move somewhere central - -struct do_nothing_deleter{ - template<typename T> void operator()(T*){} -}; - - detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) : object_t(aname) , netlist_ref(nl) @@ -725,7 +716,7 @@ void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT if (m_time > netlist().time()) { m_in_queue = 1; /* pending */ - netlist().queue().push(this, m_time); + netlist().queue().push(queue_t::entry_t(m_time, this)); } else { @@ -1100,11 +1091,11 @@ param_double_t::param_double_t(device_t &device, const pstring name, const doubl m_param = device.setup().get_initial_param_val(this->name(),val); netlist().save(*this, m_param, "m_param"); } - +#if 0 param_double_t::~param_double_t() { } - +#endif param_int_t::param_int_t(device_t &device, const pstring name, const int val) : param_t(device, name) { @@ -1112,9 +1103,11 @@ param_int_t::param_int_t(device_t &device, const pstring name, const int val) netlist().save(*this, m_param, "m_param"); } +#if 0 param_int_t::~param_int_t() { } +#endif param_logic_t::param_logic_t(device_t &device, const pstring name, const bool val) : param_t(device, name) @@ -1123,9 +1116,11 @@ param_logic_t::param_logic_t(device_t &device, const pstring name, const bool va netlist().save(*this, m_param, "m_param"); } +#if 0 param_logic_t::~param_logic_t() { } +#endif param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val) : param_t(device, name) @@ -1134,9 +1129,11 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val) //netlist().save(*this, m_param, "m_param"); } +#if 0 param_ptr_t::~param_ptr_t() { } +#endif void param_model_t::changed() { diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index e1bb98e3651..b1b4dac9341 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -29,7 +29,7 @@ // ---------------------------------------------------------------------------------------- /*! netlist_sig_t is the type used for logic signals. */ -using netlist_sig_t = std::uint_least32_t; +using netlist_sig_t = std::uint32_t; //============================================================ // MACROS / New Syntax @@ -281,12 +281,12 @@ namespace netlist public: logic_family_t() : m_logic_family(nullptr) {} - ~logic_family_t() { } const logic_family_desc_t *logic_family() const { return m_logic_family; } void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; } protected: + ~logic_family_t() { } // prohibit polymorphic destruction const logic_family_desc_t *m_logic_family; }; @@ -321,19 +321,15 @@ namespace netlist //! Move Constructor. state_var(state_var &&rhs) NL_NOEXCEPT = default; //! Assignment operator to assign value of a state var. - state_var &operator=(state_var rhs) { std::swap(rhs.m_value, this->m_value); return *this; } + state_var &operator=(const state_var &rhs) { m_value = rhs; return *this; } //! Assignment operator to assign value of type T. - state_var &operator=(const T rhs) { m_value = rhs; return *this; } + state_var &operator=(const T &rhs) { m_value = rhs; return *this; } //! Return value of state variable. operator T & () { return m_value; } - //! Return value of state variable. - T & operator()() { return m_value; } - //! Return const value of state variable. - operator const T & () const { return m_value; } //! Return const value of state variable. - const T & operator()() const { return m_value; } + constexpr operator const T & () const { return m_value; } T * ptr() { return &m_value; } - const T * ptr() const { return &m_value; } + constexpr T * ptr() const { return &m_value; } private: T m_value; }; @@ -346,13 +342,20 @@ namespace netlist struct state_var<T[N]> { public: - state_var(device_t &dev, const pstring name, const T & value); + //! Constructor. + template <typename O> + state_var(O &owner, //!< owner must have a netlist() method. + const pstring name, //!< identifier/name for this state variable + const T &value //!< Initial value after construction + ); + //! Copy Constructor. state_var(const state_var &rhs) NL_NOEXCEPT = default; + //! Move Constructor. state_var(state_var &&rhs) NL_NOEXCEPT = default; - state_var &operator=(const state_var rhs) { m_value = rhs.m_value; return *this; } - state_var &operator=(const T rhs) { m_value = rhs; return *this; } + state_var &operator=(const state_var &rhs) { m_value = rhs.m_value; return *this; } + state_var &operator=(const T &rhs) { m_value = rhs; return *this; } T & operator[](const std::size_t i) { return m_value[i]; } - const T & operator[](const std::size_t i) const { return m_value[i]; } + constexpr T & operator[](const std::size_t i) const { return m_value[i]; } private: T m_value[N]; }; @@ -392,7 +395,6 @@ namespace netlist * Every class derived from the object_t class must have a name. */ object_t(const pstring &aname /*!< string containing name of the object */); - virtual ~object_t(); /*! return name of the object * @@ -404,6 +406,8 @@ namespace netlist void operator delete (void *ptr, void *) { } void * operator new (size_t size); void operator delete (void * mem); + protected: + ~object_t(); // only childs should be destructible private: pstring m_name; @@ -412,11 +416,13 @@ namespace netlist struct detail::netlist_ref { netlist_ref(netlist_t &nl) : m_netlist(nl) { } - ~netlist_ref() {} netlist_t & netlist() { return m_netlist; } const netlist_t & netlist() const { return m_netlist; } + protected: + ~netlist_ref() {} // prohibit polymorphic destruction + private: netlist_t & m_netlist; @@ -435,14 +441,6 @@ namespace netlist { P_PREVENT_COPYING(device_object_t) public: - /*! Enum specifying the type of object */ - enum type_t { - TERMINAL = 0, /*!< object is an analog terminal */ - INPUT = 1, /*!< object is an input */ - OUTPUT = 2, /*!< object is an output */ - PARAM = 3, /*!< object is a parameter */ - }; - /*! Constructor. * * \param dev device owning the object. @@ -454,16 +452,6 @@ namespace netlist */ core_device_t &device() const { return m_device; } - /*! The object type. - * \returns type of the object - */ - type_t type() const; - /*! Checks if object is of specified type. - * \param atype type to check object against. - * \returns true if object is of specified type else false. - */ - bool is_type(const type_t atype) const { return (type() == atype); } - /*! The netlist owning the owner of this object. * \returns reference to netlist object. */ @@ -500,9 +488,26 @@ namespace netlist STATE_BIDIR = 256 }; + /*! Enum specifying the type of object */ + enum type_t { + TERMINAL = 0, /*!< object is an analog terminal */ + INPUT = 1, /*!< object is an input */ + OUTPUT = 2, /*!< object is an output */ + }; + core_terminal_t(core_device_t &dev, const pstring &aname, const state_e state); virtual ~core_terminal_t(); + /*! The object type. + * \returns type of the object + */ + type_t type() const; + /*! Checks if object is of specified type. + * \param atype type to check object against. + * \returns true if object is of specified type else false. + */ + bool is_type(const type_t atype) const { return (type() == atype); } + void set_net(net_t *anet); void clear_net(); bool has_net() const { return (m_net != nullptr); } @@ -706,12 +711,6 @@ namespace netlist void reset(); - void add_terminal(core_terminal_t &terminal); - void remove_terminal(core_terminal_t &terminal); - - bool is_logic() const NL_NOEXCEPT; - bool is_analog() const NL_NOEXCEPT; - void toggle_new_Q() { m_new_Q ^= 1; } void force_queue_execution() { m_new_Q = (m_cur_Q ^ 1); } @@ -732,6 +731,14 @@ namespace netlist void inc_active(core_terminal_t &term) NL_NOEXCEPT; void dec_active(core_terminal_t &term) NL_NOEXCEPT; + /* setup stuff */ + + void add_terminal(core_terminal_t &terminal); + void remove_terminal(core_terminal_t &terminal); + + bool is_logic() const NL_NOEXCEPT; + bool is_analog() const NL_NOEXCEPT; + void rebuild_list(); /* rebuild m_list after a load */ void move_connections(net_t &dest_net); @@ -764,7 +771,7 @@ namespace netlist virtual ~logic_net_t(); netlist_sig_t Q() const { return m_cur_Q; } - netlist_sig_t new_Q() const { return m_new_Q; } + netlist_sig_t new_Q() const { return m_new_Q; } void initial(const netlist_sig_t val) { m_cur_Q = m_new_Q = val; } void set_Q(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT @@ -789,7 +796,7 @@ namespace netlist /* internal state support * FIXME: get rid of this and implement export/import in MAME */ - netlist_sig_t &Q_state_ptr() { return m_cur_Q; } + netlist_sig_t *Q_state_ptr() { return m_cur_Q.ptr(); } protected: private: @@ -808,7 +815,7 @@ namespace netlist virtual ~analog_net_t(); nl_double Q_Analog() const { return m_cur_Analog; } - nl_double &Q_Analog_state_ptr() { return m_cur_Analog; } + nl_double *Q_Analog_state_ptr() { return m_cur_Analog.ptr(); } //FIXME: needed by current solver code devices::matrix_solver_t *solver() const { return m_solver; } @@ -874,11 +881,12 @@ namespace netlist }; param_t(device_t &device, const pstring &name); - virtual ~param_t(); param_type_t param_type() const; protected: + virtual ~param_t(); /* not intended to be destroyed */ + void update_param(); template<typename C> @@ -897,7 +905,6 @@ namespace netlist { public: param_ptr_t(device_t &device, const pstring name, std::uint8_t* val); - virtual ~param_ptr_t(); std::uint8_t * operator()() const { return m_param; } void setTo(std::uint8_t *param) { set(m_param, param); } private: @@ -908,7 +915,6 @@ namespace netlist { public: param_logic_t(device_t &device, const pstring name, const bool val); - virtual ~param_logic_t(); bool operator()() const { return m_param; } void setTo(const bool ¶m) { set(m_param, param); } private: @@ -919,7 +925,6 @@ namespace netlist { public: param_int_t(device_t &device, const pstring name, const int val); - virtual ~param_int_t(); int operator()() const { return m_param; } void setTo(const int ¶m) { set(m_param, param); } private: @@ -930,7 +935,6 @@ namespace netlist { public: param_double_t(device_t &device, const pstring name, const double val); - virtual ~param_double_t(); double operator()() const { return m_param; } void setTo(const double ¶m) { set(m_param, param); } private: @@ -942,6 +946,7 @@ namespace netlist public: param_str_t(device_t &device, const pstring name, const pstring val); virtual ~param_str_t(); + const pstring operator()() const { return Value(); } void setTo(const pstring ¶m) { @@ -1128,7 +1133,7 @@ namespace netlist template<class C, typename... Args> void register_sub(const pstring &name, std::unique_ptr<C> &dev, const Args&... args) { - dev.reset(new C(*this, name, args...)); + dev.reset(plib::palloc<C>(*this, name, args...)); } void register_subalias(const pstring &name, detail::core_terminal_t &term); @@ -1309,9 +1314,9 @@ namespace netlist devices::NETLIB_NAME(netlistparams) *m_params; pstring m_name; - setup_t * m_setup; + std::unique_ptr<setup_t> m_setup; plib::plog_base<NL_DEBUG> m_log; - plib::dynlib * m_lib; // external lib needs to be loaded as long as netlist exists + std::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists plib::state_manager_t m_state; @@ -1421,7 +1426,7 @@ namespace netlist m_time = netlist().time() + delay; m_in_queue = (m_active > 0); /* queued ? */ if (m_in_queue) - netlist().queue().push(this, m_time); + netlist().queue().push(queue_t::entry_t(m_time, this)); } } @@ -1433,7 +1438,7 @@ namespace netlist m_time = netlist().time() + delay; m_in_queue = (m_active > 0); /* queued ? */ if (m_in_queue) - netlist().queue().push(this, m_time); + netlist().queue().push(queue_t::entry_t(m_time, this)); } inline const analog_net_t & analog_t::net() const NL_NOEXCEPT @@ -1450,7 +1455,7 @@ namespace netlist inline logic_net_t & logic_t::net() NL_NOEXCEPT { - return *static_cast<logic_net_t *>(&core_terminal_t::net()); + return static_cast<logic_net_t &>(core_terminal_t::net()); } inline const logic_net_t & logic_t::net() const NL_NOEXCEPT @@ -1487,9 +1492,10 @@ namespace netlist } template <typename T, std::size_t N> - state_var<T[N]>::state_var(device_t &dev, const pstring name, const T & value) + template <typename O> + state_var<T[N]>::state_var(O &owner, const pstring name, const T & value) { - dev.netlist().save(dev, m_value, name); + owner.netlist().save(owner, m_value, name); for (std::size_t i=0; i<N; i++) m_value[i] = value; } @@ -1506,5 +1512,14 @@ namespace netlist } +namespace plib +{ + template<typename X> + struct ptype_traits<netlist::state_var<X>> : ptype_traits<X> + { + }; +} + + #endif /* NLBASE_H_ */ diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index 8c911e2a0bd..f5a38d416da 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -17,12 +17,11 @@ #include "plib/putil.h" #include "nl_base.h" -#if 1 #define NETLIB_DEVICE_IMPL(chip) \ static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \ const pstring &name, const pstring &classname, const pstring &def_param) \ { \ - return std::unique_ptr<factory::element_t>(new factory::device_element_t<NETLIB_NAME(chip)>(name, classname, def_param, pstring(__FILE__))); \ + return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \ } \ factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c); @@ -30,16 +29,10 @@ static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \ const pstring &name, const pstring &classname, const pstring &def_param) \ { \ - return std::unique_ptr<factory::element_t>(new factory::device_element_t<ns :: NETLIB_NAME(chip)>(name, classname, def_param, pstring(__FILE__))); \ + return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \ } \ factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c); -#else -#define NETLIB_DEVICE_IMPL(chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< NETLIB_NAME(chip) >; -#define NETLIB_DEVICE_IMPL_NS(ns, chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< ns :: NETLIB_NAME(chip) >; -#endif - - namespace netlist { namespace factory { // ----------------------------------------------------------------------------- @@ -99,7 +92,7 @@ namespace netlist { namespace factory void register_device(const pstring &name, const pstring &classname, const pstring &def_param) { - register_device(std::unique_ptr<element_t>(new device_element_t<device_class>(name, classname, def_param))); + register_device(std::unique_ptr<element_t>(plib::palloc<device_element_t<device_class>>(name, classname, def_param))); } void register_device(std::unique_ptr<element_t> factory); @@ -127,7 +120,7 @@ namespace netlist { namespace factory std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname, const pstring &def_param) { - return std::unique_ptr<element_t>(new device_element_t<T>(name, classname, def_param)); + return std::unique_ptr<element_t>(plib::palloc<device_element_t<T>>(name, classname, def_param)); } // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index 2b378dadf71..9d35adf20ef 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -11,6 +11,8 @@ #define NLLISTS_H_ #include <atomic> +#include <thread> +#include <mutex> #include "nl_config.h" #include "plib/plists.h" @@ -26,30 +28,24 @@ namespace netlist //FIXME: move to an appropriate place template<bool enabled_ = true> - class pspin_lock + class pspin_mutex { public: - pspin_lock() { } - void acquire() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } } - void release() noexcept { m_lock.clear(std::memory_order_release); } + pspin_mutex() noexcept { } + void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } } + void unlock() noexcept { m_lock.clear(std::memory_order_release); } private: std::atomic_flag m_lock = ATOMIC_FLAG_INIT; }; template<> - class pspin_lock<false> + class pspin_mutex<false> { public: - void acquire() const noexcept { } - void release() const noexcept { } + void lock() const noexcept { } + void unlock() const noexcept { } }; - #if HAS_OPENMP && USE_OPENMP - using tqlock = pspin_lock<true>; - #else - using tqlock = pspin_lock<false>; - #endif - template <class Element, class Time> class timed_queue { @@ -58,6 +54,18 @@ namespace netlist struct entry_t { + entry_t() { } + entry_t(const Time &t, const Element &o) : m_exec_time(t), m_object(o) { } + entry_t(const entry_t &e) : m_exec_time(e.m_exec_time), m_object(e.m_object) { } + entry_t(entry_t &&e) : m_exec_time(e.m_exec_time), m_object(e.m_object) { } + + entry_t& operator=(entry_t && other) + { + m_exec_time = other.m_exec_time; + m_object = other.m_object; + return *this; + } + Time m_exec_time; Element m_object; }; @@ -65,37 +73,35 @@ namespace netlist timed_queue(unsigned list_size) : m_list(list_size) { - m_lock.acquire(); clear(); - m_lock.release(); } std::size_t capacity() const { return m_list.size(); } bool empty() const { return (m_end == &m_list[1]); } - void push(Element o, const Time t) noexcept + void push(entry_t &&e) noexcept { /* Lock */ - m_lock.acquire(); + tqlock lck(m_lock); entry_t * i = m_end; - for (; t > (i - 1)->m_exec_time; --i) + while (e.m_exec_time > (i - 1)->m_exec_time) { - *(i) = *(i-1); + *(i) = std::move(*(i-1)); + --i; m_prof_sortmove.inc(); } - *i = { t, o }; + *i = std::move(e); ++m_end; m_prof_call.inc(); - m_lock.release(); } - entry_t pop() noexcept { return *(--m_end); } - const entry_t &top() const noexcept { return *(m_end-1); } + entry_t pop() noexcept { return std::move(*(--m_end)); } + const entry_t &top() const noexcept { return std::move(*(m_end-1)); } void remove(const Element &elem) noexcept { /* Lock */ - m_lock.acquire(); + tqlock lck(m_lock); for (entry_t * i = m_end - 1; i > &m_list[0]; i--) { if (i->m_object == elem) @@ -103,24 +109,23 @@ namespace netlist m_end--; while (i < m_end) { - *i = *(i+1); + *i = std::move(*(i+1)); ++i; } - m_lock.release(); return; } } - m_lock.release(); } void retime(const Element &elem, const Time t) noexcept { remove(elem); - push(elem, t); + push(entry_t(t, elem)); } void clear() { + tqlock lck(m_lock); m_end = &m_list[0]; /* put an empty element with maximum time into the queue. * the insert algo above will run into this element and doesn't @@ -137,8 +142,14 @@ namespace netlist const entry_t & operator[](const std::size_t index) const { return m_list[ 1 + index]; } private: + #if HAS_OPENMP && USE_OPENMP + using tqmutex = pspin_mutex<true>; + #else + using tqmutex = pspin_mutex<false>; + #endif + using tqlock = std::lock_guard<tqmutex>; - tqlock m_lock; + tqmutex m_lock; entry_t * m_end; std::vector<entry_t> m_list; diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 46f6a92aed1..2fbc4d5f6f5 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -135,7 +135,7 @@ void setup_t::register_dippins_arr(const pstring &terms) } } -pstring setup_t::objtype_as_str(detail::device_object_t &in) const +pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const { switch (in.type()) { @@ -145,8 +145,6 @@ pstring setup_t::objtype_as_str(detail::device_object_t &in) const return pstring("INPUT"); case terminal_t::OUTPUT: return pstring("OUTPUT"); - case terminal_t::PARAM: - return pstring("PARAM"); } // FIXME: noreturn log().fatal(MF_1_UNKNOWN_OBJECT_TYPE_1, static_cast<unsigned>(in.type())); @@ -199,9 +197,9 @@ void setup_t::register_param(pstring name, param_t ¶m) void setup_t::register_term(detail::core_terminal_t &term) { if (!m_terminals.insert({term.name(), &term}).second) - log().fatal(MF_2_ADDING_1_2_TO_TERMINAL_LIST, objtype_as_str(term), + log().fatal(MF_2_ADDING_1_2_TO_TERMINAL_LIST, termtype_as_str(term), term.name()); - log().debug("{1} {2}\n", objtype_as_str(term), term.name()); + log().debug("{1} {2}\n", termtype_as_str(term), term.name()); } void setup_t::register_link_arr(const pstring &terms) @@ -340,12 +338,12 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool } detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, - detail::device_object_t::type_t atype, bool required) + detail::core_terminal_t::type_t atype, bool required) { const pstring &tname = resolve_alias(terminal_in); auto ret = m_terminals.find(tname); /* look for default */ - if (ret == m_terminals.end() && atype == detail::device_object_t::OUTPUT) + if (ret == m_terminals.end() && atype == detail::core_terminal_t::OUTPUT) { /* look for ".Q" std output */ ret = m_terminals.find(tname + ".Q"); @@ -440,7 +438,6 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) auto ret = new_proxy.get(); -#if 1 /* connect all existing terminals to new net */ if (inp.has_net()) @@ -455,13 +452,6 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) inp.net().m_core_terms.clear(); // clear the list } ret->out().net().add_terminal(inp); -#else - if (inp.has_net()) - //fatalerror("logic inputs can only belong to one net!\n"); - merge_nets(ret->out().net(), inp.net()); - else - ret->out().net().add_terminal(inp); -#endif netlist().register_dev(std::move(new_proxy)); return ret; } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 06f70623ada..79a21a6815b 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -285,7 +285,7 @@ namespace netlist std::unordered_map<pstring, detail::core_terminal_t *> m_terminals; /* needed by proxy */ - detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::device_object_t::type_t atype, bool required = true); + detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::core_terminal_t::type_t atype, bool required = true); private: @@ -300,7 +300,7 @@ namespace netlist bool connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2); // helpers - pstring objtype_as_str(detail::device_object_t &in) const; + pstring termtype_as_str(detail::core_terminal_t &in) const; devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out); devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp); diff --git a/src/lib/netlist/nl_time.h b/src/lib/netlist/nl_time.h index 4edc9524a43..6235c195172 100644 --- a/src/lib/netlist/nl_time.h +++ b/src/lib/netlist/nl_time.h @@ -45,82 +45,83 @@ namespace netlist constexpr explicit ptime(const internal_type nom, const internal_type den) noexcept : m_time(nom * (resolution / den)) { } - ptime &operator=(const ptime rhs) { m_time = rhs.m_time; return *this; } + ptime &operator=(const ptime rhs) noexcept { m_time = rhs.m_time; return *this; } - ptime &operator+=(const ptime &rhs) { m_time += rhs.m_time; return *this; } - ptime &operator-=(const ptime &rhs) { m_time -= rhs.m_time; return *this; } + ptime &operator+=(const ptime &rhs) noexcept { m_time += rhs.m_time; return *this; } + ptime &operator-=(const ptime &rhs) noexcept { m_time -= rhs.m_time; return *this; } - friend ptime operator-(ptime lhs, const ptime &rhs) + friend constexpr ptime operator-(const ptime &lhs, const ptime &rhs) noexcept { - lhs -= rhs; - return lhs; + return ptime(lhs.m_time - rhs.m_time); } - friend ptime operator+(ptime lhs, const ptime &rhs) + friend constexpr ptime operator+(const ptime &lhs, const ptime &rhs) noexcept { - lhs += rhs; - return lhs; + return ptime(lhs.m_time + rhs.m_time); } - friend ptime operator*(ptime lhs, const mult_type factor) + friend constexpr ptime operator*(const ptime &lhs, const mult_type factor) noexcept { - lhs.m_time *= static_cast<internal_type>(factor); - return lhs; + return ptime(lhs.m_time * static_cast<internal_type>(factor)); } - friend mult_type operator/(const ptime &lhs, const ptime &rhs) + friend constexpr mult_type operator/(const ptime &lhs, const ptime &rhs) noexcept { return static_cast<mult_type>(lhs.m_time / rhs.m_time); } - friend bool operator<(const ptime &lhs, const ptime &rhs) + friend constexpr bool operator<(const ptime &lhs, const ptime &rhs) noexcept { return (lhs.m_time < rhs.m_time); } - friend bool operator>(const ptime &lhs, const ptime &rhs) + friend constexpr bool operator>(const ptime &lhs, const ptime &rhs) noexcept { return (rhs < lhs); } - friend bool operator<=(const ptime &lhs, const ptime &rhs) + friend constexpr bool operator<=(const ptime &lhs, const ptime &rhs) noexcept { return !(lhs > rhs); } - friend bool operator>=(const ptime &lhs, const ptime &rhs) + friend constexpr bool operator>=(const ptime &lhs, const ptime &rhs) noexcept { return !(lhs < rhs); } - friend bool operator==(const ptime &lhs, const ptime &rhs) + friend constexpr bool operator==(const ptime &lhs, const ptime &rhs) noexcept { return lhs.m_time == rhs.m_time; } - friend bool operator!=(const ptime &lhs, const ptime &rhs) + friend constexpr bool operator!=(const ptime &lhs, const ptime &rhs) noexcept { return !(lhs == rhs); } - constexpr internal_type as_raw() const { return m_time; } - constexpr double as_double() const { return static_cast<double>(m_time) - / static_cast<double>(resolution); } + constexpr internal_type as_raw() const noexcept { return m_time; } + constexpr double as_double() const noexcept + { + return static_cast<double>(m_time) + / static_cast<double>(resolution); + } // for save states .... - internal_type *get_internaltype_ptr() { return &m_time; } - - static constexpr ptime from_nsec(const internal_type ns) { return ptime(ns, UINT64_C(1000000000)); } - static constexpr ptime from_usec(const internal_type us) { return ptime(us, UINT64_C(1000000)); } - static constexpr ptime from_msec(const internal_type ms) { return ptime(ms, UINT64_C(1000)); } - static constexpr ptime from_hz(const internal_type hz) { return ptime(1 , hz); } - static constexpr ptime from_raw(const internal_type raw) { return ptime(raw, resolution); } - static constexpr ptime from_double(const double t) { return ptime(static_cast<internal_type>( t * static_cast<double>(resolution)), resolution); } - - static constexpr ptime zero() { return ptime(0, resolution); } - static constexpr ptime quantum() { return ptime(1, resolution); } - static constexpr ptime never() { return ptime(plib::numeric_limits<internal_type>::max(), resolution); } + internal_type *get_internaltype_ptr() noexcept { return &m_time; } + + static constexpr ptime from_nsec(const internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); } + static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C(1000000)); } + static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C(1000)); } + static constexpr ptime from_hz(const internal_type hz) noexcept { return ptime(1 , hz); } + static constexpr ptime from_raw(const internal_type raw) noexcept { return ptime(raw); } + static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast<internal_type>( t * static_cast<double>(resolution)), resolution); } + + static constexpr ptime zero() noexcept { return ptime(0, resolution); } + static constexpr ptime quantum() noexcept { return ptime(1, resolution); } + static constexpr ptime never() noexcept { return ptime(plib::numeric_limits<internal_type>::max(), resolution); } private: + constexpr explicit ptime(const internal_type time) : m_time(time) {} internal_type m_time; }; diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 198da5a4cc5..756130dd190 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -41,6 +41,9 @@ typedef __int128_t INT128; #endif #if defined(__GNUC__) +#ifdef RESTRICT +#undef RESTRICT +#endif #define RESTRICT __restrict__ #define ATTR_UNUSED __attribute__((__unused__)) #else @@ -240,7 +243,7 @@ namespace plib { inline R call(O *obj, Targs... args) const { using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args); - return (*reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...); + return (reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...); } private: generic_function m_func; diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 37f4e2a1391..fd9aaa5e176 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -56,6 +56,7 @@ public: template<typename... Args> void emplace(const std::size_t index, Args&&... args) { + // allocate on buffer new (&m_buf[index]) C(std::forward<Args>(args)...); } diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 14b7409b95e..19b453cb069 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -502,30 +502,11 @@ static const pstring pmf_verbose[] = }; #endif -struct tt -{ - void test(int a) {printf ("test :%d\n", a);} - int test1() { return 1;} -}; - -plib::pmfp<void, int> atest; -plib::pmfp<int> atest1; - int main(int argc, char *argv[]) { tool_options_t opts; int ret; - tt x; - - atest.set(&tt::test, &x); - atest1.set(&tt::test1, &x); - - atest(1); - int a = atest1(); - - printf("%d\n", a); - //return 1 ; /* make SIGFPE actually deliver signals on supoorted platforms */ plib::fpsignalenabler::global_enable(true); plib::fpsignalenabler sigen(plib::FP_ALL & ~plib::FP_INEXACT & ~plib::FP_UNDERFLOW); diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 5c0d3c11dc8..8612469431e 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -1,13 +1,12 @@ // license:GPL-2.0+ // copyright-holders:Couriersud -#include <plib/poptions.h> #include <cstdio> #include <cstring> #include "plib/pstring.h" #include "plib/plists.h" #include "plib/pstream.h" +#include "plib/poptions.h" #include "nl_setup.h" -#include <memory> class nlwav_options_t : public plib::options { @@ -143,10 +142,10 @@ private: static void convert() { - plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : new plib::pofilestream(opts.opt_out())); - plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : new plib::pifilestream(opts.opt_inp())); + plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : plib::palloc<plib::pofilestream>(opts.opt_out())); + plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : plib::palloc<plib::pifilestream>(opts.opt_inp())); plib::putf8_reader reader(*fin); - wav_t *wo = new wav_t(*fo, 48000); + wav_t *wo = plib::palloc<wav_t>(*fo, 48000U); double dt = 1.0 / static_cast<double>(wo->sample_rate()); double ct = dt; @@ -213,11 +212,11 @@ static void convert() //printf("%f %f\n", t, v); #endif } - delete wo; + plib::pfree(wo); if (opts.opt_inp() != "-") - delete fin; + plib::pfree(fin); if (opts.opt_out() != "-") - delete fo; + plib::pfree(fo); if (!opts.opt_quiet()) { diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index 051fa10a253..71950174a5a 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -91,11 +91,6 @@ matrix_solver_t::matrix_solver_t(netlist_t &anetlist, const pstring &name, matrix_solver_t::~matrix_solver_t() { - for (unsigned k = 0; k < m_terms.size(); k++) - { - plib::pfree(m_terms[k]); - } - } void matrix_solver_t::setup_base(analog_net_t::list_t &nets) @@ -109,7 +104,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) for (auto & net : nets) { m_nets.push_back(net); - m_terms.push_back(plib::palloc<terms_for_net_t>()); + m_terms.push_back(plib::make_unique<terms_for_net_t>()); m_rails_temp.push_back(plib::palloc<terms_for_net_t>()); } @@ -164,7 +159,6 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) } break; case terminal_t::OUTPUT: - case terminal_t::PARAM: log().fatal(MF_1_UNHANDLED_ELEMENT_1_FOUND, p->name()); break; @@ -242,7 +236,7 @@ void matrix_solver_t::setup_matrix() /* create a list of non zero elements. */ for (unsigned k = 0; k < iN; k++) { - terms_for_net_t * t = m_terms[k]; + terms_for_net_t * t = m_terms[k].get(); /* pretty brutal */ int *other = t->connected_net_idx(); @@ -264,7 +258,7 @@ void matrix_solver_t::setup_matrix() */ for (unsigned k = 0; k < iN; k++) { - terms_for_net_t * t = m_terms[k]; + terms_for_net_t * t = m_terms[k].get(); /* pretty brutal */ int *other = t->connected_net_idx(); @@ -294,9 +288,9 @@ void matrix_solver_t::setup_matrix() * This should reduce cache misses ... */ - bool **touched = new bool*[iN]; + bool **touched = plib::palloc_array<bool *>(iN); for (unsigned k=0; k<iN; k++) - touched[k] = new bool[iN]; + touched[k] = plib::palloc_array<bool>(iN); for (unsigned k = 0; k < iN; k++) { @@ -354,8 +348,8 @@ void matrix_solver_t::setup_matrix() } for (unsigned k=0; k<iN; k++) - delete [] touched[k]; - delete [] touched; + plib::pfree_array(touched[k]); + plib::pfree_array(touched); } void matrix_solver_t::update_inputs() @@ -499,7 +493,7 @@ netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts) for (std::size_t k = 0, iN=m_terms.size(); k < iN; k++) { analog_net_t *n = m_nets[k]; - terms_for_net_t *t = m_terms[k]; + terms_for_net_t *t = m_terms[k].get(); const nl_double DD_n = (n->Q_Analog() - t->m_last_V); const nl_double hn = cur_ts; @@ -548,12 +542,12 @@ void matrix_solver_t::log_stats() log().verbose(" {1:6.3} average newton raphson loops", static_cast<double>(this->m_stat_newton_raphson) / static_cast<double>(this->m_stat_vsolver_calls)); log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average", - this->m_stat_calculations(), - static_cast<double>(this->m_stat_calculations()) / this->netlist().time().as_double(), - this->m_iterative_fail(), - 100.0 * static_cast<double>(this->m_iterative_fail()) - / static_cast<double>(this->m_stat_calculations()), - static_cast<double>(this->m_iterative_total()) / static_cast<double>(this->m_stat_calculations())); + this->m_stat_calculations, + static_cast<double>(this->m_stat_calculations) / this->netlist().time().as_double(), + this->m_iterative_fail, + 100.0 * static_cast<double>(this->m_iterative_fail) + / static_cast<double>(this->m_stat_calculations), + static_cast<double>(this->m_iterative_total) / static_cast<double>(this->m_stat_calculations)); } } diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index fc7ab7fcbdb..3a095fbe1ee 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -161,7 +161,7 @@ protected: template <typename T> void build_LE_RHS(); - std::vector<terms_for_net_t *> m_terms; + std::vector<std::unique_ptr<terms_for_net_t>> m_terms; std::vector<analog_net_t *> m_nets; std::vector<std::unique_ptr<proxied_analog_output_t>> m_inps; diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index a5ee5bbf8c1..e7f89a57e67 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -200,7 +200,7 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) /* add RHS element */ for (unsigned k = 0; k < N(); k++) { - terms_for_net_t * t = m_terms[k]; + terms_for_net_t * t = m_terms[k].get(); if (!plib::container::contains(t->m_nzrd, N())) t->m_nzrd.push_back(N()); diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index 853cc34d39c..99fde152f51 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -96,7 +96,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) bool touched[storage_N][storage_N] = { { false } }; for (unsigned k = 0; k < iN; k++) { - for (auto & j : this->m_terms[k]->m_nz) + for (auto &j : this->m_terms[k]->m_nz) touched[k][j] = true; } @@ -255,7 +255,7 @@ unsigned matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newt for (unsigned k = 0; k < iN; k++) { - terms_for_net_t *t = this->m_terms[k]; + terms_for_net_t *t = this->m_terms[k].get(); nl_double gtot_t = 0.0; nl_double RHS_t = 0.0; diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index 0c5a5e6228f..baa61723cf9 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -81,7 +81,7 @@ void matrix_solver_GMRES_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) for (unsigned k=0; k<iN; k++) { - terms_for_net_t * RESTRICT row = this->m_terms[k]; + terms_for_net_t * RESTRICT row = this->m_terms[k].get(); mat.ia[k] = nz; for (unsigned j=0; j<row->m_nz.size(); j++) diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 629c7c0173e..fe60d6f3c95 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -297,12 +297,12 @@ void NETLIB_NAME(solver)::post_start() switch (net_count) { -#if 1 +#if 0 case 1: - ms = create_solver<1,1>(1, use_specific); + ms = create_solver<1,1>(1, false); break; case 2: - ms = create_solver<2,2>(2, use_specific); + ms = create_solver<2,2>(2, false); break; case 3: ms = create_solver<3,3>(3, use_specific); @@ -322,6 +322,9 @@ void NETLIB_NAME(solver)::post_start() case 8: ms = create_solver<8,8>(8, use_specific); break; + case 9: + ms = create_solver<9,9>(9, use_specific); + break; case 10: ms = create_solver<10,10>(10, use_specific); break; |