diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index e8b28792656..a78b4b5f2fc 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -1184,7 +1184,7 @@ ATTR_COLD void netlist_mame_device::device_pre_save() netlist().run_state_manager().pre_save(); } -void netlist_mame_device::update_icount(netlist::netlist_time time) +void netlist_mame_device::update_icount(netlist::netlist_time time) noexcept { const netlist::netlist_time newt(time); const netlist::netlist_time delta(newt - m_old + m_rem); @@ -1194,7 +1194,7 @@ void netlist_mame_device::update_icount(netlist::netlist_time time) m_icount -= d; } -void netlist_mame_device::check_mame_abort_slice() +void netlist_mame_device::check_mame_abort_slice() noexcept { if (m_icount <= 0) netlist().abort_current_queue_slice(); diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index 0667f4e41fc..52d7602248a 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -72,11 +72,11 @@ public: void set_setup_func(func_type &&func) { m_setup_func = std::move(func); } - ATTR_HOT inline netlist::setup_t &setup(); - ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; } + netlist::setup_t &setup(); + netlist_mame_t &netlist() noexcept { return *m_netlist; } - ATTR_HOT void update_icount(netlist::netlist_time time); - ATTR_HOT void check_mame_abort_slice(); + void update_icount(netlist::netlist_time time) noexcept; + void check_mame_abort_slice() noexcept; static void register_memregion_source(netlist::nlparse_t &setup, device_t &dev, const char *name); diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 961a2f4cc89..6f75a1d9612 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -26,6 +26,7 @@ TIDY_FLAGSX += -bugprone-macro-parentheses,-misc-macro-parentheses, TIDY_FLAGSX += -modernize-use-trailing-return-type TIDY_FLAGSX += -bugprone-too-small-loop-variable TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-array-to-pointer-decay +TIDY_FLAGSX += -modernize-use-trailing-return-type space := space += diff --git a/src/lib/netlist/devices/nld_4020.cpp b/src/lib/netlist/devices/nld_4020.cpp index d0e35f502b7..97161071306 100644 --- a/src/lib/netlist/devices/nld_4020.cpp +++ b/src/lib/netlist/devices/nld_4020.cpp @@ -34,7 +34,7 @@ namespace netlist NETLIB_UPDATEI(); public: - void update_outputs(const unsigned cnt); + void update_outputs(const unsigned cnt) NL_NOEXCEPT; logic_input_t m_IP; object_array_t m_Q; diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp index 23daf983174..34826a068f9 100644 --- a/src/lib/netlist/devices/nld_7448.cpp +++ b/src/lib/netlist/devices/nld_7448.cpp @@ -36,7 +36,7 @@ namespace netlist NETLIB_UPDATEI(); public: - void update_outputs(unsigned v); + void update_outputs(unsigned v) NL_NOEXCEPT; logic_input_t m_A; logic_input_t m_B; diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp index 157563f5f0c..497547c3630 100644 --- a/src/lib/netlist/devices/nld_7490.cpp +++ b/src/lib/netlist/devices/nld_7490.cpp @@ -34,7 +34,7 @@ namespace netlist NETLIB_UPDATEI(); NETLIB_RESETI(); - void update_outputs(); + void update_outputs() NL_NOEXCEPT; logic_input_t m_A; logic_input_t m_B; diff --git a/src/lib/netlist/devices/nld_am2847.cpp b/src/lib/netlist/devices/nld_am2847.cpp index d4a7cbe53b7..8153274e523 100644 --- a/src/lib/netlist/devices/nld_am2847.cpp +++ b/src/lib/netlist/devices/nld_am2847.cpp @@ -27,7 +27,7 @@ namespace netlist NETLIB_UPDATEI(); public: - void shift(); + void shift() NL_NOEXCEPT; logic_input_t m_RC; logic_input_t m_IN; diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 7035aa73b2e..034422792cd 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -107,7 +107,7 @@ const logic_family_desc_t *family_CD4XXX() // ---------------------------------------------------------------------------------------- detail::queue_t::queue_t(netlist_state_t &nl) - : timed_queue, false, true>(512) + : timed_queue, false>(512) , netlist_ref(nl) , m_qsize(0) , m_times(512) @@ -142,7 +142,7 @@ void detail::queue_t::on_post_load(plib::state_manager_t &manager) for (std::size_t i = 0; i < m_qsize; i++ ) { detail::net_t *n = state().nets()[m_net_ids[i]].get(); - this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n)); + this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n)); } } @@ -740,7 +740,7 @@ void detail::net_t::update_devs() NL_NOEXCEPT { case core_terminal_t::STATE_INP_HL: case core_terminal_t::STATE_INP_LH: - process(mask | core_terminal_t::STATE_INP_ACTIVE, new_Q); + process(mask, new_Q); break; default: /* do nothing */ @@ -749,20 +749,10 @@ void detail::net_t::update_devs() NL_NOEXCEPT #else nl_assert(this->isRailNet()); - const unsigned int mask((m_new_Q << core_terminal_t::INP_LH_SHIFT) - | (m_cur_Q << core_terminal_t::INP_HL_SHIFT)); - m_in_queue = queue_status::DELIVERED; /* mark as taken ... */ - switch (mask) - { - case core_terminal_t::STATE_INP_HL: - case core_terminal_t::STATE_INP_LH: - process(mask | core_terminal_t::STATE_INP_ACTIVE, m_new_Q); - break; - default: - /* do nothing */ - break; - } + if (m_new_Q ^ m_cur_Q) + process((m_new_Q << core_terminal_t::INP_LH_SHIFT) + | (m_cur_Q << core_terminal_t::INP_HL_SHIFT), m_new_Q); #endif } @@ -791,7 +781,7 @@ void detail::net_t::reset() } } -void detail::net_t::add_terminal(detail::core_terminal_t &terminal) +void detail::net_t::add_terminal(detail::core_terminal_t &terminal) NL_NOEXCEPT { for (auto &t : m_core_terms) if (t == &terminal) @@ -802,7 +792,7 @@ void detail::net_t::add_terminal(detail::core_terminal_t &terminal) m_core_terms.push_back(&terminal); } -void detail::net_t::remove_terminal(detail::core_terminal_t &terminal) +void detail::net_t::remove_terminal(detail::core_terminal_t &terminal) NL_NOEXCEPT { if (plib::container::contains(m_core_terms, &terminal)) { @@ -1002,7 +992,7 @@ param_t::param_type_t param_t::param_type() const } -void param_t::update_param() +void param_t::update_param() NL_NOEXCEPT { device().update_param(); } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index e58a439a35c..e3868944d7d 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -98,7 +98,7 @@ class NETLIB_NAME(name) : public device_t * device a dynamic device if parameter m_func is set. */ #define NETLIB_IS_DYNAMIC(expr) \ - public: virtual bool is_dynamic() const override { return expr; } + public: virtual bool is_dynamic() const NL_NOEXCEPT override { return expr; } /*! Add this to a device definition to mark the device as a time-stepping device. * @@ -122,26 +122,26 @@ class NETLIB_NAME(name) : public device_t * */ #define NETLIB_IS_TIMESTEP(expr) \ - public: virtual bool is_timestep() const override { return expr; } + public: virtual bool is_timestep() const NL_NOEXCEPT override { return expr; } /*! Used to implement the time stepping code. * * Please see NETLIB_IS_TIMESTEP for an example. */ #define NETLIB_TIMESTEPI() \ - public: virtual void timestep(const nl_double step) override + public: virtual void timestep(const nl_double step) NL_NOEXCEPT override #define NETLIB_FAMILY(family) , m_famsetter(*this, family) #define NETLIB_DELEGATE(chip, name) nldelegate(&NETLIB_NAME(chip) :: name, this) -#define NETLIB_UPDATE_TERMINALSI() virtual void update_terminals() override +#define NETLIB_UPDATE_TERMINALSI() virtual void update_terminals() NL_NOEXCEPT override #define NETLIB_HANDLERI(name) virtual void name() NL_NOEXCEPT #define NETLIB_UPDATEI() virtual void update() NL_NOEXCEPT override -#define NETLIB_UPDATE_PARAMI() virtual void update_param() override +#define NETLIB_UPDATE_PARAMI() virtual void update_param() NL_NOEXCEPT override #define NETLIB_RESETI() virtual void reset() override -#define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(const nl_double step) +#define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(nl_double step) NL_NOEXCEPT #define NETLIB_SUB(chip) nld_ ## chip #define NETLIB_SUBXX(ns, chip) unique_pool_ptr< ns :: nld_ ## chip > @@ -151,10 +151,10 @@ class NETLIB_NAME(name) : public device_t #define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void) -#define NETLIB_UPDATE_PARAM(chip) void NETLIB_NAME(chip) :: update_param() -#define NETLIB_FUNC_VOID(chip, name, params) void NETLIB_NAME(chip) :: name params +#define NETLIB_UPDATE_PARAM(chip) void NETLIB_NAME(chip) :: update_param() NL_NOEXCEPT +#define NETLIB_FUNC_VOID(chip, name, params) void NETLIB_NAME(chip) :: name params NL_NOEXCEPT -#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals() +#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals() NL_NOEXCEPT //============================================================ // Asserts @@ -254,13 +254,13 @@ namespace netlist virtual unique_pool_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; } - double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; } - double high_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_high_thresh_PCNT; } - double low_offset_V() const { return m_low_VO; } - double high_offset_V() const { return m_high_VO; } - double R_low() const { return m_R_low; } - double R_high() const { return m_R_high; } + double fixed_V() const noexcept{ return m_fixed_V; } + double low_thresh_V(const double VN, const double VP) const noexcept{ return VN + (VP - VN) * m_low_thresh_PCNT; } + double high_thresh_V(const double VN, const double VP) const noexcept{ return VN + (VP - VN) * m_high_thresh_PCNT; } + double low_offset_V() const noexcept{ return m_low_VO; } + double high_offset_V() const noexcept{ return m_high_VO; } + double R_low() const noexcept{ return m_R_low; } + double R_high() const noexcept{ return m_R_high; } double m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. */ double m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled @@ -285,11 +285,9 @@ namespace netlist class logic_family_t { public: - logic_family_t() : m_logic_family(nullptr) {} COPYASSIGNMOVE(logic_family_t, delete) - 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; } @@ -321,7 +319,7 @@ namespace netlist template //! Constructor. state_var(O &owner, //!< owner must have a netlist() method. - const pstring &name, //!< identifier/name for this state variable + const pstring &name, //!< identifier/name for this state variable const T &value //!< Initial value after construction ); @@ -332,7 +330,7 @@ namespace netlist //! Move Constructor. constexpr state_var(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of a state var. - C14CONSTEXPR state_var &operator=(const state_var &rhs) = default; + C14CONSTEXPR state_var &operator=(const state_var &rhs) /*noexcept*/ = default; // OSX doesn't like noexcept //! Assignment move operator to assign value of a state var. C14CONSTEXPR state_var &operator=(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of type T. @@ -355,7 +353,7 @@ namespace netlist * Please refer to \ref state_var. */ template - struct state_array + struct state_array : public std::array { public: //! Constructor. @@ -372,12 +370,6 @@ namespace netlist state_array(state_array &&rhs) noexcept = default; state_array &operator=(const state_array &rhs) noexcept = default; state_array &operator=(state_array &&rhs) noexcept = default; - - state_array &operator=(const T &rhs) noexcept { m_value = rhs; return *this; } - T & operator[](const std::size_t i) noexcept { return m_value[i]; } - constexpr const T & operator[](const std::size_t i) const noexcept { return m_value[i]; } - private: - std::array m_value; }; // ----------------------------------------------------------------------------- @@ -401,22 +393,22 @@ namespace netlist template struct property_store_t { - static void add(const C *obj, const T &aname) + static void add(const C *obj, const T &aname) noexcept { store().insert({obj, aname}); } - static const T get(const C *obj) + static const T get(const C *obj) noexcept { return store().find(obj)->second; } - static void remove(const C *obj) + static void remove(const C *obj) noexcept { store().erase(store().find(obj)); } - static std::unordered_map &store() + static std::unordered_map &store() noexcept { static std::unordered_map lstore; return lstore; @@ -453,7 +445,7 @@ namespace netlist * * \returns name of the object. */ - pstring name() const + pstring name() const noexcept { return props::get(this); } @@ -549,17 +541,14 @@ namespace netlist { public: - using list_t = std::vector; - static constexpr const unsigned int INP_HL_SHIFT = 0; static constexpr const unsigned int INP_LH_SHIFT = 1; - static constexpr const unsigned int INP_ACTIVE_SHIFT = 2; enum state_e { STATE_INP_PASSIVE = 0, STATE_INP_HL = (1 << INP_HL_SHIFT), STATE_INP_LH = (1 << INP_LH_SHIFT), - STATE_INP_ACTIVE = (1 << INP_ACTIVE_SHIFT), + STATE_INP_ACTIVE = STATE_INP_HL | STATE_INP_LH, STATE_OUT = 128, STATE_BIDIR = 256 }; @@ -669,8 +658,8 @@ namespace netlist /* setup stuff */ - void add_terminal(core_terminal_t &terminal); - void remove_terminal(core_terminal_t &terminal); + void add_terminal(core_terminal_t &terminal) NL_NOEXCEPT; + void remove_terminal(core_terminal_t &terminal) NL_NOEXCEPT; bool is_logic() const NL_NOEXCEPT; bool is_analog() const NL_NOEXCEPT; @@ -730,7 +719,7 @@ namespace netlist * FIXME: get rid of this and implement export/import in MAME */ /* only used for logic nets */ - netlist_sig_t *Q_state_ptr() { return m_cur_Q.ptr(); } + netlist_sig_t *Q_state_ptr() noexcept { return m_cur_Q.ptr(); } private: state_var m_new_Q; @@ -989,12 +978,12 @@ namespace netlist protected: virtual ~param_t() noexcept = default; /* not intended to be destroyed */ - void update_param(); + void update_param() NL_NOEXCEPT; pstring get_initial(const device_t &dev, bool *found); template - void set(C &p, const C v) + void set(C &p, const C v) noexcept { if (p != v) { @@ -1018,7 +1007,7 @@ namespace netlist T operator()() const NL_NOEXCEPT { return m_param; } operator T() const NL_NOEXCEPT { return m_param; } - void setTo(const T ¶m) { set(m_param, param); } + void setTo(const T ¶m) noexcept { set(m_param, param); } private: T m_param; }; @@ -1031,7 +1020,7 @@ namespace netlist T operator()() const NL_NOEXCEPT { return T(m_param); } operator T() const NL_NOEXCEPT { return T(m_param); } - void setTo(const T ¶m) { set(m_param, static_cast(param)); } + void setTo(const T ¶m) noexcept { set(m_param, static_cast(param)); } private: int m_param; }; @@ -1050,7 +1039,7 @@ namespace netlist public: param_ptr_t(device_t &device, const pstring &name, std::uint8_t* val); std::uint8_t * operator()() const NL_NOEXCEPT { return m_param; } - void setTo(std::uint8_t *param) { set(m_param, param); } + void setTo(std::uint8_t *param) noexcept { set(m_param, param); } private: std::uint8_t* m_param; }; @@ -1200,10 +1189,10 @@ namespace netlist } } - void set_hint_deactivate(bool v) { m_hint_deactivate = v; } - bool get_hint_deactivate() { return m_hint_deactivate; } + void set_hint_deactivate(bool v) noexcept { m_hint_deactivate = v; } + bool get_hint_deactivate() const noexcept { return m_hint_deactivate; } /* Has to be set in device reset */ - void set_active_outputs(int n) { m_active_outputs = n; } + void set_active_outputs(int n) noexcept { m_active_outputs = n; } void set_default_delegate(detail::core_terminal_t &term); @@ -1229,12 +1218,12 @@ namespace netlist log_type & log(); public: - virtual void timestep(const nl_double st) { plib::unused_var(st); } - virtual void update_terminals() { } + virtual void timestep(const nl_double st) NL_NOEXCEPT { plib::unused_var(st); } + virtual void update_terminals() NL_NOEXCEPT { } - virtual void update_param() {} - virtual bool is_dynamic() const { return false; } - virtual bool is_timestep() const { return false; } + virtual void update_param() NL_NOEXCEPT {} + virtual bool is_dynamic() const NL_NOEXCEPT { return false; } + virtual bool is_timestep() const NL_NOEXCEPT { return false; } private: bool m_hint_deactivate; @@ -1303,12 +1292,12 @@ namespace netlist */ class detail::queue_t : //public timed_queue, false, NL_KEEP_STATISTICS>, - public timed_queue, false, true>, + public timed_queue, false>, public detail::netlist_ref, public plib::state_manager_t::callback_t { public: - using base_queue = timed_queue, false, true>; + using base_queue = timed_queue, false>; using entry_t = pqentry_t; explicit queue_t(netlist_state_t &nl); virtual ~queue_t() noexcept = default; @@ -1550,25 +1539,31 @@ namespace netlist netlist_time time() const NL_NOEXCEPT { return m_time; } void process_queue(netlist_time delta) NL_NOEXCEPT; - void abort_current_queue_slice() NL_NOEXCEPT { m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); } + void abort_current_queue_slice() NL_NOEXCEPT + { + if (!USE_QUEUE_STATS || !m_use_stats) + m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); + else + m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); + } const detail::queue_t &queue() const NL_NOEXCEPT { return m_queue; } void qpush(detail::queue_t::entry_t && e) noexcept { if (!USE_QUEUE_STATS || !m_use_stats) - m_queue.push_nostats(std::move(e)); // NOLINT(performance-move-const-arg) + m_queue.push(std::move(e)); // NOLINT(performance-move-const-arg) else - m_queue.push(std::move(e)); // NOLINT(performance-move-const-arg) + m_queue.push(std::move(e)); // NOLINT(performance-move-const-arg) } template void qremove(const R &elem) noexcept { if (!USE_QUEUE_STATS || !m_use_stats) - m_queue.remove_nostats(elem); + m_queue.remove(elem); else - m_queue.remove(elem); + m_queue.remove(elem); } /* Control functions */ @@ -1905,9 +1900,9 @@ namespace netlist template state_array::state_array(O &owner, const pstring &name, const T & value) { - owner.state().save(owner, m_value, owner.name(), name); + owner.state().save(owner, *static_cast *>(this), owner.name(), name); for (std::size_t i=0; i {1} nets") - PERRMSGV(MI_NO_SPECIFIC_SOLVER, 1, "No specific solver found for netlist of size {1}") // nld_mm5837.cpp diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index f4b1c4e8ff5..27db664cc05 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -69,37 +69,34 @@ namespace netlist std::swap(m_object, other.m_object); } #endif - struct QueueOp + inline bool operator ==(const pqentry_t &rhs) const noexcept { - inline static constexpr bool less(const pqentry_t &lhs, const pqentry_t &rhs) noexcept - { - return (lhs.m_exec_time < rhs.m_exec_time); - } + return m_object == rhs.m_object; + } - inline static constexpr bool lessequal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept - { - return (lhs.m_exec_time <= rhs.m_exec_time); - } + inline bool operator ==(const Element &rhs) const noexcept + { + return m_object == rhs; + } - inline static constexpr bool equal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept - { - return lhs.m_object == rhs.m_object; - } + inline bool operator <=(const pqentry_t &rhs) const noexcept + { + return (m_exec_time <= rhs.m_exec_time); + } - inline static constexpr bool equal(const pqentry_t &lhs, const Element &rhs) noexcept - { - return lhs.m_object == rhs; - } + inline bool operator <(const pqentry_t &rhs) const noexcept + { + return (m_exec_time < rhs.m_exec_time); + } - inline static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); } - }; + inline static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); } Time m_exec_time; Element m_object; }; /* Use TS = true for a threadsafe queue */ - template + template class timed_queue_linear : plib::nocopyassignmove { public: @@ -113,28 +110,31 @@ namespace netlist std::size_t capacity() const noexcept { return m_list.capacity() - 1; } bool empty() const noexcept { return (m_end == &m_list[1]); } + template void push(T && e) noexcept { /* Lock */ lock_guard_type lck(m_lock); T * i(m_end-1); - for (; QueueOp::less(*(i), e); --i) + for (; *i < e; --i) { *(i+1) = *(i); - m_prof_sortmove.inc(); + if (KEEPSTAT) + m_prof_sortmove.inc(); } *(i+1) = std::move(e); ++m_end; - m_prof_call.inc(); + if (KEEPSTAT) + m_prof_call.inc(); } - void push_nostats(T && e) noexcept + void push_nostatsx(T && e) noexcept { /* Lock */ lock_guard_type lck(m_lock); #if 1 T * i(m_end-1); - for (; QueueOp::less(*(i), e); --i) + for (; *i < e; --i) { *(i+1) = *(i); } @@ -153,22 +153,18 @@ namespace netlist T pop() noexcept { return *(--m_end); } const T &top() const noexcept { return *(m_end-1); } - template + template void remove(const R &elem) noexcept - { - m_prof_remove.inc(); - remove_nostats(elem); - } - - template - void remove_nostats(const R &elem) noexcept { /* Lock */ lock_guard_type lck(m_lock); + if (KEEPSTAT) + m_prof_remove.inc(); #if 1 for (T * i = m_end - 1; i > &m_list[0]; --i) { - if (QueueOp::equal(*i, elem)) + // == operator ignores time! + if (*i == elem) { std::copy(i+1, m_end--, i); return; @@ -186,23 +182,25 @@ namespace netlist #endif } - void retime(T && elem) noexcept + template + void retime(R && elem) noexcept { /* Lock */ lock_guard_type lck(m_lock); - m_prof_retime.inc(); + if (KEEPSTAT) + m_prof_retime.inc(); - for (T * i = m_end - 1; i > &m_list[0]; --i) + for (R * i = m_end - 1; i > &m_list[0]; --i) { - if (QueueOp::equal(*i, elem)) // partial equal! + if (*i == elem) // partial equal! { *i = std::move(elem); - while (QueueOp::less(*(i-1), *i)) + while (*(i-1) < *i) { std::swap(*(i-1), *i); --i; } - while (i < m_end && QueueOp::less(*i, *(i+1))) + while (i < m_end && *i < *(i+1)) { std::swap(*(i+1), *i); ++i; @@ -220,7 +218,7 @@ namespace netlist * the insert algo above will run into this element and doesn't * need a comparison with queue start. */ - m_list[0] = QueueOp::never(); + m_list[0] = T::never(); m_end++; } @@ -241,20 +239,20 @@ namespace netlist public: // profiling - nperfcount_t m_prof_sortmove; - nperfcount_t m_prof_call; - nperfcount_t m_prof_remove; - nperfcount_t m_prof_retime; + nperfcount_t m_prof_sortmove; + nperfcount_t m_prof_call; + nperfcount_t m_prof_remove; + nperfcount_t m_prof_retime; }; - template + template class timed_queue_heap : plib::nocopyassignmove { public: struct compare { - constexpr bool operator()(const T &a, const T &b) const { return QueueOp::lessequal(b,a); } + constexpr bool operator()(const T &a, const T &b) const { return b <= a; } }; explicit timed_queue_heap(const std::size_t list_size) @@ -266,13 +264,15 @@ namespace netlist std::size_t capacity() const noexcept { return m_list.capacity(); } bool empty() const noexcept { return &m_list[0] == m_end; } + template void push(T &&e) noexcept { /* Lock */ lock_guard_type lck(m_lock); *m_end++ = e; std::push_heap(&m_list[0], m_end, compare()); - m_prof_call.inc(); + if (KEEPSTAT) + m_prof_call.inc(); } T pop() noexcept @@ -285,14 +285,16 @@ namespace netlist const T &top() const noexcept { return m_list[0]; } - template + template void remove(const R &elem) noexcept { /* Lock */ lock_guard_type lck(m_lock); + if (KEEPSTAT) + m_prof_remove.inc(); for (T * i = m_end - 1; i >= &m_list[0]; i--) { - if (QueueOp::equal(*i, elem)) + if (*i == elem) { m_end--; for (;i < m_end; i++) @@ -303,13 +305,16 @@ namespace netlist } } + template void retime(const T &elem) noexcept { /* Lock */ lock_guard_type lck(m_lock); + if (KEEPSTAT) + m_prof_retime.inc(); for (T * i = m_end - 1; i >= &m_list[0]; i--) { - if (QueueOp::equal(*i, elem)) // partial equal! + if (*i == elem) // partial equal! { *i = elem; std::make_heap(&m_list[0], m_end, compare()); @@ -340,18 +345,23 @@ namespace netlist public: // profiling - nperfcount_t m_prof_sortmove; - nperfcount_t m_prof_call; + nperfcount_t m_prof_sortmove; + nperfcount_t m_prof_call; + nperfcount_t m_prof_remove; + nperfcount_t m_prof_retime; }; + template + using timed_queue = timed_queue_linear; + /* * Use timed_queue_heap to use stdc++ heap functions instead of linear processing. * * This slows down processing by about 25% on a Kaby Lake. */ - template - using timed_queue = timed_queue_linear; + //template + //using timed_queue = timed_queue_heap; } // namespace netlist diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h index 8ceee16d9cc..8c5c724c581 100644 --- a/src/lib/netlist/plib/gmres.h +++ b/src/lib/netlist/plib/gmres.h @@ -223,6 +223,8 @@ namespace plib gmres_t(std::size_t size) : residual(size) , Ax(size) + , m_ht(RESTART +1, RESTART) + , m_v(RESTART + 1, size) , m_size(size) , m_use_more_precise_stop_condition(false) { @@ -416,12 +418,12 @@ namespace plib plib::parray m_c; /* mr + 1 */ plib::parray m_g; /* mr + 1 */ - plib::parray, RESTART + 1> m_ht; /* (mr + 1), mr */ + plib::parray2D m_ht; /* (mr + 1), mr */ plib::parray m_s; /* mr + 1 */ plib::parray m_y; /* mr + 1 */ - //plib::parray m_v[RESTART + 1]; /* mr + 1, n */ - plib::parray, RESTART + 1> m_v; /* mr + 1, n */ + //plib::parray, RESTART + 1> m_v; /* mr + 1, n */ + plib::parray2D m_v; /* mr + 1, n */ std::size_t m_size; diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h index 9ddf2f2d39f..bc06d151042 100644 --- a/src/lib/netlist/plib/mat_cr.h +++ b/src/lib/netlist/plib/mat_cr.h @@ -36,7 +36,7 @@ namespace plib using index_type = C; using value_type = T; - static constexpr const int NSQ = (N > 0 ? -N * N : N * N); + static constexpr const int NSQ = (N < 0 ? -N * N : N * N); static constexpr const int Np1 = (N == 0) ? 0 : (N < 0 ? N - 1 : N + 1); COPYASSIGNMOVE(pmatrix_cr_t, default) @@ -64,7 +64,9 @@ namespace plib , m_size(n) { for (index_type i=0; i(i); } ilu_rows[p] = 0; // end of array this->build_from_fill_mat(fill, ilup); //, m_band_width); // ILU(2) diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h index 577de2d3dfc..b385da56eab 100644 --- a/src/lib/netlist/plib/parray.h +++ b/src/lib/netlist/plib/parray.h @@ -30,8 +30,9 @@ namespace plib { template struct sizeabs { - static constexpr const std::size_t ABS = 0; - using container = typename std::vector>; + static constexpr std::size_t ABS() { return 0; } + //using container = typename std::vector>; + using container = typename std::vector; }; /** @@ -63,27 +64,35 @@ namespace plib { using value_type = typename base_type::value_type; template - parray(size_type size, typename std::enable_if::type = 0) + parray(size_type size, typename std::enable_if<(X==0), int>::type = 0) : m_a(size), m_size(size) { } #if 1 +#if 0 + struct tag {}; /* allow construction in fixed size arrays */ template - parray(typename std::enable_if<(X > 0), int>::type = 0) + parray(tag A = tag(), typename std::enable_if<(X >= 0), int>::type = 0) : m_size(X) { } +#else + /* allow construction in fixed size arrays */ + parray() + : m_size(SIZEABS()) + { + } +#endif #endif template - parray(size_type size, typename std::enable_if::type = 0) + parray(size_type size, typename std::enable_if<(X != 0), int>::type = 0) : m_size(size) { - if (SIZE < 0 && size > SIZEABS()) - throw plib::pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZEABS())); - else if (SIZE > 0 && size != SIZEABS()) - throw plib::pexception("parray: size error"); + if ((SIZE < 0 && size > SIZEABS()) + || (SIZE > 0 && size != SIZEABS())) + throw plib::pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZE)); } inline size_type size() const noexcept { return SIZE <= 0 ? m_size : SIZEABS(); } @@ -122,6 +131,27 @@ namespace plib { PALIGNAS_CACHELINE() size_type m_size; }; + + template + struct parray2D : public parray, SIZE1> + { + public: + + using size_type = std::size_t; + + parray2D(size_type size1, size_type size2) + : parray, SIZE1>(size1) + { + if (SIZE2 <= 0) + { + for (size_type i=0; i < this->size(); i++) + (*this)[i] = parray(size2); + } + } + }; + } // namespace plib + + #endif /* PARRAY_H_ */ diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 525a65a97f2..727dad5d936 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -209,7 +209,7 @@ public: explicit constexpr iter_t(LC* x) noexcept : p(x) { } constexpr iter_t(iter_t &rhs) noexcept : p(rhs.p) { } iter_t(iter_t &&rhs) noexcept { std::swap(*this, rhs); } - iter_t& operator=(const iter_t &rhs) noexcept { iter_t t(rhs); std::swap(*this, t); return *this; } + iter_t& operator=(const iter_t &rhs) noexcept { p = rhs.p; return *this; } iter_t& operator=(iter_t &&rhs) noexcept { std::swap(*this, rhs); return *this; } iter_t& operator++() noexcept {p = p->next();return *this;} // NOLINTNEXTLINE(cert-dcl21-cpp) @@ -219,8 +219,8 @@ public: constexpr bool operator==(const iter_t& rhs) const noexcept {return p == rhs.p;} constexpr bool operator!=(const iter_t& rhs) const noexcept {return p != rhs.p;} - /* constexpr */ LC& operator*() noexcept {return *p;} - /* constexpr */ LC* operator->() noexcept {return p;} + constexpr LC& operator*() noexcept {return *p;} + constexpr LC* operator->() noexcept {return p;} constexpr LC& operator*() const noexcept {return *p;} constexpr LC* operator->() const noexcept {return p;} @@ -269,8 +269,19 @@ public: } LC *front() const noexcept { return m_head; } - void clear() noexcept { m_head = nullptr; } constexpr bool empty() const noexcept { return (m_head == nullptr); } + void clear() noexcept + { + LC *p(m_head); + while (p != nullptr) + { + LC *n(p->m_next); + p->m_next = nullptr; + p->m_prev = nullptr; + p = n; + } + m_head = nullptr; + } private: LC *m_head; diff --git a/src/lib/netlist/plib/ppmf.h b/src/lib/netlist/plib/ppmf.h index 6ce65d4e960..9c5c989da0b 100644 --- a/src/lib/netlist/plib/ppmf.h +++ b/src/lib/netlist/plib/ppmf.h @@ -176,13 +176,13 @@ namespace plib { *reinterpret_cast(&m_func) = t; } template - inline R call(O *obj, Targs... args) + inline R call(O *obj, Targs... args) const noexcept(true) { using function_ptr = R (O::*)(Targs...); function_ptr t = *reinterpret_cast(&m_func); return (obj->*t)(std::forward(args)...); } - bool is_set() { + bool is_set() const { #if defined(_MSC_VER) || (defined (__INTEL_COMPILER) && defined (_M_X64)) int *p = reinterpret_cast(&m_func); int *e = p + sizeof(generic_function) / sizeof(int); @@ -225,12 +225,12 @@ namespace plib { #endif } template - R call(O *obj, Targs... args) const + R call(O *obj, Targs... args) const noexcept(true) { using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args); return (reinterpret_cast(m_func))(obj, std::forward(args)...); } - bool is_set() noexcept { return m_func != nullptr; } + bool is_set() const noexcept { return m_func != nullptr; } generic_function get_function() const noexcept { return m_func; } private: generic_function m_func; @@ -244,7 +244,7 @@ namespace plib { class generic_class; template - using MemberFunctionType = R (C::*)(Targs...); + using MemberFunctionType = R (C::*)(Targs...); // noexcept(true) --> c++-17 pmfp() : pmfp_base(), m_obj(nullptr) {} @@ -263,7 +263,7 @@ namespace plib { m_obj = reinterpret_cast(object); } - inline R operator()(Targs ... args) + inline R operator()(Targs ... args) const noexcept(true) { return this->call(m_obj, std::forward(args)...); } diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index c428a08ce25..0692824b97c 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -319,8 +319,7 @@ namespace devices } else { - log().fatal(MF_NETGROUP_SIZE_EXCEEDED_1(128)); - return; /* tease compilers */ + ms = create_solver(net_count, sname); } break; }