summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--3rdparty/bgfx/src/renderer_gl.cpp5
-rw-r--r--3rdparty/bgfx/src/renderer_vk.cpp4
-rw-r--r--scripts/src/netlist.lua1
-rw-r--r--src/lib/netlist/build/makefile7
-rw-r--r--src/lib/netlist/nl_base.cpp1610
-rw-r--r--src/lib/netlist/nl_base.h209
-rw-r--r--src/lib/netlist/nl_errstr.h4
-rw-r--r--src/lib/netlist/nl_lists.h335
-rw-r--r--src/lib/netlist/nltypes.h11
-rw-r--r--src/lib/netlist/plib/palloc.h31
-rw-r--r--src/lib/netlist/plib/parray.h12
-rw-r--r--src/lib/netlist/plib/pchrono.h424
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp2
-rw-r--r--src/lib/netlist/plib/plists.h635
-rw-r--r--src/lib/netlist/plib/pmempool.h8
-rw-r--r--src/lib/netlist/plib/pparser.cpp30
-rw-r--r--src/lib/netlist/plib/pparser.h19
-rw-r--r--src/lib/netlist/plib/ppmf.h14
-rw-r--r--src/lib/netlist/plib/pstring.cpp2
-rw-r--r--src/lib/netlist/plib/ptypes.h18
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp1
21 files changed, 1644 insertions, 1738 deletions
diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp
index 3fe8afcba0f..c990e635350 100644
--- a/3rdparty/bgfx/src/renderer_gl.cpp
+++ b/3rdparty/bgfx/src/renderer_gl.cpp
@@ -5579,7 +5579,10 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
version = 0 == bx::strCmp(code, "#version 430", 12) ? 430 : version;
- bx::write(&writer, &err, "#version %d\n", version);
+ if (version < 130)
+ bx::write(&writer, &err, "#version %d\n", 130);
+ else
+ bx::write(&writer, &err, "#version %d\n", version);
if (430 > version && usesTextureLod)
{
diff --git a/3rdparty/bgfx/src/renderer_vk.cpp b/3rdparty/bgfx/src/renderer_vk.cpp
index 579b6c146b8..a4ec5f31435 100644
--- a/3rdparty/bgfx/src/renderer_vk.cpp
+++ b/3rdparty/bgfx/src/renderer_vk.cpp
@@ -3935,8 +3935,8 @@ VK_IMPORT_DEVICE
{
attachments[mrt].colorAttachment = mrt;
attachments[mrt].aspectMask = 0;
- attachments[mrt].aspectMask |= (_clear.m_flags & BGFX_CLEAR_DEPTH ) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0;
- attachments[mrt].aspectMask |= (_clear.m_flags & BGFX_CLEAR_STENCIL) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0;
+ //attachments[mrt].aspectMask |= (_clear.m_flags & BGFX_CLEAR_DEPTH ) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0;
+ //attachments[mrt].aspectMask |= (_clear.m_flags & BGFX_CLEAR_STENCIL) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0;
attachments[mrt].clearValue.depthStencil.stencil = _clear.m_stencil;
attachments[mrt].clearValue.depthStencil.depth = _clear.m_depth;
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua
index 930e8712e4f..6d4c8c909f9 100644
--- a/scripts/src/netlist.lua
+++ b/scripts/src/netlist.lua
@@ -43,7 +43,6 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/nl_dice_compat.h",
MAME_DIR .. "src/lib/netlist/nl_factory.cpp",
MAME_DIR .. "src/lib/netlist/nl_factory.h",
- MAME_DIR .. "src/lib/netlist/nl_lists.h",
MAME_DIR .. "src/lib/netlist/nl_parser.cpp",
MAME_DIR .. "src/lib/netlist/nl_parser.h",
MAME_DIR .. "src/lib/netlist/nl_setup.cpp",
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index 6f75a1d9612..189a486aff6 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -23,10 +23,9 @@ TIDY_FLAGSX += -cppcoreguidelines-avoid-magic-numbers,
TIDY_FLAGSX += -cppcoreguidelines-macro-usage,
TIDY_FLAGSX += -cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,
TIDY_FLAGSX += -bugprone-macro-parentheses,-misc-macro-parentheses,
-TIDY_FLAGSX += -modernize-use-trailing-return-type
-TIDY_FLAGSX += -bugprone-too-small-loop-variable
+TIDY_FLAGSX += -bugprone-too-small-loop-variable,
+TIDY_FLAGSX += -modernize-use-trailing-return-type,
TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-array-to-pointer-decay
-TIDY_FLAGSX += -modernize-use-trailing-return-type
space :=
space +=
@@ -60,7 +59,7 @@ LD = @g++
MD = @mkdir
RM = @rm
DOXYGEN = @doxygen
-CLANG_TIDY = clang-tidy-10
+CLANG_TIDY = clang-tidy-9
TARGETS = nltool nlwav
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 034422792cd..39cdd685608 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -26,1026 +26,904 @@
namespace netlist
{
-// ----------------------------------------------------------------------------------------
-// logic_family_ttl_t
-// ----------------------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------------------
+ // logic_family_ttl_t
+ // ----------------------------------------------------------------------------------------
-// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default)
-logic_family_desc_t::logic_family_desc_t()
-{
-}
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default)
+ logic_family_desc_t::logic_family_desc_t()
+ {
+ }
-class logic_family_ttl_t : public logic_family_desc_t
-{
-public:
- logic_family_ttl_t() : logic_family_desc_t()
- {
- m_fixed_V = 5.0;
- m_low_thresh_PCNT = 0.8 / 5.0;
- m_high_thresh_PCNT = 2.0 / 5.0;
- // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
- m_low_VO = 0.1;
- m_high_VO = 1.0; // 4.0
- m_R_low = 1.0;
- m_R_high = 130.0;
- }
- unique_pool_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
- 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 override;
-};
-
-unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
-{
- return pool().make_unique<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
-}
-unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
-{
- return pool().make_unique<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
-}
+ class logic_family_ttl_t : public logic_family_desc_t
+ {
+ public:
+ logic_family_ttl_t() : logic_family_desc_t()
+ {
+ m_fixed_V = 5.0;
+ m_low_thresh_PCNT = 0.8 / 5.0;
+ m_high_thresh_PCNT = 2.0 / 5.0;
+ // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
+ m_low_VO = 0.1;
+ m_high_VO = 1.0; // 4.0
+ m_R_low = 1.0;
+ m_R_high = 130.0;
+ }
+ unique_pool_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
+ 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 override;
+ };
-class logic_family_cd4xxx_t : public logic_family_desc_t
-{
-public:
- logic_family_cd4xxx_t() : logic_family_desc_t()
- {
- m_fixed_V = 0.0;
- m_low_thresh_PCNT = 1.5 / 5.0;
- m_high_thresh_PCNT = 3.5 / 5.0;
- // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
- m_low_VO = 0.05;
- m_high_VO = 0.05; // 4.95
- m_R_low = 10.0;
- m_R_high = 10.0;
- }
- unique_pool_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
- 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 override;
-};
-
-unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
-{
- return pool().make_unique<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
-}
+ unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
+ {
+ return pool().make_unique<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ }
+ unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
+ {
+ return pool().make_unique<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
-unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
-{
- return pool().make_unique<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
-}
+ class logic_family_cd4xxx_t : public logic_family_desc_t
+ {
+ public:
+ logic_family_cd4xxx_t() : logic_family_desc_t()
+ {
+ m_fixed_V = 0.0;
+ m_low_thresh_PCNT = 1.5 / 5.0;
+ m_high_thresh_PCNT = 3.5 / 5.0;
+ // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
+ m_low_VO = 0.05;
+ m_high_VO = 0.05; // 4.95
+ m_R_low = 10.0;
+ m_R_high = 10.0;
+ }
+ unique_pool_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
+ 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 override;
+ };
-const logic_family_desc_t *family_TTL()
-{
- static logic_family_ttl_t obj;
- return &obj;
-}
-const logic_family_desc_t *family_CD4XXX()
-{
- static logic_family_cd4xxx_t obj;
- return &obj;
-}
+ unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
+ {
+ return pool().make_unique<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ }
+ unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
+ {
+ return pool().make_unique<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
-// ----------------------------------------------------------------------------------------
-// queue_t
-// ----------------------------------------------------------------------------------------
+ const logic_family_desc_t *family_TTL()
+ {
+ static logic_family_ttl_t obj;
+ return &obj;
+ }
+ const logic_family_desc_t *family_CD4XXX()
+ {
+ static logic_family_cd4xxx_t obj;
+ return &obj;
+ }
-detail::queue_t::queue_t(netlist_state_t &nl)
- : timed_queue<pqentry_t<net_t *, netlist_time>, false>(512)
- , netlist_ref(nl)
- , m_qsize(0)
- , m_times(512)
- , m_net_ids(512)
-{
-}
-void detail::queue_t::register_state(plib::state_manager_t &manager, const pstring &module)
-{
- //state().log().debug("register_state\n");
- manager.save_item(this, m_qsize, module + "." + "qsize");
- manager.save_item(this, &m_times[0], module + "." + "times", m_times.size());
- manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size());
-}
+ // ----------------------------------------------------------------------------------------
+ // queue_t
+ // ----------------------------------------------------------------------------------------
-void detail::queue_t::on_pre_save(plib::state_manager_t &manager)
-{
- plib::unused_var(manager);
- m_qsize = this->size();
- for (std::size_t i = 0; i < m_qsize; i++ )
+ detail::queue_t::queue_t(netlist_state_t &nl)
+ : timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>(512)
+ , netlist_ref(nl)
+ , m_qsize(0)
+ , m_times(512)
+ , m_net_ids(512)
{
- m_times[i] = this->listptr()[i].m_exec_time.as_raw();
- m_net_ids[i] = state().find_net_id(this->listptr()[i].m_object);
}
-}
-
-void detail::queue_t::on_post_load(plib::state_manager_t &manager)
-{
- plib::unused_var(manager);
- this->clear();
- for (std::size_t i = 0; i < m_qsize; i++ )
+ void detail::queue_t::register_state(plib::state_manager_t &manager, const pstring &module)
{
- detail::net_t *n = state().nets()[m_net_ids[i]].get();
- this->push<false>(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n));
+ //state().log().debug("register_state\n");
+ manager.save_item(this, m_qsize, module + "." + "qsize");
+ manager.save_item(this, &m_times[0], module + "." + "times", m_times.size());
+ manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size());
}
-}
-// ----------------------------------------------------------------------------------------
-// netlist_ref_t
-// ----------------------------------------------------------------------------------------
+ void detail::queue_t::on_pre_save(plib::state_manager_t &manager)
+ {
+ plib::unused_var(manager);
+ m_qsize = this->size();
+ for (std::size_t i = 0; i < m_qsize; i++ )
+ {
+ m_times[i] = this->listptr()[i].m_exec_time.as_raw();
+ m_net_ids[i] = state().find_net_id(this->listptr()[i].m_object);
+ }
+ }
-detail::netlist_ref::netlist_ref(netlist_state_t &nl)
-: m_netlist(nl.exec()) { }
-// ----------------------------------------------------------------------------------------
-// device_object_t
-// ----------------------------------------------------------------------------------------
+ void detail::queue_t::on_post_load(plib::state_manager_t &manager)
+ {
+ plib::unused_var(manager);
+ this->clear();
+ for (std::size_t i = 0; i < m_qsize; i++ )
+ {
+ detail::net_t *n = state().nets()[m_net_ids[i]].get();
+ this->push<false>(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n));
+ }
+ }
-detail::device_object_t::device_object_t(core_device_t &dev, const pstring &aname)
-: object_t(aname)
-, m_device(dev)
-{
-}
+ // ----------------------------------------------------------------------------------------
+ // netlist_ref_t
+ // ----------------------------------------------------------------------------------------
-detail::terminal_type detail::core_terminal_t::type() const
-{
- if (dynamic_cast<const terminal_t *>(this) != nullptr)
- return terminal_type::TERMINAL;
- else if (dynamic_cast<const logic_input_t *>(this) != nullptr
- || dynamic_cast<const analog_input_t *>(this) != nullptr)
- return terminal_type::INPUT;
- else if (dynamic_cast<const logic_output_t *>(this) != nullptr
- || dynamic_cast<const analog_output_t *>(this) != nullptr)
- return terminal_type::OUTPUT;
- else
- {
- state().log().fatal(MF_UNKNOWN_TYPE_FOR_OBJECT(name()));
- return terminal_type::TERMINAL; // please compiler
- }
-}
-
-// ----------------------------------------------------------------------------------------
-// netlist_t
-// ----------------------------------------------------------------------------------------
-
-netlist_t::netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks)
- : m_state(plib::make_unique<netlist_state_t>(aname, *this, std::move(callbacks)))
- , m_solver(nullptr)
- , m_time(netlist_time::zero())
- , m_mainclock(nullptr)
- , m_queue(*m_state)
- , m_use_stats(false)
-{
- devices::initialize_factory(nlstate().setup().factory());
- NETLIST_NAME(base)(nlstate().setup());
- run_state_manager().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
- run_state_manager().save_item(this, m_time, "m_time");
-}
-
-// ----------------------------------------------------------------------------------------
-// netlist_t
-// ----------------------------------------------------------------------------------------
-
-netlist_state_t::netlist_state_t(const pstring &aname,
- netlist_t & anetlist,
- plib::unique_ptr<callbacks_t> &&callbacks)
-: m_name(aname)
-, m_netlist(anetlist)
-, m_state()
-, m_callbacks(std::move(callbacks)) // Order is important here
-, m_log(*m_callbacks)
-, m_setup(plib::make_unique<setup_t>(*this))
-{
- pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
- m_lib = plib::make_unique<plib::dynlib>(libpath);
-}
+ detail::netlist_ref::netlist_ref(netlist_state_t &nl)
+ : m_netlist(nl.exec()) { }
+ // ----------------------------------------------------------------------------------------
+ // device_object_t
+ // ----------------------------------------------------------------------------------------
-void netlist_t::stop()
-{
- log().debug("Printing statistics ...\n");
- print_stats();
- log().debug("Stopping solver device ...\n");
- if (m_solver != nullptr)
- m_solver->stop();
-}
-
-detail::net_t *netlist_state_t::find_net(const pstring &name) const
-{
- for (auto & net : m_nets)
- if (net->name() == name)
- return net.get();
+ detail::device_object_t::device_object_t(core_device_t &dev, const pstring &aname)
+ : object_t(aname)
+ , m_device(dev)
+ {
+ }
- return nullptr;
-}
+ detail::terminal_type detail::core_terminal_t::type() const
+ {
+ if (dynamic_cast<const terminal_t *>(this) != nullptr)
+ return terminal_type::TERMINAL;
+ else if (dynamic_cast<const logic_input_t *>(this) != nullptr
+ || dynamic_cast<const analog_input_t *>(this) != nullptr)
+ return terminal_type::INPUT;
+ else if (dynamic_cast<const logic_output_t *>(this) != nullptr
+ || dynamic_cast<const analog_output_t *>(this) != nullptr)
+ return terminal_type::OUTPUT;
+ else
+ {
+ state().log().fatal(MF_UNKNOWN_TYPE_FOR_OBJECT(name()));
+ return terminal_type::TERMINAL; // please compiler
+ }
+ }
-std::size_t netlist_state_t::find_net_id(const detail::net_t *net) const
-{
- for (std::size_t i = 0; i < m_nets.size(); i++)
- if (m_nets[i].get() == net)
- return i;
- return std::numeric_limits<std::size_t>::max();
-}
+ // ----------------------------------------------------------------------------------------
+ // netlist_t
+ // ----------------------------------------------------------------------------------------
+
+ netlist_t::netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks)
+ : m_state(plib::make_unique<netlist_state_t>(aname, *this, std::move(callbacks)))
+ , m_solver(nullptr)
+ , m_time(netlist_time::zero())
+ , m_mainclock(nullptr)
+ , m_queue(*m_state)
+ , m_use_stats(false)
+ {
+ devices::initialize_factory(nlstate().setup().factory());
+ NETLIST_NAME(base)(nlstate().setup());
+ run_state_manager().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
+ run_state_manager().save_item(this, m_time, "m_time");
+ }
+ // ----------------------------------------------------------------------------------------
+ // netlist_t
+ // ----------------------------------------------------------------------------------------
+
+ netlist_state_t::netlist_state_t(const pstring &aname,
+ netlist_t & anetlist,
+ plib::unique_ptr<callbacks_t> &&callbacks)
+ : m_name(aname)
+ , m_netlist(anetlist)
+ , m_state()
+ , m_callbacks(std::move(callbacks)) // Order is important here
+ , m_log(*m_callbacks)
+ , m_setup(plib::make_unique<setup_t>(*this))
+ {
+ pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
+ m_lib = plib::make_unique<plib::dynlib>(libpath);
+ }
-void netlist_state_t::rebuild_lists()
-{
- for (auto & net : m_nets)
- net->rebuild_list();
-}
+ void netlist_t::stop()
+ {
+ log().debug("Printing statistics ...\n");
+ print_stats();
+ log().debug("Stopping solver device ...\n");
+ if (m_solver != nullptr)
+ m_solver->stop();
+ }
+ detail::net_t *netlist_state_t::find_net(const pstring &name) const
+ {
+ for (auto & net : m_nets)
+ if (net->name() == name)
+ return net.get();
-void netlist_state_t::compile_defines(std::vector<std::pair<pstring, pstring>> &defs)
-{
-//#define ENTRY(x) { #x, PSTRINGIFY(x) }
-#define ENTRY(x) std::pair<pstring, pstring>(#x, PSTRINGIFY(x))
- defs.emplace_back(ENTRY(PHAS_RDTSCP));
- defs.emplace_back(ENTRY(PUSE_ACCURATE_STATS));
- defs.emplace_back(ENTRY(PHAS_INT128));
- defs.emplace_back(ENTRY(USE_ALIGNED_OPTIMIZATIONS));
- defs.emplace_back(ENTRY(NVCCBUILD));
- defs.emplace_back(ENTRY(USE_MEMPOOL));
- defs.emplace_back(ENTRY(USE_QUEUE_STATS));
- defs.emplace_back(ENTRY(USE_COPY_INSTEAD_OF_REFERENCE));
- defs.emplace_back(ENTRY(USE_TRUTHTABLE_7448));
- defs.emplace_back(ENTRY(NL_DEBUG));
- defs.emplace_back(ENTRY(HAS_OPENMP));
- defs.emplace_back(ENTRY(USE_OPENMP));
-
- defs.emplace_back(ENTRY(PPMF_TYPE));
- defs.emplace_back(ENTRY(PHAS_PMF_INTERNAL));
-
-#undef ENTRY
-}
-
-void netlist_t::reset()
-{
- log().debug("Searching for mainclock\n");
- m_mainclock = m_state->get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
+ return nullptr;
+ }
- log().debug("Searching for solver\n");
- m_solver = m_state->get_single_device<devices::NETLIB_NAME(solver)>("solver");
+ std::size_t netlist_state_t::find_net_id(const detail::net_t *net) const
+ {
+ for (std::size_t i = 0; i < m_nets.size(); i++)
+ if (m_nets[i].get() == net)
+ return i;
+ return std::numeric_limits<std::size_t>::max();
+ }
- m_time = netlist_time::zero();
- m_queue.clear();
- if (m_mainclock != nullptr)
- m_mainclock->m_Q.net().set_next_scheduled_time(netlist_time::zero());
- //if (m_solver != nullptr)
- // m_solver->reset();
- m_state->reset();
-}
-void netlist_state_t::reset()
-{
- //FIXME: never used ???
- std::unordered_map<core_device_t *, bool> m;
-
- // Reset all nets once !
- log().verbose("Call reset on all nets:");
- for (auto & n : nets())
- n->reset();
-
- // Reset all devices once !
- log().verbose("Call reset on all devices:");
- for (auto & dev : m_devices)
- dev.second->reset();
-
- // Make sure everything depending on parameters is set
- // Currently analog input and logic input also
- // push their outputs to queue.
-
- log().verbose("Call update_param on all devices:");
- for (auto & dev : m_devices)
- dev.second->update_param();
-
- // Step all devices once !
- /*
- * INFO: The order here affects power up of e.g. breakout. However, such
- * variations are explicitly stated in the breakout manual.
- */
+ void netlist_state_t::rebuild_lists()
+ {
+ for (auto & net : m_nets)
+ net->rebuild_list();
+ }
- auto *netlist_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
- switch (netlist_params->m_startup_strategy())
+ void netlist_state_t::compile_defines(std::vector<std::pair<pstring, pstring>> &defs)
{
- case 0:
- {
- std::vector<core_device_t *> d;
- std::vector<nldelegate *> t;
- log().verbose("Using default startup strategy");
- for (auto &n : m_nets)
- for (auto & term : n->core_terms())
- if (term->m_delegate.has_object())
- {
- if (!plib::container::contains(t, &term->m_delegate))
- {
- t.push_back(&term->m_delegate);
- term->m_delegate();
- }
- auto *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
- if (!plib::container::contains(d, dev))
- d.push_back(dev);
- }
- log().verbose("Devices not yet updated:");
- for (auto &dev : m_devices)
- if (!plib::container::contains(d, dev.second.get()))
- {
- log().verbose("\t ...{1}", dev.second->name());
- dev.second->update();
- }
- }
- break;
- case 1: // brute force backward
- {
- log().verbose("Using brute force backward startup strategy");
+ //#define ENTRY(x) { #x, PSTRINGIFY(x) }
+ #define ENTRY(x) std::pair<pstring, pstring>(#x, PSTRINGIFY(x))
+ defs.emplace_back(ENTRY(PHAS_RDTSCP));
+ defs.emplace_back(ENTRY(PUSE_ACCURATE_STATS));
+ defs.emplace_back(ENTRY(PHAS_INT128));
+ defs.emplace_back(ENTRY(USE_ALIGNED_OPTIMIZATIONS));
+ defs.emplace_back(ENTRY(NVCCBUILD));
+ defs.emplace_back(ENTRY(USE_MEMPOOL));
+ defs.emplace_back(ENTRY(USE_QUEUE_STATS));
+ defs.emplace_back(ENTRY(USE_COPY_INSTEAD_OF_REFERENCE));
+ defs.emplace_back(ENTRY(USE_TRUTHTABLE_7448));
+ defs.emplace_back(ENTRY(NL_DEBUG));
+ defs.emplace_back(ENTRY(HAS_OPENMP));
+ defs.emplace_back(ENTRY(USE_OPENMP));
+
+ defs.emplace_back(ENTRY(PPMF_TYPE));
+ defs.emplace_back(ENTRY(PHAS_PMF_INTERNAL));
+
+ #undef ENTRY
+ }
- for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
- n->update_inputs();
+ void netlist_t::reset()
+ {
+ log().debug("Searching for mainclock\n");
+ m_mainclock = m_state->get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
- std::size_t i = m_devices.size();
- while (i>0)
- m_devices[--i].second->update();
+ log().debug("Searching for solver\n");
+ m_solver = m_state->get_single_device<devices::NETLIB_NAME(solver)>("solver");
- for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
- n->update_inputs();
+ m_time = netlist_time::zero();
+ m_queue.clear();
+ if (m_mainclock != nullptr)
+ m_mainclock->m_Q.net().set_next_scheduled_time(netlist_time::zero());
+ //if (m_solver != nullptr)
+ // m_solver->reset();
- }
- break;
- case 2: // brute force forward
- {
- log().verbose("Using brute force forward startup strategy");
- for (auto &d : m_devices)
- d.second->update();
- }
- break;
+ m_state->reset();
}
-#if 1
- /* the above may screw up m_active and the list */
- rebuild_lists();
-#endif
-}
-
-void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
-{
- if (!m_use_stats)
- process_queue_stats<false>(delta);
- else
+ void netlist_state_t::reset()
{
- auto sm_guard(m_stat_mainloop.guard());
- process_queue_stats<true>(delta);
- }
-}
+ //FIXME: never used ???
+ std::unordered_map<core_device_t *, bool> m;
-template <bool KEEP_STATS>
-void netlist_t::process_queue_stats(const netlist_time delta) NL_NOEXCEPT
-{
- netlist_time stop(m_time + delta);
+ // Reset all nets once !
+ log().verbose("Call reset on all nets:");
+ for (auto & n : nets())
+ n->reset();
- qpush(detail::queue_t::entry_t(stop, nullptr));
+ // Reset all devices once !
+ log().verbose("Call reset on all devices:");
+ for (auto & dev : m_devices)
+ dev.second->reset();
- if (m_mainclock == nullptr)
- {
- detail::queue_t::entry_t e(m_queue.pop());
- m_time = e.m_exec_time;
- while (e.m_object != nullptr)
- {
- e.m_object->template update_devs<KEEP_STATS>();
- if (KEEP_STATS)
- m_perf_out_processed.inc();
- e = m_queue.pop();
- m_time = e.m_exec_time;
- }
- }
- else
- {
- logic_net_t &mc_net(m_mainclock->m_Q.net());
- const netlist_time inc(m_mainclock->m_inc);
- netlist_time mc_time(mc_net.next_scheduled_time());
+ // Make sure everything depending on parameters is set
+ // Currently analog input and logic input also
+ // push their outputs to queue.
+
+ log().verbose("Call update_param on all devices:");
+ for (auto & dev : m_devices)
+ dev.second->update_param();
+
+ // Step all devices once !
+ /*
+ * INFO: The order here affects power up of e.g. breakout. However, such
+ * variations are explicitly stated in the breakout manual.
+ */
- do
+ auto *netlist_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+
+ switch (netlist_params->m_startup_strategy())
{
- while (m_queue.top().m_exec_time > mc_time)
+ case 0:
{
- m_time = mc_time;
- mc_net.toggle_new_Q();
- mc_net.update_devs<KEEP_STATS>();
- mc_time += inc;
+ std::vector<core_device_t *> d;
+ std::vector<nldelegate *> t;
+ log().verbose("Using default startup strategy");
+ for (auto &n : m_nets)
+ for (auto & term : n->core_terms())
+ if (term->m_delegate.has_object())
+ {
+ if (!plib::container::contains(t, &term->m_delegate))
+ {
+ t.push_back(&term->m_delegate);
+ term->m_delegate();
+ }
+ auto *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
+ if (!plib::container::contains(d, dev))
+ d.push_back(dev);
+ }
+ log().verbose("Devices not yet updated:");
+ for (auto &dev : m_devices)
+ if (!plib::container::contains(d, dev.second.get()))
+ {
+ log().verbose("\t ...{1}", dev.second->name());
+ dev.second->update();
+ }
}
+ break;
+ case 1: // brute force backward
+ {
+ log().verbose("Using brute force backward startup strategy");
- detail::queue_t::entry_t e(m_queue.pop());
- m_time = e.m_exec_time;
- if (e.m_object != nullptr)
+ for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
+ n->update_inputs();
+
+ std::size_t i = m_devices.size();
+ while (i>0)
+ m_devices[--i].second->update();
+
+ for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
+ n->update_inputs();
+
+ }
+ break;
+ case 2: // brute force forward
{
- e.m_object->template update_devs<KEEP_STATS>();
- if (KEEP_STATS)
- m_perf_out_processed.inc();
+ log().verbose("Using brute force forward startup strategy");
+ for (auto &d : m_devices)
+ d.second->update();
}
- else
- break;
- } while (true); //while (e.m_object != nullptr);
- mc_net.set_next_scheduled_time(mc_time);
+ break;
+ }
+
+ #if 1
+ /* the above may screw up m_active and the list */
+ rebuild_lists();
+ #endif
}
-}
-void netlist_t::print_stats() const
-{
- if (m_use_stats)
+
+ void netlist_t::print_stats() const NL_NOEXCEPT
{
- std::vector<size_t> index;
- for (size_t i=0; i < m_state->m_devices.size(); i++)
- index.push_back(i);
+ if (m_use_stats)
+ {
+ std::vector<size_t> index;
+ for (size_t i=0; i < m_state->m_devices.size(); i++)
+ index.push_back(i);
- std::sort(index.begin(), index.end(),
- [&](size_t i1, size_t i2) { return m_state->m_devices[i1].second->m_stats->m_stat_total_time.total() < m_state->m_devices[i2].second->m_stats->m_stat_total_time.total(); });
+ std::sort(index.begin(), index.end(),
+ [&](size_t i1, size_t i2) { return m_state->m_devices[i1].second->m_stats->m_stat_total_time.total() < m_state->m_devices[i2].second->m_stats->m_stat_total_time.total(); });
- nperftime_t<true>::type total_time(0);
- nperftime_t<true>::ctype total_count(0);
+ plib::pperftime_t<true>::type total_time(0);
+ plib::pperftime_t<true>::ctype total_count(0);
- for (auto & j : index)
- {
- auto entry = m_state->m_devices[j].second.get();
- auto stats = m_state->m_devices[j].second.get()->m_stats.get();
- log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(),
- stats->m_stat_call_count(), stats->m_stat_total_time.count(),
- stats->m_stat_total_time.total(), stats->m_stat_inc_active());
- total_time += stats->m_stat_total_time.total();
- total_count += stats->m_stat_total_time.count();
- }
+ for (auto & j : index)
+ {
+ auto entry = m_state->m_devices[j].second.get();
+ auto stats = m_state->m_devices[j].second.get()->m_stats.get();
+ log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(),
+ stats->m_stat_call_count(), stats->m_stat_total_time.count(),
+ stats->m_stat_total_time.total(), stats->m_stat_inc_active());
+ total_time += stats->m_stat_total_time.total();
+ total_count += stats->m_stat_total_time.count();
+ }
- log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count,
- total_time, total_time / static_cast<decltype(total_time)>(total_count ? total_count : 1));
+ log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count,
+ total_time, total_time / static_cast<decltype(total_time)>(total_count ? total_count : 1));
- log().verbose("Total loop {1:15}", m_stat_mainloop());
- log().verbose("Total time {1:15}", total_time);
+ log().verbose("Total loop {1:15}", m_stat_mainloop());
+ log().verbose("Total time {1:15}", total_time);
- // FIXME: clang complains about unreachable code without
- const auto clang_workaround_unreachable_code = USE_QUEUE_STATS;
- if (clang_workaround_unreachable_code)
- {
- /* Only one serialization should be counted in total time */
- /* But two are contained in m_stat_mainloop */
- nperftime_t<true> overhead;
- nperftime_t<true> test;
+ // FIXME: clang complains about unreachable code without
+ const auto clang_workaround_unreachable_code = USE_QUEUE_STATS;
+ if (clang_workaround_unreachable_code)
{
- auto overhead_guard(overhead.guard());
- for (int j=0; j<100000;j++)
+ /* Only one serialization should be counted in total time */
+ /* But two are contained in m_stat_mainloop */
+ plib::pperftime_t<true> overhead;
+ plib::pperftime_t<true> test;
{
- auto test_guard(test.guard());
+ auto overhead_guard(overhead.guard());
+ for (int j=0; j<100000;j++)
+ {
+ auto test_guard(test.guard());
+ }
}
- }
- nperftime_t<true>::type total_overhead = overhead()
- * static_cast<nperftime_t<true>::type>(total_count)
- / static_cast<nperftime_t<true>::type>(200000);
-
- log().verbose("Queue Pushes {1:15}", m_queue.m_prof_call());
- log().verbose("Queue Moves {1:15}", m_queue.m_prof_sortmove());
- log().verbose("Queue Removes {1:15}", m_queue.m_prof_remove());
- log().verbose("Queue Retimes {1:15}", m_queue.m_prof_retime());
- log().verbose("");
-
- log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation.");
- log().verbose("Total overhead {1:15}", total_overhead);
- nperftime_t<true>::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead))
- / static_cast<nperftime_t<true>::type>(m_queue.m_prof_call());
- log().verbose("Overhead per pop {1:11}", overhead_per_pop );
- log().verbose("");
- }
+ plib::pperftime_t<true>::type total_overhead = overhead()
+ * static_cast<plib::pperftime_t<true>::type>(total_count)
+ / static_cast<plib::pperftime_t<true>::type>(200000);
+
+ log().verbose("Queue Pushes {1:15}", m_queue.m_prof_call());
+ log().verbose("Queue Moves {1:15}", m_queue.m_prof_sortmove());
+ log().verbose("Queue Removes {1:15}", m_queue.m_prof_remove());
+ log().verbose("Queue Retimes {1:15}", m_queue.m_prof_retime());
+ log().verbose("");
+
+ log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation.");
+ log().verbose("Total overhead {1:15}", total_overhead);
+ plib::pperftime_t<true>::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead))
+ / static_cast<plib::pperftime_t<true>::type>(m_queue.m_prof_call());
+ log().verbose("Overhead per pop {1:11}", overhead_per_pop );
+ log().verbose("");
+ }
- auto trigger = total_count * 200 / 1000000; // 200 ppm
- for (auto &entry : m_state->m_devices)
- {
- auto ep = entry.second.get();
- auto stats = ep->m_stats.get();
- // Factor of 3 offers best performace increase
- if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count()
- && stats->m_stat_inc_active() > trigger)
- log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(),
- static_cast<double>(stats->m_stat_inc_active()) / static_cast<double>(stats->m_stat_total_time.count()),
- stats->m_stat_inc_active(), stats->m_stat_total_time.count());
+ auto trigger = total_count * 200 / 1000000; // 200 ppm
+ for (auto &entry : m_state->m_devices)
+ {
+ auto ep = entry.second.get();
+ auto stats = ep->m_stats.get();
+ // Factor of 3 offers best performace increase
+ if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count()
+ && stats->m_stat_inc_active() > trigger)
+ log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(),
+ static_cast<double>(stats->m_stat_inc_active()) / static_cast<double>(stats->m_stat_total_time.count()),
+ stats->m_stat_inc_active(), stats->m_stat_total_time.count());
+ }
}
}
-}
-core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
-{
- core_device_t *ret = nullptr;
- for (auto &d : m_devices)
+ core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
{
- if (cc(d.second.get()))
+ core_device_t *ret = nullptr;
+ for (auto &d : m_devices)
{
- if (ret != nullptr)
- m_log.fatal(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname));
- else
- ret = d.second.get();
+ if (cc(d.second.get()))
+ {
+ if (ret != nullptr)
+ m_log.fatal(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname));
+ else
+ ret = d.second.get();
+ }
}
+ return ret;
}
- return ret;
-}
-
-// ----------------------------------------------------------------------------------------
-// core_device_t
-// ----------------------------------------------------------------------------------------
-core_device_t::core_device_t(netlist_state_t &owner, const pstring &name)
- : object_t(name)
- , logic_family_t()
- , netlist_ref(owner)
- , m_hint_deactivate(false)
- , m_active_outputs(*this, "m_active_outputs", 1)
-{
- if (logic_family() == nullptr)
- set_logic_family(family_TTL());
- if (exec().stats_enabled())
- m_stats = pool().make_unique<stats_t>();
-}
-
-core_device_t::core_device_t(core_device_t &owner, const pstring &name)
- : object_t(owner.name() + "." + name)
- , logic_family_t()
- , netlist_ref(owner.state())
- , m_hint_deactivate(false)
- , m_active_outputs(*this, "m_active_outputs", 1)
-{
- set_logic_family(owner.logic_family());
- if (logic_family() == nullptr)
- set_logic_family(family_TTL());
- state().register_device(this->name(), owned_pool_ptr<core_device_t>(this, false));
- if (exec().stats_enabled())
- m_stats = pool().make_unique<stats_t>();
-}
-
-void core_device_t::set_default_delegate(detail::core_terminal_t &term)
-{
- if (!term.m_delegate.is_set())
- term.m_delegate.set(&core_device_t::update, this);
-}
-
-log_type & core_device_t::log()
-{
- return state().log();
-}
+ // ----------------------------------------------------------------------------------------
+ // core_device_t
+ // ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// device_t
-// ----------------------------------------------------------------------------------------
+ core_device_t::core_device_t(netlist_state_t &owner, const pstring &name)
+ : object_t(name)
+ , logic_family_t()
+ , netlist_ref(owner)
+ , m_hint_deactivate(false)
+ , m_active_outputs(*this, "m_active_outputs", 1)
+ {
+ if (logic_family() == nullptr)
+ set_logic_family(family_TTL());
+ if (exec().stats_enabled())
+ m_stats = pool().make_unique<stats_t>();
+ }
-device_t::device_t(netlist_state_t &owner, const pstring &name)
-: core_device_t(owner, name)
-{
-}
+ core_device_t::core_device_t(core_device_t &owner, const pstring &name)
+ : object_t(owner.name() + "." + name)
+ , logic_family_t()
+ , netlist_ref(owner.state())
+ , m_hint_deactivate(false)
+ , m_active_outputs(*this, "m_active_outputs", 1)
+ {
+ set_logic_family(owner.logic_family());
+ if (logic_family() == nullptr)
+ set_logic_family(family_TTL());
+ state().register_device(this->name(), owned_pool_ptr<core_device_t>(this, false));
+ if (exec().stats_enabled())
+ m_stats = pool().make_unique<stats_t>();
+ }
-device_t::device_t(core_device_t &owner, const pstring &name)
-: core_device_t(owner, name)
-{
-}
+ void core_device_t::set_default_delegate(detail::core_terminal_t &term)
+ {
+ if (!term.m_delegate.is_set())
+ term.m_delegate.set(&core_device_t::update, this);
+ }
-setup_t &device_t::setup()
-{
- return state().setup();
-}
+ log_type & core_device_t::log()
+ {
+ return state().log();
+ }
-const setup_t &device_t::setup() const
-{
- return state().setup();
-}
+ // ----------------------------------------------------------------------------------------
+ // device_t
+ // ----------------------------------------------------------------------------------------
-void device_t::register_subalias(const pstring &name, detail::core_terminal_t &term)
-{
- pstring alias = this->name() + "." + name;
+ device_t::device_t(netlist_state_t &owner, const pstring &name)
+ : core_device_t(owner, name)
+ {
+ }
- // everything already fully qualified
- setup().register_alias_nofqn(alias, term.name());
-}
+ device_t::device_t(core_device_t &owner, const pstring &name)
+ : core_device_t(owner, name)
+ {
+ }
-void device_t::register_subalias(const pstring &name, const pstring &aliased)
-{
- pstring alias = this->name() + "." + name;
- pstring aliased_fqn = this->name() + "." + aliased;
+ setup_t &device_t::setup() noexcept
+ {
+ return state().setup();
+ }
- // everything already fully qualified
- setup().register_alias_nofqn(alias, aliased_fqn);
-}
+ const setup_t &device_t::setup() const noexcept
+ {
+ return state().setup();
+ }
-void device_t::connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
-{
- setup().register_link_fqn(t1.name(), t2.name());
-}
+ void device_t::register_subalias(const pstring &name, detail::core_terminal_t &term)
+ {
+ pstring alias = this->name() + "." + name;
-void device_t::connect(const pstring &t1, const pstring &t2)
-{
- setup().register_link_fqn(name() + "." + t1, name() + "." + t2);
-}
+ // everything already fully qualified
+ setup().register_alias_nofqn(alias, term.name());
+ }
-/* FIXME: this is only used by solver code since matrix solvers are started in
- * post_start.
- */
-void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
-{
- if (!setup().connect(t1, t2))
- log().fatal(MF_ERROR_CONNECTING_1_TO_2(t1.name(), t2.name()));
-}
+ void device_t::register_subalias(const pstring &name, const pstring &aliased)
+ {
+ pstring alias = this->name() + "." + name;
+ pstring aliased_fqn = this->name() + "." + aliased;
+ // everything already fully qualified
+ setup().register_alias_nofqn(alias, aliased_fqn);
+ }
-// -----------------------------------------------------------------------------
-// family_setter_t
-// -----------------------------------------------------------------------------
+ void device_t::connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
+ {
+ setup().register_link_fqn(t1.name(), t2.name());
+ }
-// NOLINTNEXTLINE(modernize-use-equals-default)
-detail::family_setter_t::family_setter_t()
-{
-}
+ void device_t::connect(const pstring &t1, const pstring &t2)
+ {
+ setup().register_link_fqn(name() + "." + t1, name() + "." + t2);
+ }
-detail::family_setter_t::family_setter_t(core_device_t &dev, const pstring &desc)
-{
- dev.set_logic_family(dev.setup().family_from_model(desc));
-}
+ /* FIXME: this is only used by solver code since matrix solvers are started in
+ * post_start.
+ */
+ void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
+ {
+ if (!setup().connect(t1, t2))
+ log().fatal(MF_ERROR_CONNECTING_1_TO_2(t1.name(), t2.name()));
+ }
-detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc)
-{
- dev.set_logic_family(desc);
-}
-// ----------------------------------------------------------------------------------------
-// net_t
-// ----------------------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ // family_setter_t
+ // -----------------------------------------------------------------------------
-detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr)
- : object_t(aname)
- , netlist_ref(nl)
- , m_new_Q(*this, "m_new_Q", 0)
- , m_cur_Q (*this, "m_cur_Q", 0)
- , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED)
- , m_next_scheduled_time(*this, "m_time", netlist_time::zero())
- , m_railterminal(mr)
-{
-}
+ // NOLINTNEXTLINE(modernize-use-equals-default)
+ detail::family_setter_t::family_setter_t()
+ {
+ }
-void detail::net_t::rebuild_list()
-{
- /* rebuild m_list */
+ detail::family_setter_t::family_setter_t(core_device_t &dev, const pstring &desc)
+ {
+ dev.set_logic_family(dev.setup().family_from_model(desc));
+ }
- m_list_active.clear();
- for (auto & term : m_core_terms)
- if (term->terminal_state() != logic_t::STATE_INP_PASSIVE)
- {
- m_list_active.push_back(term);
- term->set_copied_input(m_cur_Q);
- }
-}
+ detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc)
+ {
+ dev.set_logic_family(desc);
+ }
-template <bool KEEP_STATS, typename T>
-void detail::net_t::process(const T mask, netlist_sig_t sig)
-{
- m_cur_Q = sig;
+ // ----------------------------------------------------------------------------------------
+ // net_t
+ // ----------------------------------------------------------------------------------------
+
+ detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr)
+ : object_t(aname)
+ , netlist_ref(nl)
+ , m_new_Q(*this, "m_new_Q", 0)
+ , m_cur_Q (*this, "m_cur_Q", 0)
+ , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED)
+ , m_next_scheduled_time(*this, "m_time", netlist_time::zero())
+ , m_railterminal(mr)
+ {
+ }
- if (KEEP_STATS)
+ void detail::net_t::rebuild_list()
{
- for (auto & p : m_list_active)
- {
- p.set_copied_input(sig);
- auto *stats = p.device().m_stats.get();
- stats->m_stat_call_count.inc();
- if ((p.terminal_state() & mask))
+ /* rebuild m_list */
+
+ m_list_active.clear();
+ for (auto & term : m_core_terms)
+ if (term->terminal_state() != logic_t::STATE_INP_PASSIVE)
{
- auto g(stats->m_stat_total_time.guard());
- p.m_delegate();
+ m_list_active.push_back(term);
+ term->set_copied_input(m_cur_Q);
}
- }
}
- else
+
+
+ void detail::net_t::reset()
{
- for (auto & p : m_list_active)
- {
- p.set_copied_input(sig);
- if ((p.terminal_state() & mask))
- p.m_delegate();
- }
- }
-}
+ m_next_scheduled_time = netlist_time::zero();
+ m_in_queue = queue_status::DELIVERED;
-template <bool KEEP_STATS>
-void detail::net_t::update_devs() NL_NOEXCEPT
-{
-#if 0
- nl_assert(this->isRailNet());
+ m_new_Q = 0;
+ m_cur_Q = 0;
- const unsigned int new_Q(m_new_Q);
+ auto *p = dynamic_cast<analog_net_t *>(this);
- const unsigned int mask((new_Q << core_terminal_t::INP_LH_SHIFT)
- | (m_cur_Q << core_terminal_t::INP_HL_SHIFT));
+ if (p != nullptr)
+ p->m_cur_Analog = 0.0;
- 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, new_Q);
- break;
- default:
- /* do nothing */
- break;
+ /* rebuild m_list and reset terminals to active or analog out state */
+
+ m_list_active.clear();
+ for (core_terminal_t *ct : m_core_terms)
+ {
+ ct->reset();
+ if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE)
+ m_list_active.push_back(ct);
+ ct->set_copied_input(m_cur_Q);
+ }
}
-#else
- nl_assert(this->isRailNet());
- m_in_queue = queue_status::DELIVERED; /* mark as taken ... */
- 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
-}
+ void detail::net_t::add_terminal(detail::core_terminal_t &terminal) NL_NOEXCEPT
+ {
+ for (auto &t : m_core_terms)
+ if (t == &terminal)
+ state().log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(name(), t->name()));
-void detail::net_t::reset()
-{
- m_next_scheduled_time = netlist_time::zero();
- m_in_queue = queue_status::DELIVERED;
+ terminal.set_net(this);
- m_new_Q = 0;
- m_cur_Q = 0;
+ m_core_terms.push_back(&terminal);
+ }
- auto *p = dynamic_cast<analog_net_t *>(this);
+ void detail::net_t::remove_terminal(detail::core_terminal_t &terminal) NL_NOEXCEPT
+ {
+ if (plib::container::contains(m_core_terms, &terminal))
+ {
+ terminal.set_net(nullptr);
+ plib::container::remove(m_core_terms, &terminal);
+ }
+ else
+ state().log().fatal(MF_REMOVE_TERMINAL_1_FROM_NET_2(terminal.name(), this->name()));
+ }
- if (p != nullptr)
- p->m_cur_Analog = 0.0;
+ void detail::net_t::move_connections(detail::net_t &dest_net)
+ {
+ for (auto &ct : m_core_terms)
+ dest_net.add_terminal(*ct);
+ m_core_terms.clear();
+ }
- /* rebuild m_list and reset terminals to active or analog out state */
+ // ----------------------------------------------------------------------------------------
+ // logic_net_t
+ // ----------------------------------------------------------------------------------------
- m_list_active.clear();
- for (core_terminal_t *ct : m_core_terms)
+ logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
+ : net_t(nl, aname, mr)
{
- ct->reset();
- if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE)
- m_list_active.push_back(ct);
- ct->set_copied_input(m_cur_Q);
}
-}
-void detail::net_t::add_terminal(detail::core_terminal_t &terminal) NL_NOEXCEPT
-{
- for (auto &t : m_core_terms)
- if (t == &terminal)
- state().log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(name(), t->name()));
+ // ----------------------------------------------------------------------------------------
+ // analog_net_t
+ // ----------------------------------------------------------------------------------------
- terminal.set_net(this);
+ analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
+ : net_t(nl, aname, mr)
+ , m_cur_Analog(*this, "m_cur_Analog", 0.0)
+ , m_solver(nullptr)
+ {
+ }
- m_core_terms.push_back(&terminal);
-}
+ // ----------------------------------------------------------------------------------------
+ // core_terminal_t
+ // ----------------------------------------------------------------------------------------
+
+ detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname,
+ const state_e state, nldelegate delegate)
+ : device_object_t(dev, dev.name() + "." + aname)
+ , plib::linkedlist_t<core_terminal_t>::element_t()
+ , m_delegate(delegate)
+ #if USE_COPY_INSTEAD_OF_REFERENCE
+ , m_Q(*this, "m_Q", 0)
+ #endif
+ , m_net(nullptr)
+ , m_state(*this, "m_state", state)
+ {
+ }
-void detail::net_t::remove_terminal(detail::core_terminal_t &terminal) NL_NOEXCEPT
-{
- if (plib::container::contains(m_core_terms, &terminal))
+ analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state,
+ nldelegate delegate)
+ : core_terminal_t(dev, aname, state, delegate)
{
- terminal.set_net(nullptr);
- plib::container::remove(m_core_terms, &terminal);
}
- else
- state().log().fatal(MF_REMOVE_TERMINAL_1_FROM_NET_2(terminal.name(), this->name()));
-}
-void detail::net_t::move_connections(detail::net_t &dest_net)
-{
- for (auto &ct : m_core_terms)
- dest_net.add_terminal(*ct);
- m_core_terms.clear();
-}
+ logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state,
+ nldelegate delegate)
+ : core_terminal_t(dev, aname, state, delegate)
+ , logic_family_t()
+ , m_proxy(nullptr)
+ {
+ }
-// ----------------------------------------------------------------------------------------
-// logic_net_t
-// ----------------------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------------------
+ // terminal_t
+ // ----------------------------------------------------------------------------------------
-logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
- : net_t(nl, aname, mr)
-{
-}
+ terminal_t::terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm)
+ : analog_t(dev, aname, STATE_BIDIR)
+ , m_Idr1(nullptr)
+ , m_go1(nullptr)
+ , m_gt1(nullptr)
+ , m_connected_terminal(otherterm)
+ {
+ state().setup().register_term(*this);
+ }
-// ----------------------------------------------------------------------------------------
-// analog_net_t
-// ----------------------------------------------------------------------------------------
+ void terminal_t::solve_now()
+ {
+ // Nets may belong to railnets which do not have a solver attached
+ if (this->has_net())
+ if (net().solver() != nullptr)
+ net().solver()->update_forced();
+ }
-analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
- : net_t(nl, aname, mr)
- , m_cur_Analog(*this, "m_cur_Analog", 0.0)
- , m_solver(nullptr)
-{
-}
-
-// ----------------------------------------------------------------------------------------
-// core_terminal_t
-// ----------------------------------------------------------------------------------------
-
-detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname,
- const state_e state, nldelegate delegate)
-: device_object_t(dev, dev.name() + "." + aname)
-, plib::linkedlist_t<core_terminal_t>::element_t()
-, m_delegate(delegate)
-#if USE_COPY_INSTEAD_OF_REFERENCE
-, m_Q(*this, "m_Q", 0)
-#endif
-, m_net(nullptr)
-, m_state(*this, "m_state", state)
-{
-}
+ void terminal_t::schedule_solve_after(const netlist_time after)
+ {
+ // Nets may belong to railnets which do not have a solver attached
+ if (this->has_net())
+ if (net().solver() != nullptr)
+ net().solver()->update_after(after);
+ }
-analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state,
- nldelegate delegate)
-: core_terminal_t(dev, aname, state, delegate)
-{
-}
+ // ----------------------------------------------------------------------------------------
+ // net_input_t
+ // ----------------------------------------------------------------------------------------
-logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state,
- nldelegate delegate)
- : core_terminal_t(dev, aname, state, delegate)
- , logic_family_t()
- , m_proxy(nullptr)
-{
-}
-
-// ----------------------------------------------------------------------------------------
-// terminal_t
-// ----------------------------------------------------------------------------------------
-
-terminal_t::terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm)
-: analog_t(dev, aname, STATE_BIDIR)
-, m_Idr1(nullptr)
-, m_go1(nullptr)
-, m_gt1(nullptr)
-, m_connected_terminal(otherterm)
-{
- state().setup().register_term(*this);
-}
+ // ----------------------------------------------------------------------------------------
+ // net_output_t
+ // ----------------------------------------------------------------------------------------
-void terminal_t::solve_now()
-{
- // Nets may belong to railnets which do not have a solver attached
- if (this->has_net())
- if (net().solver() != nullptr)
- net().solver()->update_forced();
-}
+ // ----------------------------------------------------------------------------------------
+ // logic_output_t
+ // ----------------------------------------------------------------------------------------
-void terminal_t::schedule_solve_after(const netlist_time after)
-{
- // Nets may belong to railnets which do not have a solver attached
- if (this->has_net())
- if (net().solver() != nullptr)
- net().solver()->update_after(after);
-}
-
-// ----------------------------------------------------------------------------------------
-// net_input_t
-// ----------------------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------------------
-// net_output_t
-// ----------------------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------------------
-// logic_output_t
-// ----------------------------------------------------------------------------------------
-
-logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname)
- : logic_t(dev, aname, STATE_OUT)
- , m_my_net(dev.state(), name() + ".net", this)
-{
- this->set_net(&m_my_net);
- state().register_net(owned_pool_ptr<logic_net_t>(&m_my_net, false));
- set_logic_family(dev.logic_family());
- state().setup().register_term(*this);
-}
+ logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname)
+ : logic_t(dev, aname, STATE_OUT)
+ , m_my_net(dev.state(), name() + ".net", this)
+ {
+ this->set_net(&m_my_net);
+ state().register_net(owned_pool_ptr<logic_net_t>(&m_my_net, false));
+ set_logic_family(dev.logic_family());
+ state().setup().register_term(*this);
+ }
-void logic_output_t::initial(const netlist_sig_t val)
-{
- if (has_net())
- net().initial(val);
-}
+ void logic_output_t::initial(const netlist_sig_t val)
+ {
+ if (has_net())
+ net().initial(val);
+ }
-// ----------------------------------------------------------------------------------------
-// analog_input_t
-// ----------------------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------------------
+ // analog_input_t
+ // ----------------------------------------------------------------------------------------
-analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname,
- nldelegate delegate)
-: analog_t(dev, aname, STATE_INP_ACTIVE, delegate)
-{
- state().setup().register_term(*this);
-}
+ analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname,
+ nldelegate delegate)
+ : analog_t(dev, aname, STATE_INP_ACTIVE, delegate)
+ {
+ state().setup().register_term(*this);
+ }
-// ----------------------------------------------------------------------------------------
-// analog_output_t
-// ----------------------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------------------
+ // analog_output_t
+ // ----------------------------------------------------------------------------------------
-analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
- : analog_t(dev, aname, STATE_OUT)
- , m_my_net(dev.state(), name() + ".net", this)
-{
- state().register_net(owned_pool_ptr<analog_net_t>(&m_my_net, false));
- this->set_net(&m_my_net);
+ analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
+ : analog_t(dev, aname, STATE_OUT)
+ , m_my_net(dev.state(), name() + ".net", this)
+ {
+ state().register_net(owned_pool_ptr<analog_net_t>(&m_my_net, false));
+ this->set_net(&m_my_net);
- //net().m_cur_Analog = NL_FCONST(0.0);
- state().setup().register_term(*this);
-}
+ //net().m_cur_Analog = NL_FCONST(0.0);
+ state().setup().register_term(*this);
+ }
-void analog_output_t::initial(const nl_double val)
-{
- net().set_Q_Analog(val);
-}
+ void analog_output_t::initial(const nl_double val)
+ {
+ net().set_Q_Analog(val);
+ }
-// -----------------------------------------------------------------------------
-// logic_input_t
-// -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ // logic_input_t
+ // -----------------------------------------------------------------------------
-logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname,
- nldelegate delegate)
- : logic_t(dev, aname, STATE_INP_ACTIVE, delegate)
-{
- set_logic_family(dev.logic_family());
- state().setup().register_term(*this);
-}
+ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname,
+ nldelegate delegate)
+ : logic_t(dev, aname, STATE_INP_ACTIVE, delegate)
+ {
+ set_logic_family(dev.logic_family());
+ state().setup().register_term(*this);
+ }
-// ----------------------------------------------------------------------------------------
-// Parameters ...
-// ----------------------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------------------
+ // Parameters ...
+ // ----------------------------------------------------------------------------------------
-param_t::param_t(device_t &device, const pstring &name)
- : device_object_t(device, device.name() + "." + name)
-{
- device.setup().register_param_t(this->name(), *this);
-}
+ param_t::param_t(device_t &device, const pstring &name)
+ : device_object_t(device, device.name() + "." + name)
+ {
+ device.setup().register_param_t(this->name(), *this);
+ }
-param_t::param_type_t param_t::param_type() const
-{
- if (dynamic_cast<const param_str_t *>(this) != nullptr)
- return STRING;
- else if (dynamic_cast<const param_double_t *>(this) != nullptr)
- return DOUBLE;
- else if (dynamic_cast<const param_int_t *>(this) != nullptr)
- return INTEGER;
- else if (dynamic_cast<const param_logic_t *>(this) != nullptr)
- return LOGIC;
- else if (dynamic_cast<const param_ptr_t *>(this) != nullptr)
- return POINTER;
- else
+ param_t::param_type_t param_t::param_type() const
{
- state().log().fatal(MF_UNKNOWN_PARAM_TYPE(name()));
- return POINTER; /* Please compiler */
+ if (dynamic_cast<const param_str_t *>(this) != nullptr)
+ return STRING;
+ else if (dynamic_cast<const param_double_t *>(this) != nullptr)
+ return DOUBLE;
+ else if (dynamic_cast<const param_int_t *>(this) != nullptr)
+ return INTEGER;
+ else if (dynamic_cast<const param_logic_t *>(this) != nullptr)
+ return LOGIC;
+ else if (dynamic_cast<const param_ptr_t *>(this) != nullptr)
+ return POINTER;
+ else
+ {
+ state().log().fatal(MF_UNKNOWN_PARAM_TYPE(name()));
+ return POINTER; /* Please compiler */
+ }
}
-}
-void param_t::update_param() NL_NOEXCEPT
-{
- device().update_param();
-}
+ void param_t::update_param() NL_NOEXCEPT
+ {
+ device().update_param();
+ }
-pstring param_t::get_initial(const device_t &dev, bool *found)
-{
- pstring res = dev.setup().get_initial_param_val(this->name(), "");
- *found = (res != "");
- return res;
-}
+ pstring param_t::get_initial(const device_t &dev, bool *found)
+ {
+ pstring res = dev.setup().get_initial_param_val(this->name(), "");
+ *found = (res != "");
+ return res;
+ }
-const pstring param_model_t::type()
-{
- return state().setup().models().type(str());
-}
+ const pstring param_model_t::type()
+ {
+ return state().setup().models().type(str());
+ }
-param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val)
-: param_t(device, name)
-{
- m_param = device.setup().get_initial_param_val(this->name(),val);
-}
+ param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val)
+ : param_t(device, name)
+ {
+ m_param = device.setup().get_initial_param_val(this->name(),val);
+ }
-void param_str_t::changed()
-{
-}
+ void param_str_t::changed()
+ {
+ }
-param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val)
-: param_t(device, name)
-{
- m_param = val; //device.setup().get_initial_param_val(this->name(),val);
- //netlist().save(*this, m_param, "m_param");
-}
+ param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val)
+ : param_t(device, name)
+ {
+ m_param = val; //device.setup().get_initial_param_val(this->name(),val);
+ //netlist().save(*this, m_param, "m_param");
+ }
-void param_model_t::changed()
-{
- state().log().fatal(MF_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME(name()));
-}
+ void param_model_t::changed()
+ {
+ state().log().fatal(MF_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME(name()));
+ }
-const pstring param_model_t::value_str(const pstring &entity)
-{
- return state().setup().models().value_str(str(), entity);
-}
+ const pstring param_model_t::value_str(const pstring &entity)
+ {
+ return state().setup().models().value_str(str(), entity);
+ }
-nl_double param_model_t::value(const pstring &entity)
-{
- return state().setup().models().value(str(), entity);
-}
+ nl_double param_model_t::value(const pstring &entity)
+ {
+ return state().setup().models().value(str(), entity);
+ }
-plib::unique_ptr<std::istream> param_data_t::stream()
-{
- return device().setup().get_data_stream(str());
-}
+ plib::unique_ptr<std::istream> param_data_t::stream()
+ {
+ return device().setup().get_data_stream(str());
+ }
bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT
{
@@ -1088,5 +966,15 @@ plib::unique_ptr<std::istream> param_data_t::stream()
return dynamic_cast<const analog_net_t *>(this) != nullptr;
}
+ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
+ {
+ if (!m_use_stats)
+ process_queue_stats<false>(delta, m_mainclock);
+ else
+ {
+ auto sm_guard(m_stat_mainloop.guard());
+ process_queue_stats<true>(delta, m_mainclock);
+ }
+ }
} // namespace netlist
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index e3868944d7d..9518705c2c6 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -16,15 +16,15 @@
#include "plib/palloc.h" // owned_ptr
#include "plib/pdynlib.h"
#include "plib/pfmtlog.h"
+#include "plib/plists.h"
#include "plib/pmempool.h"
#include "plib/ppmf.h"
#include "plib/pstate.h"
#include "plib/pstream.h"
+#include "plib/ptime.h"
#include "nl_errstr.h"
-#include "nl_lists.h"
#include "nltypes.h"
-#include "plib/ptime.h"
#include <unordered_map>
#include <vector>
@@ -311,7 +311,6 @@ namespace netlist
* state_var<unsigned> m_var;
* }
*/
-
template <typename T>
struct state_var
{
@@ -591,14 +590,14 @@ namespace netlist
nldelegate m_delegate;
#if USE_COPY_INSTEAD_OF_REFERENCE
- void set_copied_input(netlist_sig_t val)
+ void set_copied_input(netlist_sig_t val) noexcept
{
m_Q = val;
}
state_var_sig m_Q;
#else
- void set_copied_input(netlist_sig_t val) const { plib::unused_var(val); }
+ void set_copied_input(netlist_sig_t val) const noexcept { plib::unused_var(val); }
#endif
private:
@@ -669,13 +668,13 @@ namespace netlist
std::vector<core_terminal_t *> &core_terms() { return m_core_terms; }
#if USE_COPY_INSTEAD_OF_REFERENCE
- void update_inputs()
+ void update_inputs() noexcept
{
for (auto & term : m_core_terms)
term->m_Q = m_cur_Q;
}
#else
- void update_inputs() const
+ void update_inputs() const noexcept
{
/* nothing needs to be done */
}
@@ -810,9 +809,9 @@ namespace netlist
logic_t(core_device_t &dev, const pstring &aname,
const state_e state, nldelegate delegate = nldelegate());
- bool has_proxy() const { return (m_proxy != nullptr); }
- devices::nld_base_proxy *get_proxy() const { return m_proxy; }
- void set_proxy(devices::nld_base_proxy *proxy) { m_proxy = proxy; }
+ bool has_proxy() const noexcept { return (m_proxy != nullptr); }
+ devices::nld_base_proxy *get_proxy() const noexcept { return m_proxy; }
+ void set_proxy(devices::nld_base_proxy *proxy) noexcept { m_proxy = proxy; }
logic_net_t & net() NL_NOEXCEPT;
const logic_net_t & net() const NL_NOEXCEPT;
@@ -901,13 +900,13 @@ namespace netlist
analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
- nl_double Q_Analog() const NL_NOEXCEPT { return m_cur_Analog; }
- void set_Q_Analog(const nl_double v) NL_NOEXCEPT { m_cur_Analog = v; }
+ nl_double Q_Analog() const noexcept { return m_cur_Analog; }
+ void set_Q_Analog(const nl_double v) noexcept { m_cur_Analog = v; }
nl_double *Q_Analog_state_ptr() NL_NOEXCEPT { return m_cur_Analog.ptr(); }
//FIXME: needed by current solver code
- devices::matrix_solver_t *solver() const NL_NOEXCEPT { return m_solver; }
- void set_solver(devices::matrix_solver_t *solver) NL_NOEXCEPT { m_solver = solver; }
+ devices::matrix_solver_t *solver() const noexcept { return m_solver; }
+ void set_solver(devices::matrix_solver_t *solver) noexcept { m_solver = solver; }
private:
state_var<nl_double> m_cur_Analog;
@@ -1200,9 +1199,9 @@ namespace netlist
struct stats_t
{
// NL_KEEP_STATISTICS
- nperftime_t<true> m_stat_total_time;
- nperfcount_t<true> m_stat_call_count;
- nperfcount_t<true> m_stat_inc_active;
+ plib::pperftime_t<true> m_stat_total_time;
+ plib::pperfcount_t<true> m_stat_call_count;
+ plib::pperfcount_t<true> m_stat_inc_active;
};
unique_pool_ptr<stats_t> m_stats;
@@ -1245,8 +1244,8 @@ namespace netlist
~device_t() noexcept override = default;
- setup_t &setup();
- const setup_t &setup() const;
+ setup_t &setup() noexcept;
+ const setup_t &setup() const noexcept;
template<class C, typename... Args>
void create_and_register_subdevice(const pstring &name, unique_pool_ptr<C> &dev, Args&&... args)
@@ -1283,6 +1282,16 @@ namespace netlist
family_setter_t(core_device_t &dev, const logic_family_desc_t *desc);
};
+ template <class T, bool TS>
+ using timed_queue = plib::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>
+ //using timed_queue = timed_queue_heap<T, TS>;
+
// -----------------------------------------------------------------------------
// queue_t
// -----------------------------------------------------------------------------
@@ -1292,13 +1301,13 @@ 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>,
+ public timed_queue<plib::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>;
- using entry_t = pqentry_t<net_t *, netlist_time>;
+ using base_queue = timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>;
+ using entry_t = plib::pqentry_t<net_t *, netlist_time>;
explicit queue_t(netlist_state_t &nl);
virtual ~queue_t() noexcept = default;
@@ -1342,7 +1351,7 @@ namespace netlist
friend class netlist_t; // allow access to private members
template<class C>
- static bool check_class(core_device_t *p)
+ static bool check_class(core_device_t *p) noexcept
{
return dynamic_cast<C *>(p) != nullptr;
}
@@ -1385,12 +1394,12 @@ namespace netlist
/* logging and name */
- pstring name() const { return m_name; }
+ pstring name() const noexcept { return m_name; }
- log_type & log() { return m_log; }
- const log_type &log() const { return m_log; }
+ log_type & log() noexcept { return m_log; }
+ const log_type &log() const noexcept { return m_log; }
- plib::dynlib &lib() { return *m_lib; }
+ plib::dynlib &lib() const noexcept { return *m_lib; }
netlist_t &exec() { return m_netlist; }
const netlist_t &exec() const { return m_netlist; }
@@ -1486,16 +1495,19 @@ namespace netlist
}
}
- setup_t &setup() NL_NOEXCEPT { return *m_setup; }
- const setup_t &setup() const NL_NOEXCEPT { return *m_setup; }
+ setup_t &setup() noexcept { return *m_setup; }
+ const setup_t &setup() const noexcept { return *m_setup; }
// FIXME: make a postload member and include code there
void rebuild_lists(); /* must be called after post_load ! */
static void compile_defines(std::vector<std::pair<pstring, pstring>> &defs);
- nets_collection_type & nets() { return m_nets; }
- devices_collection_type & devices() { return m_devices; }
+ nets_collection_type & nets() noexcept { return m_nets; }
+ const nets_collection_type & nets() const noexcept { return m_nets; }
+
+ devices_collection_type & devices() noexcept { return m_devices; }
+ const devices_collection_type & devices() const noexcept { return m_devices; }
/* sole use is to manage lifetime of family objects */
std::unordered_map<pstring, plib::unique_ptr<logic_family_desc_t>> m_family_cache;
@@ -1549,12 +1561,13 @@ namespace netlist
const detail::queue_t &queue() const NL_NOEXCEPT { return m_queue; }
- void qpush(detail::queue_t::entry_t && e) noexcept
+ template <typename E>
+ void qpush(E && e) noexcept
{
if (!USE_QUEUE_STATS || !m_use_stats)
- m_queue.push<false>(std::move(e)); // NOLINT(performance-move-const-arg)
+ m_queue.push<false>(std::forward<E>(e)); // NOLINT(performance-move-const-arg)
else
- m_queue.push<true>(std::move(e)); // NOLINT(performance-move-const-arg)
+ m_queue.push<true>(std::forward<E>(e)); // NOLINT(performance-move-const-arg)
}
template <class R>
@@ -1573,10 +1586,10 @@ namespace netlist
/* state handling */
- plib::state_manager_t &run_state_manager() { return m_state->run_state_manager(); }
+ plib::state_manager_t &run_state_manager() noexcept { return m_state->run_state_manager(); }
/* only used by nltool to create static c-code */
- devices::NETLIB_NAME(solver) *solver() const NL_NOEXCEPT { return m_solver; }
+ devices::NETLIB_NAME(solver) *solver() const noexcept { return m_solver; }
/* force late type resolution */
template <typename X = devices::NETLIB_NAME(solver)>
@@ -1586,21 +1599,21 @@ namespace netlist
return static_cast<X *>(m_solver)->gmin();
}
- netlist_state_t &nlstate() NL_NOEXCEPT { return *m_state; }
- const netlist_state_t &nlstate() const { return *m_state; }
+ netlist_state_t &nlstate() noexcept { return *m_state; }
+ const netlist_state_t &nlstate() const noexcept { return *m_state; }
- log_type & log() { return m_state->log(); }
- const log_type &log() const { return m_state->log(); }
+ log_type & log() NL_NOEXCEPT { return m_state->log(); }
+ const log_type &log() const NL_NOEXCEPT { return m_state->log(); }
- void print_stats() const;
+ void print_stats() const NL_NOEXCEPT;
- bool stats_enabled() const { return m_use_stats; }
- void enable_stats(bool val) { m_use_stats = val; }
+ bool stats_enabled() const noexcept { return m_use_stats; }
+ void enable_stats(bool val) noexcept { m_use_stats = val; }
private:
- template <bool KEEP_STATS>
- void process_queue_stats(netlist_time delta) NL_NOEXCEPT;
+ template <bool KEEP_STATS, typename MCT>
+ void process_queue_stats(netlist_time delta, MCT *mainclock) NL_NOEXCEPT;
plib::unique_ptr<netlist_state_t> m_state;
devices::NETLIB_NAME(solver) * m_solver;
@@ -1615,8 +1628,8 @@ namespace netlist
bool m_use_stats;
// performance
- nperftime_t<true> m_stat_mainloop;
- nperfcount_t<true> m_perf_out_processed;
+ plib::pperftime_t<true> m_stat_mainloop;
+ plib::pperfcount_t<true> m_perf_out_processed;
};
// -----------------------------------------------------------------------------
@@ -1782,7 +1795,7 @@ namespace netlist
if (m_next_scheduled_time > exec().time())
{
m_in_queue = queue_status::QUEUED; /* pending */
- exec().qpush({m_next_scheduled_time, this});
+ exec().qpush(detail::queue_t::entry_t(m_next_scheduled_time, this));
}
else
{
@@ -1904,6 +1917,106 @@ namespace netlist
for (std::size_t i=0; i<N; i++)
(*this)[i] = value;
}
+
+ // -----------------------------------------------------------------------------
+ // Hot section
+ //
+ // Any changes below will impact performance.
+ // -----------------------------------------------------------------------------
+
+ template <bool KEEP_STATS, typename T>
+ inline void detail::net_t::process(const T mask, netlist_sig_t sig)
+ {
+ m_cur_Q = sig;
+
+ if (KEEP_STATS)
+ {
+ for (auto & p : m_list_active)
+ {
+ p.set_copied_input(sig);
+ auto *stats = p.device().m_stats.get();
+ stats->m_stat_call_count.inc();
+ if ((p.terminal_state() & mask))
+ {
+ auto g(stats->m_stat_total_time.guard());
+ p.m_delegate();
+ }
+ }
+ }
+ else
+ {
+ for (auto &p : m_list_active)
+ {
+ p.set_copied_input(sig);
+ if ((p.terminal_state() & mask))
+ p.m_delegate();
+ }
+ }
+ }
+
+ template <bool KEEP_STATS>
+ inline void detail::net_t::update_devs() NL_NOEXCEPT
+ {
+ nl_assert(this->isRailNet());
+
+ m_in_queue = queue_status::DELIVERED; /* mark as taken ... */
+ 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);
+ }
+
+ template <bool KEEP_STATS, typename MCT>
+ inline void netlist_t::process_queue_stats(const netlist_time delta, MCT *mainclock) NL_NOEXCEPT
+ {
+ netlist_time stop(m_time + delta);
+
+ qpush(detail::queue_t::entry_t(stop, nullptr));
+
+ if (m_mainclock == nullptr)
+ {
+ detail::queue_t::entry_t e(m_queue.pop());
+ m_time = e.m_exec_time;
+ while (e.m_object != nullptr)
+ {
+ e.m_object->template update_devs<KEEP_STATS>();
+ if (KEEP_STATS)
+ m_perf_out_processed.inc();
+ e = m_queue.pop();
+ m_time = e.m_exec_time;
+ }
+ }
+ else
+ {
+ logic_net_t &mc_net(mainclock->m_Q.net());
+ const netlist_time inc(mainclock->m_inc);
+ netlist_time mc_time(mc_net.next_scheduled_time());
+
+ do
+ {
+ while (m_queue.top().m_exec_time > mc_time)
+ {
+ m_time = mc_time;
+ mc_net.toggle_new_Q();
+ mc_net.update_devs<KEEP_STATS>();
+ mc_time += inc;
+ }
+
+ detail::queue_t::entry_t e(m_queue.pop());
+ m_time = e.m_exec_time;
+ if (e.m_object != nullptr)
+ {
+ e.m_object->template update_devs<KEEP_STATS>();
+ if (KEEP_STATS)
+ m_perf_out_processed.inc();
+ }
+ else
+ break;
+ } while (true); //while (e.m_object != nullptr);
+ mc_net.set_next_scheduled_time(mc_time);
+ }
+ }
+
+
} // namespace netlist
namespace plib
diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h
index 12cf72769a9..4681d027d79 100644
--- a/src/lib/netlist/nl_errstr.h
+++ b/src/lib/netlist/nl_errstr.h
@@ -14,7 +14,7 @@
#define PERRMSG(name, str) \
struct name \
{ \
- operator pstring() const { return str; } \
+ operator pstring() const noexcept { return str; } \
};
#define PERRMSGV(name, narg, str) \
@@ -23,7 +23,7 @@
template<typename... Args> name(Args&&... args) \
: m_m(plib::pfmt(str)(std::forward<Args>(args)...)) \
{ static_assert(narg == sizeof...(args), "Argument count mismatch"); } \
- operator pstring() const { return m_m; } \
+ operator pstring() const noexcept { return m_m; } \
pstring m_m; \
};
diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h
deleted file mode 100644
index 30c73062fd0..00000000000
--- a/src/lib/netlist/nl_lists.h
+++ /dev/null
@@ -1,335 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * nllists.h
- *
- */
-
-#pragma once
-
-#ifndef NLLISTS_H_
-#define NLLISTS_H_
-
-#include "plib/pchrono.h"
-#include "plib/plists.h"
-#include "plib/ptypes.h"
-#include "plib/parray.h"
-
-#include "nl_config.h"
-#include "nltypes.h"
-
-#include <algorithm>
-#include <atomic>
-#include <mutex>
-#include <thread>
-#include <utility>
-
-
-// ----------------------------------------------------------------------------------------
-// timed queue
-// ----------------------------------------------------------------------------------------
-
-namespace netlist
-{
- //FIXME: move to an appropriate place
- template<bool enabled_ = true>
- class pspin_mutex
- {
- public:
- pspin_mutex() noexcept = default;
- void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
- void unlock() noexcept { m_lock.clear(std::memory_order_release); }
- private:
- PALIGNAS_CACHELINE()
- std::atomic_flag m_lock = ATOMIC_FLAG_INIT;
- };
-
- template<>
- class pspin_mutex<false>
- {
- public:
- void lock() const noexcept { }
- void unlock() const noexcept { }
- };
-
- template <class Element, class Time>
- struct pqentry_t final
- {
- constexpr pqentry_t() noexcept : m_exec_time(), m_object(nullptr) { }
- constexpr pqentry_t(const Time t, const Element o) noexcept : m_exec_time(t), m_object(o) { }
-#if 0
- ~pqentry_t() = default;
- constexpr pqentry_t(const pqentry_t &e) noexcept = default;
- constexpr pqentry_t(pqentry_t &&e) noexcept = default;
- pqentry_t& operator=(pqentry_t && other) noexcept = default;
- pqentry_t& operator=(const pqentry_t &other) noexcept = default;
-
- void swap(pqentry_t &other) noexcept
- {
- std::swap(m_exec_time, other.m_exec_time);
- std::swap(m_object, other.m_object);
- }
-#endif
- inline bool operator ==(const pqentry_t &rhs) const noexcept
- {
- return m_object == rhs.m_object;
- }
-
- inline bool operator ==(const Element &rhs) const noexcept
- {
- return m_object == rhs;
- }
-
- inline bool operator <=(const pqentry_t &rhs) const noexcept
- {
- return (m_exec_time <= rhs.m_exec_time);
- }
-
- 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); }
-
- Time m_exec_time;
- Element m_object;
- };
-
- /* Use TS = true for a threadsafe queue */
- template <class T, bool TS>
- class timed_queue_linear : plib::nocopyassignmove
- {
- public:
-
- explicit timed_queue_linear(const std::size_t list_size)
- : m_list(list_size)
- {
- clear();
- }
-
- 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 (; *i < e; --i)
- {
- *(i+1) = *(i);
- if (KEEPSTAT)
- m_prof_sortmove.inc();
- }
- *(i+1) = std::move(e);
- ++m_end;
- if (KEEPSTAT)
- m_prof_call.inc();
- }
-
- T pop() noexcept { return *(--m_end); }
- const T &top() const noexcept { return *(m_end-1); }
-
- 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)
- {
- // == operator ignores time!
- if (*i == elem)
- {
- std::copy(i+1, m_end--, i);
- return;
- }
- }
- }
-
- template <bool KEEPSTAT, class R>
- void retime(R && elem) noexcept
- {
- /* Lock */
- lock_guard_type lck(m_lock);
- if (KEEPSTAT)
- m_prof_retime.inc();
-
- for (R * i = m_end - 1; i > &m_list[0]; --i)
- {
- if (*i == elem) // partial equal!
- {
- *i = std::move(elem);
- while (*(i-1) < *i)
- {
- std::swap(*(i-1), *i);
- --i;
- }
- while (i < m_end && *i < *(i+1))
- {
- std::swap(*(i+1), *i);
- ++i;
- }
- return;
- }
- }
- }
-
- void clear() noexcept
- {
- lock_guard_type 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
- * need a comparison with queue start.
- */
- m_list[0] = T::never();
- m_end++;
- }
-
- // save state support & mame disasm
-
- const T *listptr() const noexcept { return &m_list[1]; }
- std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); }
- const T & operator[](const std::size_t index) const noexcept { return m_list[ 1 + index]; }
- private:
- using mutex_type = pspin_mutex<TS>;
- using lock_guard_type = std::lock_guard<mutex_type>;
-
- mutex_type m_lock;
- PALIGNAS_CACHELINE()
- T * m_end;
- plib::aligned_vector<T> m_list;
-
- public:
- // profiling
- 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>
- class timed_queue_heap : plib::nocopyassignmove
- {
- public:
-
- struct compare
- {
- constexpr bool operator()(const T &a, const T &b) const { return b <= a; }
- };
-
- explicit timed_queue_heap(const std::size_t list_size)
- : m_list(list_size)
- {
- clear();
- }
-
- 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());
- if (KEEPSTAT)
- m_prof_call.inc();
- }
-
- T pop() noexcept
- {
- T ret(m_list[0]);
- std::pop_heap(&m_list[0], m_end, compare());
- m_end--;
- return ret;
- }
-
- const T &top() const noexcept { return m_list[0]; }
-
- 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 (*i == elem)
- {
- m_end--;
- for (;i < m_end; i++)
- *i = std::move(*(i+1));
- std::make_heap(&m_list[0], m_end, compare());
- return;
- }
- }
- }
-
- 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 (*i == elem) // partial equal!
- {
- *i = elem;
- std::make_heap(&m_list[0], m_end, compare());
- return;
- }
- }
- }
-
- void clear()
- {
- lock_guard_type lck(m_lock);
- m_list.clear();
- m_end = &m_list[0];
- }
-
- // save state support & mame disasm
-
- constexpr const T *listptr() const { return &m_list[0]; }
- constexpr std::size_t size() const noexcept { return m_list.size(); }
- constexpr const T & operator[](const std::size_t index) const { return m_list[ 0 + index]; }
- private:
- using mutex_type = pspin_mutex<TS>;
- using lock_guard_type = std::lock_guard<mutex_type>;
-
- mutex_type m_lock;
- std::vector<T> m_list;
- T *m_end;
-
- public:
- // profiling
- 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>
- //using timed_queue = timed_queue_heap<T, TS>;
-
-} // namespace netlist
-
-#endif /* NLLISTS_H_ */
diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h
index 3fb78d5e35b..453b0bb4adf 100644
--- a/src/lib/netlist/nltypes.h
+++ b/src/lib/netlist/nltypes.h
@@ -68,17 +68,6 @@ namespace netlist
using log_type = plib::plog_base<callbacks_t, NL_DEBUG>;
-
- //============================================================
- // Performance tracking
- //============================================================
-
- template<bool enabled_>
- using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, enabled_>;
-
- template<bool enabled_>
- using nperfcount_t = plib::chrono::counter<enabled_>;
-
//============================================================
// Types needed by various includes
//============================================================
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h
index ad42d14c690..5b7d2f59c2d 100644
--- a/src/lib/netlist/plib/palloc.h
+++ b/src/lib/netlist/plib/palloc.h
@@ -34,8 +34,10 @@ namespace plib {
{
//using arena_storage_type = P *;
using arena_storage_type = typename std::conditional<P::is_stateless, P, P *>::type;
+
template <typename X, typename Y = void>
typename std::enable_if<!X::is_stateless, X&>::type getref(X *x) { return *x;}
+
template <typename X, typename Y = void *>
typename std::enable_if<std::remove_pointer<X>::type::is_stateless, X&>::type
getref(X &x, Y y = nullptr)
@@ -44,13 +46,18 @@ namespace plib {
return x;
}
- constexpr arena_deleter(arena_storage_type a = arena_storage_type()) noexcept
+ constexpr arena_deleter(arena_storage_type a = arena_storage_type())
: m_a(a) { }
+#if 1
+ template<typename U, typename = typename
+ std::enable_if<std::is_convertible< U*, T*>::value>::type>
+ arena_deleter(const arena_deleter<P, U> &rhs) : m_a(rhs.m_a) { }
+#else
template<typename PU, typename U, typename = typename
std::enable_if<std::is_convertible< U*, T*>::value>::type>
- arena_deleter(const arena_deleter<PU, U> &rhs) noexcept : m_a(rhs.m_a) { }
-
+ arena_deleter(const arena_deleter<PU, U> &rhs) : m_a(rhs.m_a) { }
+#endif
void operator()(T *p) //const
{
/* call destructor */
@@ -80,11 +87,11 @@ namespace plib {
template <typename, typename>
friend class owned_ptr;
- owned_ptr(pointer p, bool owned) noexcept
+ owned_ptr(pointer p, bool owned)
: m_ptr(p), m_deleter(), m_is_owned(owned)
{ }
- owned_ptr(pointer p, bool owned, D deleter) noexcept
+ owned_ptr(pointer p, bool owned, D deleter)
: m_ptr(p), m_deleter(deleter), m_is_owned(owned)
{ }
@@ -93,7 +100,7 @@ namespace plib {
owned_ptr & operator =(owned_ptr &r) = delete;
template<typename DC, typename DC_D>
- owned_ptr & operator =(owned_ptr<DC, DC_D> &&r)
+ owned_ptr & operator =(owned_ptr<DC, DC_D> &&r) noexcept
{
if (m_is_owned && (m_ptr != nullptr))
//delete m_ptr;
@@ -122,7 +129,7 @@ namespace plib {
m_deleter(m_ptr);
m_is_owned = r.m_is_owned;
m_ptr = r.m_ptr;
- m_deleter = std::move(r.m_deleter);
+ m_deleter = r.m_deleter;
r.m_is_owned = false;
r.m_ptr = nullptr;
return *this;
@@ -197,18 +204,12 @@ namespace plib {
~arena_allocator() noexcept = default;
- arena_allocator(const arena_allocator &rhs) noexcept = default;
- arena_allocator& operator=(const arena_allocator&) noexcept = delete;
-
- arena_allocator(arena_allocator&&) noexcept = default;
- arena_allocator& operator=(arena_allocator&&) = delete;
-
arena_allocator(arena_type & a) noexcept : m_a(a)
{
}
template <class U>
- arena_allocator(const arena_allocator<ARENA, U, ALIGN>& rhs) noexcept
+ arena_allocator(const arena_allocator<ARENA, U, ALIGN>& rhs)
: m_a(rhs.m_a)
{
}
@@ -223,7 +224,7 @@ namespace plib {
return reinterpret_cast<T *>(m_a.allocate(ALIGN, sizeof(T) * n));
}
- void deallocate(T* p, std::size_t n) noexcept
+ void deallocate(T* p, std::size_t n)
{
unused_var(n);
m_a.deallocate(p);
diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h
index 65251a02002..d8f7a441f6f 100644
--- a/src/lib/netlist/plib/parray.h
+++ b/src/lib/netlist/plib/parray.h
@@ -32,6 +32,7 @@ namespace plib {
struct sizeabs<FT, 0>
{
static constexpr std::size_t ABS() { return 0; }
+ //using container = typename std::vector<FT, arena_allocator<mempool, FT, 64>>;
using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>;
};
@@ -75,6 +76,15 @@ namespace plib {
{
}
+ // osx clang doesn't like COPYASSIGNMOVE(parray, default)
+ // it will generate some weird error messages about move assignment
+ // constructor having a different noexcept status.
+
+ parray(const parray &rhs) : m_a(rhs.m_a), m_size(rhs.m_size) {}
+ parray(parray &&rhs) noexcept : m_a(std::move(rhs.m_a)), m_size(std::move(rhs.m_size)) {}
+ parray &operator=(const parray &rhs) { m_a = rhs.m_a; m_size = rhs.m_size; return *this; }
+ parray &operator=(parray &&rhs) noexcept { std::swap(m_a,rhs.m_a); std::swap(m_size, rhs.m_size); return *this; }
+
template <int X = SIZE >
parray(size_type size, typename std::enable_if<(X != 0), int>::type = 0)
: m_size(size)
@@ -125,6 +135,8 @@ namespace plib {
(*this)[i] = parray<FT, SIZE2>(size2);
}
}
+
+ COPYASSIGNMOVE(parray2D, default)
};
} // namespace plib
diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h
index d6e98134f47..4e0bb071431 100644
--- a/src/lib/netlist/plib/pchrono.h
+++ b/src/lib/netlist/plib/pchrono.h
@@ -15,245 +15,253 @@
//#include <cstdint>
namespace plib {
-namespace chrono {
- template <typename T>
- struct sys_ticks
- {
- using type = typename T::rep;
- static inline type start() { return T::now().time_since_epoch().count(); }
- static inline type stop() { return T::now().time_since_epoch().count(); }
- static inline constexpr type per_second() { return T::period::den / T::period::num; }
- };
-
- using hires_ticks = sys_ticks<std::chrono::high_resolution_clock>;
- using steady_ticks = sys_ticks<std::chrono::steady_clock>;
- using system_ticks = sys_ticks<std::chrono::system_clock>;
-
- #if defined(__x86_64__) && !defined(_clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
-
- template <typename T, typename R>
- struct base_ticks
- {
- using ret_type = R;
- static ret_type per_second()
+ namespace chrono {
+ template <typename T>
+ struct sys_ticks
{
- static ret_type persec = 0;
- if (persec == 0)
+ using type = typename T::rep;
+ static inline constexpr type start() noexcept { return T::now().time_since_epoch().count(); }
+ static inline constexpr type stop() noexcept { return T::now().time_since_epoch().count(); }
+ static inline constexpr type per_second() noexcept { return T::period::den / T::period::num; }
+ };
+
+ using hires_ticks = sys_ticks<std::chrono::high_resolution_clock>;
+ using steady_ticks = sys_ticks<std::chrono::steady_clock>;
+ using system_ticks = sys_ticks<std::chrono::system_clock>;
+
+ #if defined(__x86_64__) && !defined(_clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
+
+ template <typename T, typename R>
+ struct base_ticks
+ {
+ using ret_type = R;
+ static ret_type per_second()
{
- ret_type x = 0;
- system_ticks::type t = system_ticks::start();
- system_ticks::type e;
- x = - T :: start();
- do {
- e = system_ticks::stop();
- } while (e - t < system_ticks::per_second() / 100 );
- x += T :: stop();
- persec = (ret_type)(double)((double) x * (double) system_ticks::per_second() / double (e - t));
+ static ret_type persec = 0;
+ if (persec == 0)
+ {
+ ret_type x = 0;
+ system_ticks::type t = system_ticks::start();
+ system_ticks::type e;
+ x = - T :: start();
+ do {
+ e = system_ticks::stop();
+ } while (e - t < system_ticks::per_second() / 100 );
+ x += T :: stop();
+ persec = (ret_type)(double)((double) x * (double) system_ticks::per_second() / double (e - t));
+ }
+ return persec;
}
- return persec;
- }
- };
+ };
- #if PHAS_RDTSCP
- struct fast_ticks : public base_ticks<fast_ticks, int64_t>
- {
- typedef int64_t type;
- static inline type start()
+ #if PHAS_RDTSCP
+ struct fast_ticks : public base_ticks<fast_ticks, int64_t>
{
- int64_t v;
- __asm__ __volatile__ (
- "rdtscp;"
- "shl $32, %%rdx;"
- "or %%rdx, %%rax;"
- : "=a"(v) /* outputs */
- : /* inputs */
- : "%rcx", "%rdx" /* clobbers */
- );
- return v;
- }
- static inline type stop()
- {
- return start();
- }
- };
-
- #else
- struct fast_ticks : public base_ticks<fast_ticks, int64_t>
- {
- typedef int64_t type;
- static inline type start()
- {
- int64_t v;
- __asm__ __volatile__ (
- "rdtsc;"
- "shl $32, %%rdx;"
- "or %%rdx, %%rax;"
- : "=a"(v) /* outputs */
- : /* inputs */
- : "%rdx" /* clobbers */
- );
- return v;
- }
- static inline type stop()
+ typedef int64_t type;
+ static inline type start() noexcept
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "rdtscp;"
+ "shl $32, %%rdx;"
+ "or %%rdx, %%rax;"
+ : "=a"(v) /* outputs */
+ : /* inputs */
+ : "%rcx", "%rdx" /* clobbers */
+ );
+ return v;
+ }
+ static inline type stop() noexcept
+ {
+ return start();
+ }
+ };
+
+ #else
+ struct fast_ticks : public base_ticks<fast_ticks, int64_t>
{
- return start();
- }
- };
+ typedef int64_t type;
+ static inline type start() noexcept
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "rdtsc;"
+ "shl $32, %%rdx;"
+ "or %%rdx, %%rax;"
+ : "=a"(v) /* outputs */
+ : /* inputs */
+ : "%rdx" /* clobbers */
+ );
+ return v;
+ }
+ static inline type stop() noexcept
+ {
+ return start();
+ }
+ };
- #endif
+ #endif
- /* Based on "How to Benchmark Code Execution Times on Intel?? IA-32 and IA-64
- * Instruction Set Architectures", Intel, 2010
- *
- */
- #if PUSE_ACCURATE_STATS && PHAS_RDTSCP
- /*
- * kills performance completely, but is accurate
- * cpuid serializes, but clobbers ebx and ecx
- *
- */
+ /* Based on "How to Benchmark Code Execution Times on Intel?? IA-32 and IA-64
+ * Instruction Set Architectures", Intel, 2010
+ *
+ */
+ #if PUSE_ACCURATE_STATS && PHAS_RDTSCP
+ /*
+ * kills performance completely, but is accurate
+ * cpuid serializes, but clobbers ebx and ecx
+ *
+ */
- struct exact_ticks : public base_ticks<exact_ticks, int64_t>
- {
- typedef int64_t type;
+ struct exact_ticks : public base_ticks<exact_ticks, int64_t>
+ {
+ typedef int64_t type;
- static inline type start()
+ static inline type start() noexcept
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "cpuid;"
+ //"xor %%eax, %%eax\n\t"
+ "rdtsc;"
+ "shl $32, %%rdx;"
+ "or %%rdx, %%rax;"
+ : "=a"(v) /* outputs */
+ : "a"(0x0) /* inputs */
+ : "%ebx", "%ecx", "%rdx" /* clobbers*/
+ );
+ return v;
+ }
+ static inline type stop() noexcept
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "rdtscp;"
+ "shl $32, %%rdx;"
+ "or %%rax, %%rdx;"
+ "mov %%rdx, %%r10;"
+ "xor %%eax, %%eax\n\t"
+ "cpuid;"
+ "mov %%r10, %%rax;"
+ : "=a" (v)
+ :
+ : "%ebx", "%ecx", "%rdx", "%r10"
+ );
+ return v;
+ }
+ };
+ #else
+ using exact_ticks = fast_ticks;
+ #endif
+
+
+ #else
+ using fast_ticks = hires_ticks;
+ using exact_ticks = fast_ticks;
+ #endif
+
+ template<bool enabled_>
+ struct counter
{
- int64_t v;
- __asm__ __volatile__ (
- "cpuid;"
- //"xor %%eax, %%eax\n\t"
- "rdtsc;"
- "shl $32, %%rdx;"
- "or %%rdx, %%rax;"
- : "=a"(v) /* outputs */
- : "a"(0x0) /* inputs */
- : "%ebx", "%ecx", "%rdx" /* clobbers*/
- );
- return v;
- }
- static inline type stop()
+ counter() : m_count(0) { }
+ using type = uint_least64_t;
+ type operator()() const noexcept { return m_count; }
+ void inc() noexcept { ++m_count; }
+ void reset() noexcept { m_count = 0; }
+ constexpr static bool enabled = enabled_;
+ private:
+ type m_count;
+ };
+
+ template<>
+ struct counter<false>
{
- int64_t v;
- __asm__ __volatile__ (
- "rdtscp;"
- "shl $32, %%rdx;"
- "or %%rax, %%rdx;"
- "mov %%rdx, %%r10;"
- "xor %%eax, %%eax\n\t"
- "cpuid;"
- "mov %%r10, %%rax;"
- : "=a" (v)
- :
- : "%ebx", "%ecx", "%rdx", "%r10"
- );
- return v;
- }
- };
- #else
- using exact_ticks = fast_ticks;
- #endif
-
-
- #else
- using fast_ticks = hires_ticks;
- using exact_ticks = fast_ticks;
- #endif
+ using type = uint_least64_t;
+ constexpr type operator()() const { return 0; }
+ void inc() const { }
+ void reset() const { }
+ constexpr static bool enabled = false;
+ };
- template<bool enabled_>
- struct counter
- {
- counter() : m_count(0) { }
- using type = uint_least64_t;
- type operator()() const { return m_count; }
- void inc() { ++m_count; }
- void reset() { m_count = 0; }
- constexpr static bool enabled = enabled_;
- private:
- type m_count;
- };
-
- template<>
- struct counter<false>
- {
- using type = uint_least64_t;
- constexpr type operator()() const { return 0; }
- void inc() const { }
- void reset() const { }
- constexpr static bool enabled = false;
- };
-
-
- template< typename T, bool enabled_ = true>
- struct timer
- {
- using type = typename T::type;
- using ctype = uint_least64_t;
- constexpr static bool enabled = enabled_;
-
- struct guard_t
+
+ template< typename T, bool enabled_ = true>
+ struct timer
{
- guard_t() = delete;
- guard_t(timer &m) noexcept : m_m(m) { m_m.m_time -= T::start(); }
- ~guard_t() { m_m.m_time += T::stop(); ++m_m.m_count; }
+ using type = typename T::type;
+ using ctype = uint_least64_t;
+ constexpr static bool enabled = enabled_;
- COPYASSIGNMOVE(guard_t, default)
+ struct guard_t
+ {
+ guard_t() = delete;
+ guard_t(timer &m) noexcept : m_m(m) { m_m.m_time -= T::start(); }
+ ~guard_t() { m_m.m_time += T::stop(); ++m_m.m_count; }
- private:
- timer &m_m;
- };
+ COPYASSIGNMOVE(guard_t, default)
- friend struct guard_t;
+ private:
+ timer &m_m;
+ };
- timer() : m_time(0), m_count(0) { }
+ friend struct guard_t;
- type operator()() const { return m_time; }
+ timer() : m_time(0), m_count(0) { }
- void reset() { m_time = 0; m_count = 0; }
- type average() const { return (m_count == 0) ? 0 : m_time / m_count; }
- type total() const { return m_time; }
- ctype count() const { return m_count; }
+ type operator()() const { return m_time; }
- double as_seconds() const { return static_cast<double>(total())
- / static_cast<double>(T::per_second()); }
+ void reset() { m_time = 0; m_count = 0; }
+ type average() const { return (m_count == 0) ? 0 : m_time / m_count; }
+ type total() const { return m_time; }
+ ctype count() const { return m_count; }
- guard_t guard() { return guard_t(*this); }
- private:
- type m_time;
- ctype m_count;
- };
+ double as_seconds() const { return static_cast<double>(total())
+ / static_cast<double>(T::per_second()); }
- template<typename T>
- struct timer<T, false>
- {
- using type = typename T::type;
- using ctype = uint_least64_t;
+ guard_t guard() { return guard_t(*this); }
+ private:
+ type m_time;
+ ctype m_count;
+ };
- struct guard_t
+ template<typename T>
+ struct timer<T, false>
{
- guard_t() = default;
- COPYASSIGNMOVE(guard_t, default)
- /* using default constructor will trigger warning on
- * unused local variable.
- */
- // NOLINTNEXTLINE(modernize-use-equals-default)
- ~guard_t() { }
+ using type = typename T::type;
+ using ctype = uint_least64_t;
+
+ struct guard_t
+ {
+ guard_t() = default;
+ COPYASSIGNMOVE(guard_t, default)
+ /* using default constructor will trigger warning on
+ * unused local variable.
+ */
+ // NOLINTNEXTLINE(modernize-use-equals-default)
+ ~guard_t() { }
+ };
+
+ constexpr type operator()() const { return 0; }
+ void reset() const { }
+ constexpr type average() const { return 0; }
+ constexpr type total() const { return 0; }
+ constexpr ctype count() const { return 0; }
+ constexpr double as_seconds() const { return 0.0; }
+ constexpr static bool enabled = false;
+ guard_t guard() { return guard_t(); }
};
- constexpr type operator()() const { return 0; }
- void reset() const { }
- constexpr type average() const { return 0; }
- constexpr type total() const { return 0; }
- constexpr ctype count() const { return 0; }
- constexpr double as_seconds() const { return 0.0; }
- constexpr static bool enabled = false;
- guard_t guard() { return guard_t(); }
- };
+ } // namespace chrono
+ //============================================================
+ // Performance tracking
+ //============================================================
+ template<bool enabled_>
+ using pperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, enabled_>;
- } // namespace chrono
+ template<bool enabled_>
+ using pperfcount_t = plib::chrono::counter<enabled_>;
} // namespace plib
#endif /* PCHRONO_H_ */
diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp
index 990c8a78e94..ca7ec88e2e3 100644
--- a/src/lib/netlist/plib/pfmtlog.cpp
+++ b/src/lib/netlist/plib/pfmtlog.cpp
@@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
- * nl_string.c
+ * pfm_log.cpp
*
*/
diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h
index 727dad5d936..d6c37eaf5ca 100644
--- a/src/lib/netlist/plib/plists.h
+++ b/src/lib/netlist/plib/plists.h
@@ -10,283 +10,506 @@
#ifndef PLISTS_H_
#define PLISTS_H_
+#include "palloc.h"
+#include "pchrono.h"
#include "pstring.h"
+#include <algorithm>
#include <array>
+#include <atomic>
+#include <mutex>
#include <type_traits>
+#include <utility>
#include <vector>
namespace plib {
-/* ----------------------------------------------------------------------------------------
- * uninitialised_array_t:
- * fixed size array allowing to override constructor and initialize
- * members by placement new.
- *
- * Use with care. This template is provided to improve locality of storage
- * in high frequency applications. It should not be used for anything else.
- * ---------------------------------------------------------------------------------------- */
-
-template <class C, std::size_t N>
-class uninitialised_array_t
-{
-public:
- using iterator = C *;
- using const_iterator = const C *;
-
- //uninitialised_array_t() noexcept = default;
- uninitialised_array_t() noexcept
- : m_initialized(0)
+ /**! fixed size array allowing to override constructor and initialize members by placement new.
+ *
+ * Use with care. This template is provided to improve locality of storage
+ * in high frequency applications. It should not be used for anything else.
+ *
+ */
+ template <class C, std::size_t N>
+ class uninitialised_array_t
{
- }
+ public:
- COPYASSIGNMOVE(uninitialised_array_t, delete)
- ~uninitialised_array_t() noexcept
- {
- if (m_initialized>=N)
- for (std::size_t i=0; i<N; i++)
- (*this)[i].~C();
- }
+ using iterator = C *;
+ using const_iterator = const C *;
- size_t size() const { return N; }
+ //uninitialised_array_t() noexcept = default;
+ uninitialised_array_t() noexcept
+ : m_initialized(0)
+ {
+ }
- C& operator[](const std::size_t &index) noexcept
- {
- return *reinterpret_cast<C *>(&m_buf[index]);
- }
+ COPYASSIGNMOVE(uninitialised_array_t, delete)
+ ~uninitialised_array_t() noexcept
+ {
+ if (m_initialized>=N)
+ for (std::size_t i=0; i<N; i++)
+ (*this)[i].~C();
+ }
- const C& operator[](const std::size_t &index) const noexcept
- {
- return *reinterpret_cast<const C *>(&m_buf[index]);
- }
+ size_t size() const { return N; }
- template<typename... Args>
- void emplace(const std::size_t index, Args&&... args)
- {
- m_initialized++;
- // allocate on buffer
- new (&m_buf[index]) C(std::forward<Args>(args)...);
- }
+ C& operator[](const std::size_t &index) noexcept
+ {
+ return *reinterpret_cast<C *>(&m_buf[index]);
+ }
- iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
- iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[N]); }
+ const C& operator[](const std::size_t &index) const noexcept
+ {
+ return *reinterpret_cast<const C *>(&m_buf[index]);
+ }
- iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
- iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[N]); }
+ template<typename... Args>
+ void emplace(const std::size_t index, Args&&... args)
+ {
+ m_initialized++;
+ // allocate on buffer
+ new (&m_buf[index]) C(std::forward<Args>(args)...);
+ }
- const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); }
- const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[N]); }
+ iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
+ iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[N]); }
-protected:
+ iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
+ iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[N]); }
-private:
+ const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); }
+ const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[N]); }
- /* ensure proper alignment */
- PALIGNAS_VECTOROPT()
- std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf;
- unsigned m_initialized;
-};
+ protected:
-// ----------------------------------------------------------------------------------------
-// plinkedlist_t: a simple linked list
-// the list allows insertions / deletions if used properly
-// ----------------------------------------------------------------------------------------
+ private:
-#if 0
-template <class LC>
-class linkedlist_t
-{
-public:
+ /* ensure proper alignment */
+ PALIGNAS_VECTOROPT()
+ std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf;
+ unsigned m_initialized;
+ };
- struct element_t
+ /**! a simple linked list.
+ *
+ * the list allows insertions deletions whilst being processed.
+ */
+ template <class LC>
+ class linkedlist_t
{
public:
- friend class linkedlist_t<LC>;
+ struct element_t
+ {
+ public:
+ friend class linkedlist_t<LC>;
+
+ constexpr element_t() : m_next(nullptr), m_prev(nullptr) {}
+ ~element_t() noexcept = default;
- constexpr element_t() : m_next(nullptr) {}
- constexpr element_t(const element_t &rhs) = delete;
- constexpr element_t(element_t &&rhs) = delete;
+ COPYASSIGNMOVE(element_t, delete)
- constexpr LC *next() const noexcept { return m_next; }
+ constexpr LC *next() const noexcept { return m_next; }
+ constexpr LC *prev() const noexcept { return m_prev; }
+ private:
+ LC * m_next;
+ LC * m_prev;
+ };
+
+ struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
+ {
+ private:
+ LC* p;
+ 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 { if (this != &rhs) p = rhs.p; return *this; }
+ iter_t& operator=(iter_t &&rhs) noexcept { std::swap(*this, rhs); return *this; }
+ ~iter_t() = default;
+
+ iter_t& operator++() noexcept { p = p->next();return *this; }
+ // NOLINTNEXTLINE(cert-dcl21-cpp)
+ iter_t operator++(int) & noexcept { const iter_t tmp(*this); operator++(); return tmp; }
+
+ 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; }
+ C14CONSTEXPR LC& operator*() noexcept { return *p; }
+ C14CONSTEXPR LC* operator->() noexcept { return p; }
+
+ C14CONSTEXPR LC& operator*() const noexcept { return *p; }
+ C14CONSTEXPR LC* operator->() const noexcept { return p; }
+ };
+
+ constexpr linkedlist_t() : m_head(nullptr) {}
+
+ constexpr iter_t begin() const noexcept { return iter_t(m_head); }
+ constexpr iter_t end() const noexcept { return iter_t(nullptr); }
+
+ void push_front(LC *elem) noexcept
+ {
+ elem->m_next = m_head;
+ elem->m_prev = nullptr;
+ if (m_head)
+ m_head->m_prev = elem;
+ m_head = elem;
+ }
+
+ void push_back(LC *elem) noexcept
+ {
+ LC ** p(&m_head);
+ LC * prev(nullptr);
+ while (*p != nullptr)
+ {
+ prev = *p;
+ p = &((*p)->m_next);
+ }
+ *p = elem;
+ elem->m_prev = prev;
+ elem->m_next = nullptr;
+ }
+
+ void remove(const LC *elem) noexcept
+ {
+ if (elem->m_prev)
+ elem->m_prev->m_next = elem->m_next;
+ else
+ m_head = elem->m_next;
+ if (elem->m_next)
+ elem->m_next->m_prev = elem->m_prev;
+ else
+ {
+ /* update tail */
+ }
+ }
+
+ LC *front() const noexcept { return m_head; }
+ 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;
+ }
- protected:
- ~element_t() = default;
private:
- LC * m_next;
+ LC *m_head;
};
- struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
+ // ----------------------------------------------------------------------------------------
+ // FIXME: Move elsewhere
+ // ----------------------------------------------------------------------------------------
+
+ template<bool enabled_ = true>
+ class pspin_mutex
{
- private:
- LC* p;
public:
- explicit constexpr iter_t(LC* x) noexcept : p(x) { }
- explicit constexpr iter_t(const iter_t &rhs) noexcept : p(rhs.p) { }
- iter_t(iter_t &&rhs) noexcept { std::swap(*this, rhs); }
- iter_t& operator=(const iter_t &rhs) { iter_t t(rhs); std::swap(*this, t); return *this; }
- iter_t& operator=(iter_t &&rhs) { std::swap(*this, rhs); return *this; }
- iter_t& operator++() noexcept {p = p->next();return *this;}
- iter_t operator++(int) noexcept {iter_t tmp(*this); operator++(); return tmp;}
- 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*() const noexcept {return *p;}
- constexpr LC* operator->() const noexcept {return p;}
+ pspin_mutex() noexcept = default;
+ void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
+ void unlock() noexcept { m_lock.clear(std::memory_order_release); }
+ private:
+ PALIGNAS_CACHELINE()
+ std::atomic_flag m_lock = ATOMIC_FLAG_INIT;
};
- constexpr linkedlist_t() : m_head(nullptr) {}
+ template<>
+ class pspin_mutex<false>
+ {
+ public:
+ void lock() const noexcept { }
+ void unlock() const noexcept { }
+ };
- constexpr iter_t begin() const noexcept { return iter_t(m_head); }
- constexpr iter_t end() const noexcept { return iter_t(nullptr); }
+ // ----------------------------------------------------------------------------------------
+ // timed queue
+ // ----------------------------------------------------------------------------------------
- void push_front(LC *elem) noexcept
+ template <class Element, class Time>
+ struct pqentry_t final
{
- elem->m_next = m_head;
- m_head = elem;
- }
+ constexpr pqentry_t() noexcept : m_exec_time(), m_object(nullptr) { }
+ constexpr pqentry_t(const Time t, const Element o) noexcept : m_exec_time(t), m_object(o) { }
+#if 0
+ ~pqentry_t() = default;
+ constexpr pqentry_t(const pqentry_t &e) noexcept = default;
+ constexpr pqentry_t(pqentry_t &&e) noexcept = default;
+ pqentry_t& operator=(pqentry_t && other) noexcept = default;
+ pqentry_t& operator=(const pqentry_t &other) noexcept = default;
- void push_back(LC *elem) noexcept
- {
- LC **p = &m_head;
- while (*p != nullptr)
+ void swap(pqentry_t &other) noexcept
{
- p = &((*p)->m_next);
+ std::swap(m_exec_time, other.m_exec_time);
+ std::swap(m_object, other.m_object);
+ }
+#endif
+ inline bool operator ==(const pqentry_t &rhs) const noexcept
+ {
+ return m_object == rhs.m_object;
}
- *p = elem;
- elem->m_next = nullptr;
- }
- void remove(const LC *elem) noexcept
- {
- auto p = &m_head;
- while(*p != elem)
+ inline bool operator ==(const Element &rhs) const noexcept
+ {
+ return m_object == rhs;
+ }
+
+ inline bool operator <=(const pqentry_t &rhs) const noexcept
{
- //nl_assert(*p != nullptr);
- p = &((*p)->m_next);
+ return (m_exec_time <= rhs.m_exec_time);
}
- (*p) = elem->m_next;
- }
- LC *front() const noexcept { return m_head; }
- void clear() noexcept { m_head = nullptr; }
- constexpr bool empty() const noexcept { return (m_head == nullptr); }
+ inline bool operator <(const pqentry_t &rhs) const noexcept
+ {
+ return (m_exec_time < rhs.m_exec_time);
+ }
-private:
- LC *m_head;
-};
-#else
-template <class LC>
-class linkedlist_t
-{
-public:
+ inline static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); }
- struct element_t
+ Time m_exec_time;
+ Element m_object;
+ };
+
+ /* Use TS = true for a threadsafe queue */
+ template <class T, bool TS>
+ class timed_queue_linear : nocopyassignmove
{
public:
- friend class linkedlist_t<LC>;
+ explicit timed_queue_linear(const std::size_t list_size)
+ : m_list(list_size)
+ {
+ clear();
+ }
+
+ 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
+ {
+#if 0
+ /* Lock */
+ lock_guard_type lck(m_lock);
+ T * i(m_end-1);
+ for (; *i < e; --i)
+ {
+ *(i+1) = *(i);
+ if (KEEPSTAT)
+ m_prof_sortmove.inc();
+ }
+ *(i+1) = std::move(e);
+ ++m_end;
+#else
+ /* Lock */
+ lock_guard_type lck(m_lock);
+ T * i(m_end++);
+ *i = std::move(e);
+ for (; *(i-1) < *i; --i)
+ {
+ std::swap(*(i-1), *(i));
+ if (KEEPSTAT)
+ m_prof_sortmove.inc();
+ }
+#endif
+ if (KEEPSTAT)
+ m_prof_call.inc();
+ }
+
+ T pop() noexcept { return *(--m_end); }
+ const T &top() const noexcept { return *(m_end-1); }
- constexpr element_t() : m_next(nullptr), m_prev(nullptr) {}
- ~element_t() noexcept = default;
+ 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)
+ {
+ // == operator ignores time!
+ if (*i == elem)
+ {
+ std::copy(i+1, m_end--, i);
+ return;
+ }
+ }
+ }
- COPYASSIGNMOVE(element_t, delete)
+ template <bool KEEPSTAT, class R>
+ void retime(R && elem) noexcept
+ {
+ /* Lock */
+ lock_guard_type lck(m_lock);
+ if (KEEPSTAT)
+ m_prof_retime.inc();
+
+ for (R * i = m_end - 1; i > &m_list[0]; --i)
+ {
+ if (*i == elem) // partial equal!
+ {
+ *i = std::forward<R>(elem);
+ while (*(i-1) < *i)
+ {
+ std::swap(*(i-1), *i);
+ --i;
+ }
+ while (i < m_end && *i < *(i+1))
+ {
+ std::swap(*(i+1), *i);
+ ++i;
+ }
+ return;
+ }
+ }
+ }
- constexpr LC *next() const noexcept { return m_next; }
- constexpr LC *prev() const noexcept { return m_prev; }
+ void clear() noexcept
+ {
+ lock_guard_type 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
+ * need a comparison with queue start.
+ */
+ m_list[0] = T::never();
+ m_end++;
+ }
+
+ // save state support & mame disasm
+
+ const T *listptr() const noexcept { return &m_list[1]; }
+ std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); }
+ const T & operator[](const std::size_t index) const noexcept { return m_list[ 1 + index]; }
private:
- LC * m_next;
- LC * m_prev;
+ using mutex_type = pspin_mutex<TS>;
+ using lock_guard_type = std::lock_guard<mutex_type>;
+
+ mutex_type m_lock;
+ PALIGNAS_CACHELINE()
+ T * m_end;
+ aligned_vector<T> m_list;
+
+ public:
+ // profiling
+ pperfcount_t<true> m_prof_sortmove;
+ pperfcount_t<true> m_prof_call;
+ pperfcount_t<true> m_prof_remove;
+ pperfcount_t<true> m_prof_retime;
};
- struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
+ template <class T, bool TS>
+ class timed_queue_heap : nocopyassignmove
{
- private:
- LC* p;
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 { 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)
- iter_t operator++(int) & noexcept {const iter_t tmp(*this); operator++(); return tmp;}
-
- ~iter_t() = default;
-
- 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*() const noexcept {return *p;}
- constexpr LC* operator->() const noexcept {return p;}
- };
- constexpr linkedlist_t() : m_head(nullptr) {}
+ struct compare
+ {
+ constexpr bool operator()(const T &a, const T &b) const { return b <= a; }
+ };
- constexpr iter_t begin() const noexcept { return iter_t(m_head); }
- constexpr iter_t end() const noexcept { return iter_t(nullptr); }
+ explicit timed_queue_heap(const std::size_t list_size)
+ : m_list(list_size)
+ {
+ clear();
+ }
- void push_front(LC *elem) noexcept
- {
- if (m_head)
- m_head->m_prev = elem;
- elem->m_next = m_head;
- elem->m_prev = nullptr;
- m_head = elem;
- }
-
- void push_back(LC *elem) noexcept
- {
- LC ** p(&m_head);
- LC * prev(nullptr);
- while (*p != nullptr)
+ 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
{
- prev = *p;
- p = &((*p)->m_next);
+ /* Lock */
+ lock_guard_type lck(m_lock);
+ *m_end++ = e;
+ std::push_heap(&m_list[0], m_end, compare());
+ if (KEEPSTAT)
+ m_prof_call.inc();
}
- *p = elem;
- elem->m_prev = prev;
- elem->m_next = nullptr;
- }
- void remove(const LC *elem) noexcept
- {
- if (elem->m_prev)
- elem->m_prev->m_next = elem->m_next;
- else
- m_head = elem->m_next;
- if (elem->m_next)
- elem->m_next->m_prev = elem->m_prev;
- else
+ T pop() noexcept
{
- /* update tail */
+ T ret(m_list[0]);
+ std::pop_heap(&m_list[0], m_end, compare());
+ m_end--;
+ return ret;
}
- }
- LC *front() const noexcept { return m_head; }
- constexpr bool empty() const noexcept { return (m_head == nullptr); }
- void clear() noexcept
- {
- LC *p(m_head);
- while (p != nullptr)
+ const T &top() const noexcept { return m_list[0]; }
+
+ template <bool KEEPSTAT, class R>
+ void remove(const R &elem) noexcept
{
- LC *n(p->m_next);
- p->m_next = nullptr;
- p->m_prev = nullptr;
- p = n;
+ /* 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 (*i == elem)
+ {
+ m_end--;
+ for (;i < m_end; i++)
+ *i = std::move(*(i+1));
+ std::make_heap(&m_list[0], m_end, compare());
+ return;
+ }
+ }
}
- m_head = nullptr;
- }
-private:
- LC *m_head;
-};
-#endif
+ 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 (*i == elem) // partial equal!
+ {
+ *i = elem;
+ std::make_heap(&m_list[0], m_end, compare());
+ return;
+ }
+ }
+ }
+
+ void clear()
+ {
+ lock_guard_type lck(m_lock);
+ m_list.clear();
+ m_end = &m_list[0];
+ }
+
+ // save state support & mame disasm
+
+ constexpr const T *listptr() const { return &m_list[0]; }
+ constexpr std::size_t size() const noexcept { return m_list.size(); }
+ constexpr const T & operator[](const std::size_t index) const { return m_list[ 0 + index]; }
+ private:
+ using mutex_type = pspin_mutex<TS>;
+ using lock_guard_type = std::lock_guard<mutex_type>;
+
+ mutex_type m_lock;
+ std::vector<T> m_list;
+ T *m_end;
+
+ public:
+ // profiling
+ pperfcount_t<true> m_prof_sortmove;
+ pperfcount_t<true> m_prof_call;
+ pperfcount_t<true> m_prof_remove;
+ pperfcount_t<true> m_prof_retime;
+ };
+
} // namespace plib
#endif /* PLISTS_H_ */
diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h
index 7a59097afe3..a4ac4fd393f 100644
--- a/src/lib/netlist/plib/pmempool.h
+++ b/src/lib/netlist/plib/pmempool.h
@@ -123,6 +123,12 @@ namespace plib {
}
}
+ static inline mempool &instance()
+ {
+ static mempool s_mempool;
+ return s_mempool;
+ }
+
void *allocate(size_t align, size_t size)
{
block *b = nullptr;
@@ -220,6 +226,8 @@ namespace plib {
}
}
+ bool operator ==(const mempool &rhs) { return this == &rhs; }
+
};
} // namespace plib
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp
index 796a18d8d26..74d0b137829 100644
--- a/src/lib/netlist/plib/pparser.cpp
+++ b/src/lib/netlist/plib/pparser.cpp
@@ -261,8 +261,8 @@ ptokenizer::token_t ptokenizer::get_token_internal()
ppreprocessor::ppreprocessor(defines_map_type *defines)
: std::istream(new readbuffer(this))
-, m_ifflag(0)
-, m_level(0)
+, m_if_flag(0)
+, m_if_level(0)
, m_lineno(0)
, m_pos(0)
, m_state(PROCESS)
@@ -473,34 +473,34 @@ pstring ppreprocessor::process_line(pstring line)
std::vector<pstring> lti(psplit(lt, " ", true));
if (lti[0] == "#if")
{
- m_level++;
+ m_if_level++;
std::size_t start = 0;
lt = replace_macros(lt);
std::vector<pstring> t(psplit(replace_all(lt.substr(3), " ", ""), m_expr_sep));
auto val = static_cast<int>(expr(t, start, 255));
if (val == 0)
- m_ifflag |= (1 << m_level);
+ m_if_flag |= (1 << m_if_level);
}
else if (lti[0] == "#ifdef")
{
- m_level++;
+ m_if_level++;
if (get_define(lti[1]) == nullptr)
- m_ifflag |= (1 << m_level);
+ m_if_flag |= (1 << m_if_level);
}
else if (lti[0] == "#ifndef")
{
- m_level++;
+ m_if_level++;
if (get_define(lti[1]) != nullptr)
- m_ifflag |= (1 << m_level);
+ m_if_flag |= (1 << m_if_level);
}
else if (lti[0] == "#else")
{
- m_ifflag ^= (1 << m_level);
+ m_if_flag ^= (1 << m_if_level);
}
else if (lti[0] == "#endif")
{
- m_ifflag &= ~(1 << m_level);
- m_level--;
+ m_if_flag &= ~(1 << m_if_level);
+ m_if_level--;
}
else if (lti[0] == "#include")
{
@@ -508,7 +508,7 @@ pstring ppreprocessor::process_line(pstring line)
}
else if (lti[0] == "#pragma")
{
- if (m_ifflag == 0 && lti.size() > 3 && lti[1] == "NETLIST")
+ if (m_if_flag == 0 && lti.size() > 3 && lti[1] == "NETLIST")
{
if (lti[2] == "warning")
error("NETLIST: " + catremainder(lti, 3, " "));
@@ -516,7 +516,7 @@ pstring ppreprocessor::process_line(pstring line)
}
else if (lti[0] == "#define")
{
- if (m_ifflag == 0)
+ if (m_if_flag == 0)
{
if (lti.size() < 2)
error("PREPRO: define needs at least one argument: " + line);
@@ -534,14 +534,14 @@ pstring ppreprocessor::process_line(pstring line)
}
else
{
- if (m_ifflag == 0)
+ if (m_if_flag == 0)
error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line)));
}
}
else
{
lt = replace_macros(lt);
- if (m_ifflag == 0)
+ if (m_if_flag == 0)
ret += lt;
}
return ret;
diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h
index 3d4f18b3eb1..5332ee2518c 100644
--- a/src/lib/netlist/plib/pparser.h
+++ b/src/lib/netlist/plib/pparser.h
@@ -190,7 +190,7 @@ public:
{
m_lineno++;
line = process_line(line);
- m_buf += decltype(m_buf)(line.c_str()) + static_cast<char>(10);
+ m_outbuf += decltype(m_outbuf)(line.c_str()) + static_cast<char>(10);
}
return *this;
}
@@ -202,10 +202,10 @@ public:
: std::istream(new readbuffer(this))
, m_defines(std::move(s.m_defines))
, m_expr_sep(std::move(s.m_expr_sep))
- , m_ifflag(s.m_ifflag)
- , m_level(s.m_level)
+ , m_if_flag(s.m_if_flag)
+ , m_if_level(s.m_if_level)
, m_lineno(s.m_lineno)
- , m_buf(std::move(s.m_buf))
+ , m_outbuf(std::move(s.m_outbuf))
, m_pos(s.m_pos)
, m_state(s.m_state)
, m_comment(s.m_comment)
@@ -225,15 +225,14 @@ protected:
int_type underflow() override
{
- //printf("here\n");
if (this->gptr() == this->egptr())
{
/* clang reports sign error - weird */
- std::size_t bytes = pstring_mem_t_size(m_strm->m_buf) - static_cast<std::size_t>(m_strm->m_pos);
+ std::size_t bytes = pstring_mem_t_size(m_strm->m_outbuf) - static_cast<std::size_t>(m_strm->m_pos);
if (bytes > m_buf.size())
bytes = m_buf.size();
- std::copy(m_strm->m_buf.c_str() + m_strm->m_pos, m_strm->m_buf.c_str() + m_strm->m_pos + bytes, m_buf.data());
+ std::copy(m_strm->m_outbuf.c_str() + m_strm->m_pos, m_strm->m_outbuf.c_str() + m_strm->m_pos + bytes, m_buf.data());
//printf("%ld\n", (long int)bytes);
this->setg(m_buf.data(), m_buf.data(), m_buf.data() + bytes);
@@ -268,10 +267,10 @@ private:
defines_map_type m_defines;
std::vector<pstring> m_expr_sep;
- std::uint_least64_t m_ifflag; // 31 if levels
- int m_level;
+ std::uint_least64_t m_if_flag; // 31 if levels
+ int m_if_level;
int m_lineno;
- pstring_t<pu8_traits> m_buf;
+ pstring_t<pu8_traits> m_outbuf;
std::istream::pos_type m_pos;
state_e m_state;
pstring m_line;
diff --git a/src/lib/netlist/plib/ppmf.h b/src/lib/netlist/plib/ppmf.h
index 4ff49911d63..035606bb984 100644
--- a/src/lib/netlist/plib/ppmf.h
+++ b/src/lib/netlist/plib/ppmf.h
@@ -15,24 +15,24 @@
/*
*
- * NL_PMF_TYPE_GNUC_PMF
+ * PMF_TYPE_GNUC_PMF
* Use standard pointer to member function syntax C++11
*
- * NL_PMF_TYPE_GNUC_PMF_CONV
+ * PMF_TYPE_GNUC_PMF_CONV
* Use gnu extension and convert the pmf to a function pointer.
* This is not standard compliant and needs
* -Wno-pmf-conversions to compile.
*
- * NL_PMF_TYPE_INTERNAL
+ * PMF_TYPE_INTERNAL
* Use the same approach as MAME for deriving the function pointer.
* This is compiler-dependent as well
*
* Benchmarks for ./nltool -c run -f src/mame/machine/nl_pong.cpp -t 10 -n pong_fast
*
- * NL_PMF_TYPE_INTERNAL: 215% 215%
- * NL_PMF_TYPE_GNUC_PMF: 163% 196%
- * NL_PMF_TYPE_GNUC_PMF_CONV: 215% 215%
- * NL_PMF_TYPE_VIRTUAL: 213% 209%
+ * PMF_TYPE_INTERNAL: 215% 215%
+ * PMF_TYPE_GNUC_PMF: 163% 196%
+ * PMF_TYPE_GNUC_PMF_CONV: 215% 215%
+ * PMF_TYPE_VIRTUAL: 213% 209%
*
* The whole exercise was done to avoid virtual calls. In prior versions of
* netlist, the INTERNAL and GNUC_PMF_CONV approach provided significant improvement.
diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp
index 2eedc6b0371..359b61e247f 100644
--- a/src/lib/netlist/plib/pstring.cpp
+++ b/src/lib/netlist/plib/pstring.cpp
@@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
- * nl_string.c
+ * pstring.cpp
*
*/
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index c3c1c5fc7c6..adaa6a2b2fd 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -17,9 +17,9 @@
// noexcept on move operator -> issue with macosx clang
#define COPYASSIGNMOVE(name, def) \
name(const name &) = def; \
- name(name &&) /*noexcept*/ = def; \
+ name(name &&) noexcept = def; \
name &operator=(const name &) = def; \
- name &operator=(name &&) /*noexcept*/ = def;
+ name &operator=(name &&) noexcept = def;
#define COPYASSIGN(name, def) \
name(const name &) = def; \
@@ -36,14 +36,14 @@ namespace plib
template<> struct is_integral<INT128> { static constexpr bool value = true; };
template<> struct numeric_limits<UINT128>
{
- static constexpr UINT128 max()
+ static constexpr UINT128 max() noexcept
{
return ~((UINT128)0);
}
};
template<> struct numeric_limits<INT128>
{
- static constexpr INT128 max()
+ static constexpr INT128 max() noexcept
{
return (~((UINT128)0)) >> 1;
}
@@ -80,7 +80,7 @@ namespace plib
// Avoid unused variable warnings
//============================================================
template<typename... Ts>
- inline void unused_var(Ts&&...) {}
+ inline void unused_var(Ts&&...) noexcept {}
//============================================================
// is_pow2
@@ -100,7 +100,7 @@ namespace plib
template<typename T>
constexpr
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, T>::type
- abs(T v)
+ abs(T v) noexcept
{
return v < 0 ? -v : v;
}
@@ -108,14 +108,14 @@ namespace plib
template<typename T>
constexpr
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, T>::type
- abs(T v)
+ abs(T v) noexcept
{
return v;
}
template<typename M, typename N>
constexpr typename std::common_type<M, N>::type
- gcd(M m, N n)
+ gcd(M m, N n) noexcept
{
static_assert(std::is_integral<M>::value, "gcd: M must be an integer");
static_assert(std::is_integral<N>::value, "gcd: N must be an integer");
@@ -127,7 +127,7 @@ namespace plib
template<typename M, typename N>
constexpr typename std::common_type<M, N>::type
- lcm(M m, N n)
+ lcm(M m, N n) noexcept
{
static_assert(std::is_integral<M>::value, "lcm: M must be an integer");
static_assert(std::is_integral<N>::value, "lcm: N must be an integer");
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index 0692824b97c..ad2432647ec 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -31,7 +31,6 @@
#pragma GCC optimize "ivopts"
#endif
-#include "netlist/nl_lists.h"
#include "netlist/nl_factory.h"
#include "nld_matrix_solver.h"
#include "nld_ms_direct.h"