summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-10-15 23:36:48 +0200
committer couriersud <couriersud@gmx.org>2019-10-15 23:36:48 +0200
commite5cceda2189fc04f4f4ed19748f78522b9033029 (patch)
tree3ca6c7eba136e5def9c03844fcbd5730b24d7003 /src/lib/netlist
parent88f544f02fddf6d15f2b3de90c8d3514d39b55d5 (diff)
Netlist: code maintenance and bug fixes. [Couriersud]
- optimized the core queue dispatching logic. Minor performance increase. - fixed a number of bugs in parray. Now parray<double, 0> will be purely dynamic allocation with the number of elements passed in the constructor. - Added noexpr where appropriate. - Simplified the queue Checked with gcc-7 (ubuntu), gcc-9, clang-10, macosx clang 10, mingw cross compile on linux.
Diffstat (limited to 'src/lib/netlist')
-rw-r--r--src/lib/netlist/build/makefile1
-rw-r--r--src/lib/netlist/devices/nld_4020.cpp2
-rw-r--r--src/lib/netlist/devices/nld_7448.cpp2
-rw-r--r--src/lib/netlist/devices/nld_7490.cpp2
-rw-r--r--src/lib/netlist/devices/nld_am2847.cpp2
-rw-r--r--src/lib/netlist/nl_base.cpp28
-rw-r--r--src/lib/netlist/nl_base.h117
-rw-r--r--src/lib/netlist/nl_config.h2
-rw-r--r--src/lib/netlist/nl_errstr.h3
-rw-r--r--src/lib/netlist/nl_lists.h120
-rw-r--r--src/lib/netlist/plib/gmres.h8
-rw-r--r--src/lib/netlist/plib/mat_cr.h13
-rw-r--r--src/lib/netlist/plib/parray.h48
-rw-r--r--src/lib/netlist/plib/plists.h19
-rw-r--r--src/lib/netlist/plib/ppmf.h12
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp3
16 files changed, 209 insertions, 173 deletions
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<logic_output_t, 14> 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<pqentry_t<net_t *, netlist_time>, false, true>(512)
+ : timed_queue<pqentry_t<net_t *, netlist_time>, 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<false>(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<KEEP_STATS>(mask | core_terminal_t::STATE_INP_ACTIVE, new_Q);
+ process<KEEP_STATS>(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<KEEP_STATS>(mask | core_terminal_t::STATE_INP_ACTIVE, m_new_Q);
- break;
- default:
- /* do nothing */
- break;
- }
+ if (m_new_Q ^ m_cur_Q)
+ process<KEEP_STATS>((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<devices::nld_base_a_to_d_proxy> 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 <typename O>
//! 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 <typename T, std::size_t N>
- struct state_array
+ struct state_array : public std::array<T, N>
{
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<T, N> m_value;
};
// -----------------------------------------------------------------------------
@@ -401,22 +393,22 @@ namespace netlist
template <typename C, typename T>
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<const C *, T> &store()
+ static std::unordered_map<const C *, T> &store() noexcept
{
static std::unordered_map<const C *, T> 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<core_terminal_t *>;
-
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<netlist_sig_t> 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<typename C>
- 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 &param) { set(m_param, param); }
+ void setTo(const T &param) 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 &param) { set(m_param, static_cast<int>(param)); }
+ void setTo(const T &param) noexcept { set(m_param, static_cast<int>(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<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>,
- public timed_queue<pqentry_t<net_t *, netlist_time>, false, true>,
+ public timed_queue<pqentry_t<net_t *, netlist_time>, false>,
public detail::netlist_ref,
public plib::state_manager_t::callback_t
{
public:
- using base_queue = timed_queue<pqentry_t<net_t *, netlist_time>, false, true>;
+ using base_queue = timed_queue<pqentry_t<net_t *, netlist_time>, false>;
using entry_t = pqentry_t<net_t *, netlist_time>;
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<false>(detail::queue_t::entry_t(m_time, nullptr));
+ else
+ m_queue.retime<true>(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<false>(std::move(e)); // NOLINT(performance-move-const-arg)
else
- m_queue.push(std::move(e)); // NOLINT(performance-move-const-arg)
+ m_queue.push<true>(std::move(e)); // NOLINT(performance-move-const-arg)
}
template <class R>
void qremove(const R &elem) noexcept
{
if (!USE_QUEUE_STATS || !m_use_stats)
- m_queue.remove_nostats(elem);
+ m_queue.remove<false>(elem);
else
- m_queue.remove(elem);
+ m_queue.remove<true>(elem);
}
/* Control functions */
@@ -1905,9 +1900,9 @@ namespace netlist
template <typename O>
state_array<T,N>::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<std::array<T, N> *>(this), owner.name(), name);
for (std::size_t i=0; i<N; i++)
- m_value[i] = value;
+ (*this)[i] = value;
}
} // namespace netlist
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index f2005602443..71a0e6c028c 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -50,7 +50,7 @@
* This approach is stricter and should identify bugs in
* the netlist core faster.
* By default it is disabled since it is not as fast as
- * the default approach. It is up to 5% slower.
+ * the default approach. It is up to 10% slower.
*
*/
#ifndef USE_COPY_INSTEAD_OF_REFERENCE
diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h
index c2464d0ef69..12cf72769a9 100644
--- a/src/lib/netlist/nl_errstr.h
+++ b/src/lib/netlist/nl_errstr.h
@@ -125,9 +125,6 @@ namespace netlist
// nld_solver.cpp
- //PERRMSGV(MF_UNKNOWN_SOLVER_TYPE, 1, "Unknown solver type: {1}")
- PERRMSGV(MF_NETGROUP_SIZE_EXCEEDED_1, 1, "Encountered netgroup with > {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 <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
+ template <class T, bool TS>
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<bool KEEPSTAT>
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 <class R>
+ template <bool KEEPSTAT, class R>
void remove(const R &elem) noexcept
{
- m_prof_remove.inc();
- remove_nostats(elem);
- }
-
- template <class R>
- 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 <bool KEEPSTAT, class R>
+ 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<KEEPSTAT> m_prof_sortmove;
- nperfcount_t<KEEPSTAT> m_prof_call;
- nperfcount_t<KEEPSTAT> m_prof_remove;
- nperfcount_t<KEEPSTAT> m_prof_retime;
+ nperfcount_t<true> m_prof_sortmove;
+ nperfcount_t<true> m_prof_call;
+ nperfcount_t<true> m_prof_remove;
+ nperfcount_t<true> m_prof_retime;
};
- template <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
+ template <class T, bool TS>
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 <bool KEEPSTAT>
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 <class R>
+ template <bool KEEPSTAT, class R>
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 <bool KEEPSTAT>
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<KEEPSTAT> m_prof_sortmove;
- nperfcount_t<KEEPSTAT> m_prof_call;
+ nperfcount_t<true> m_prof_sortmove;
+ nperfcount_t<true> m_prof_call;
+ nperfcount_t<true> m_prof_remove;
+ nperfcount_t<true> m_prof_retime;
};
+ template <class T, bool TS>
+ using timed_queue = timed_queue_linear<T, TS>;
+
/*
* 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 <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
- using timed_queue = timed_queue_linear<T, TS, KEEPSTAT, QueueOp>;
+ //template <class T, bool TS>
+ //using timed_queue = timed_queue_heap<T, TS>;
} // 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<float_type, RESTART + 1> m_c; /* mr + 1 */
plib::parray<float_type, RESTART + 1> m_g; /* mr + 1 */
- plib::parray<plib::parray<float_type, RESTART>, RESTART + 1> m_ht; /* (mr + 1), mr */
+ plib::parray2D<float_type, RESTART + 1, RESTART> m_ht; /* (mr + 1), mr */
plib::parray<float_type, RESTART + 1> m_s; /* mr + 1 */
plib::parray<float_type, RESTART + 1> m_y; /* mr + 1 */
- //plib::parray<float_type, SIZE> m_v[RESTART + 1]; /* mr + 1, n */
- plib::parray<plib::parray<float_type, storage_N>, RESTART + 1> m_v; /* mr + 1, n */
+ //plib::parray<plib::parray<float_type, storage_N>, RESTART + 1> m_v; /* mr + 1, n */
+ plib::parray2D<float_type, RESTART + 1, SIZE> 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<n+1; i++)
+ {
row_idx[i] = 0;
+ }
}
~pmatrix_cr_t() = default;
@@ -495,19 +497,18 @@ namespace plib
{
index_type p(0);
/* build ilu_rows */
- for (index_type i=1; i < fill.size(); i++)
+ for (decltype(fill.size()) i=1; i < fill.size(); i++)
{
bool found(false);
- for (index_type k = 0; k < i; k++)
+ for (decltype(fill.size()) k = 0; k < i; k++)
{
// if (fill[i][k] < base::FILL_INFINITY)
if (fill[i][k] <= ilup)
{
// assume A[k][k]!=0
- for (index_type j=k+1; j < fill.size(); j++)
+ for (decltype(fill.size()) j=k+1; j < fill.size(); j++)
{
auto f = std::min(fill[i][j], 1 + fill[i][k] + fill[k][j]);
- //if (f < base::FILL_INFINITY)
if (f <= ilup)
{
#if 0
@@ -522,7 +523,7 @@ namespace plib
}
}
if (found)
- ilu_rows[p++] = i;
+ ilu_rows[p++] = static_cast<index_type>(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 <typename FT>
struct sizeabs<FT, 0>
{
- static constexpr const std::size_t ABS = 0;
- using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>;
+ static constexpr std::size_t ABS() { return 0; }
+ //using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>;
+ using container = typename std::vector<FT>;
};
/**
@@ -63,27 +64,35 @@ namespace plib {
using value_type = typename base_type::value_type;
template <int X = SIZE >
- parray(size_type size, typename std::enable_if<X==0, int>::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 <int X = SIZE >
- 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 <int X = SIZE >
- parray(size_type size, typename std::enable_if<X!=0, int>::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 <typename FT, int SIZE1, int SIZE2>
+ struct parray2D : public parray<parray<FT, SIZE2>, SIZE1>
+ {
+ public:
+
+ using size_type = std::size_t;
+
+ parray2D(size_type size1, size_type size2)
+ : parray<parray<FT, SIZE2>, SIZE1>(size1)
+ {
+ if (SIZE2 <= 0)
+ {
+ for (size_type i=0; i < this->size(); i++)
+ (*this)[i] = parray<FT, SIZE2>(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<function_ptr *>(&m_func) = t;
}
template<typename O>
- 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<function_ptr *>(&m_func);
return (obj->*t)(std::forward<Targs>(args)...);
}
- bool is_set() {
+ bool is_set() const {
#if defined(_MSC_VER) || (defined (__INTEL_COMPILER) && defined (_M_X64))
int *p = reinterpret_cast<int *>(&m_func);
int *e = p + sizeof(generic_function) / sizeof(int);
@@ -225,12 +225,12 @@ namespace plib {
#endif
}
template<typename O>
- 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<function_ptr>(m_func))(obj, std::forward<Targs>(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 <class C>
- using MemberFunctionType = R (C::*)(Targs...);
+ using MemberFunctionType = R (C::*)(Targs...); // noexcept(true) --> c++-17
pmfp() : pmfp_base<R, Targs...>(), m_obj(nullptr) {}
@@ -263,7 +263,7 @@ namespace plib {
m_obj = reinterpret_cast<generic_class *>(object);
}
- inline R operator()(Targs ... args)
+ inline R operator()(Targs ... args) const noexcept(true)
{
return this->call(m_obj, std::forward<Targs>(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<double, 0>(net_count, sname);
}
break;
}