diff options
author | 2017-02-25 10:43:49 +0100 | |
---|---|---|
committer | 2017-02-25 10:44:04 +0100 | |
commit | 1a2f928403c37f3cdf870ac340d0f1f71a7a0761 (patch) | |
tree | 92e1115632ef6573c4a344e8f106063f008b4c33 | |
parent | 418a0ee67de77959ca7adeee7768949d5731de6e (diff) |
Netlist refactoring
- align timed_queue closer to std::priority_queue
- use uint8_t in extended clock for better memory usage.
- minor changes to nl_breakout.cpp (nw)
-rw-r--r-- | src/lib/netlist/devices/nlid_system.h | 12 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 13 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 19 | ||||
-rw-r--r-- | src/lib/netlist/nl_lists.h | 168 | ||||
-rw-r--r-- | src/mame/machine/nl_breakout.cpp | 3 |
5 files changed, 107 insertions, 108 deletions
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 9d5d2ec5aef..a04b49c2440 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -119,7 +119,7 @@ namespace netlist , m_cnt(*this, "m_cnt", 0) , m_off(*this, "m_off", netlist_time::zero()) { - m_inc[0] = netlist_time::from_double(1.0 / (m_freq()*2.0)); + m_inc[0] = netlist_time::from_double(1.0 / (m_freq() * 2.0)); connect(m_feedback, m_Q); { @@ -127,8 +127,8 @@ namespace netlist std::vector<pstring> pat(plib::psplit(m_pattern(),",")); m_off = netlist_time::from_double(m_offset()); - unsigned long pati[256]; - m_size = pat.size(); + unsigned long pati[32]; + m_size = static_cast<std::uint8_t>(pat.size()); unsigned long total = 0; for (unsigned i=0; i<m_size; i++) { @@ -155,10 +155,10 @@ namespace netlist logic_input_t m_feedback; logic_output_t m_Q; - netlist_time m_inc[32]; - state_var<unsigned> m_cnt; + state_var<std::uint8_t> m_cnt; + std::uint8_t m_size; state_var<netlist_time> m_off; - std::size_t m_size; + netlist_time m_inc[32]; }; // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index e26aef72233..6905629ddd5 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -147,7 +147,7 @@ const logic_family_desc_t *family_CD4XXX() // ---------------------------------------------------------------------------------------- detail::queue_t::queue_t(netlist_t &nl) - : timed_queue<net_t *, netlist_time>(512) + : timed_queue<pqentry_t<net_t *, netlist_time>>(512) , netlist_ref(nl) , plib::state_manager_t::callback_t() , m_qsize(0) @@ -537,13 +537,15 @@ void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT if (m_mainclock == nullptr) { - detail::queue_t::entry_t e(m_queue.pop()); + detail::queue_t::entry_t e(m_queue.top()); + m_queue.pop(); m_time = e.m_exec_time; while (e.m_object != nullptr) { e.m_object->update_devs(); m_perf_out_processed.inc(); - e = m_queue.pop(); + e = m_queue.top(); + m_queue.pop(); m_time = e.m_exec_time; } } @@ -565,7 +567,8 @@ void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT mc_time += inc; } - e = m_queue.pop(); + e = m_queue.top(); + m_queue.pop(); m_time = e.m_exec_time; if (e.m_object != nullptr) { @@ -780,9 +783,9 @@ detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) , 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", QS_DELIVERED) , m_time(*this, "m_time", netlist_time::zero()) , m_active(*this, "m_active", 0) - , m_in_queue(*this, "m_in_queue", QS_DELIVERED) , m_cur_Analog(*this, "m_cur_Analog", 0.0) , m_railterminal(mr) { diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index f8f6189f5b9..002d02869ed 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -320,11 +320,15 @@ namespace netlist //! Copy Constructor. state_var(const state_var &rhs) NL_NOEXCEPT = default; //! Move Constructor. - state_var(state_var &&rhs) NL_NOEXCEPT = default; + state_var(state_var &&rhs) NL_NOEXCEPT { std::swap(m_value, rhs.m_value); } //! Assignment operator to assign value of a state var. - state_var &operator=(const state_var &rhs) NL_NOEXCEPT { m_value = rhs; return *this; } + state_var &operator=(const state_var &rhs) NL_NOEXCEPT { m_value = rhs.m_value; return *this; } + //! Assignment move operator to assign value of a state var. + state_var &operator=(state_var &&rhs) NL_NOEXCEPT { std::swap(m_value, rhs.m_value); return *this; } //! Assignment operator to assign value of type T. state_var &operator=(const T &rhs) NL_NOEXCEPT { m_value = rhs; return *this; } + //! Assignment move operator to assign value of type T. + state_var &operator=(T &&rhs) NL_NOEXCEPT { std::swap(m_value, rhs); return *this; } //! Return value of state variable. operator T & () NL_NOEXCEPT { return m_value; } //! Return const value of state variable. @@ -716,8 +720,8 @@ namespace netlist void update_devs() NL_NOEXCEPT; - netlist_time time() const NL_NOEXCEPT { return m_time; } - void set_time(const netlist_time ntime) NL_NOEXCEPT { m_time = ntime; } + const netlist_time &time() const NL_NOEXCEPT { return m_time; } + void set_time(const netlist_time &ntime) NL_NOEXCEPT { m_time = ntime; } bool isRailNet() const { return !(m_railterminal == nullptr); } core_terminal_t & railterminal() const { return *m_railterminal; } @@ -743,10 +747,10 @@ namespace netlist protected: state_var<netlist_sig_t> m_new_Q; state_var<netlist_sig_t> m_cur_Q; + state_var<queue_status> m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ state_var<netlist_time> m_time; state_var_s32 m_active; - state_var<queue_status> m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ state_var<nl_double> m_cur_Analog; @@ -1174,11 +1178,12 @@ namespace netlist // ----------------------------------------------------------------------------- class detail::queue_t : - public timed_queue<net_t *, netlist_time>, + public timed_queue<pqentry_t<net_t *, netlist_time>>, public detail::netlist_ref, public plib::state_manager_t::callback_t { public: + typedef pqentry_t<net_t *, netlist_time> entry_t; explicit queue_t(netlist_t &nl); protected: @@ -1214,7 +1219,7 @@ namespace netlist nl_double gmin() const; void process_queue(const netlist_time &delta) NL_NOEXCEPT; - void abort_current_queue_slice() { m_queue.retime(nullptr, m_time); } + void abort_current_queue_slice() { m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); } /* Control functions */ diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index 8417d1231dc..61fb03d3ec9 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -49,43 +49,64 @@ namespace netlist void unlock() const noexcept { } }; -#if !USE_HEAP template <class Element, class Time> - class timed_queue : plib::nocopyassignmove + struct pqentry_t final { - public: + 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) { } + constexpr pqentry_t(const pqentry_t &e) noexcept : m_exec_time(e.m_exec_time), m_object(e.m_object) { } + pqentry_t(pqentry_t &&e) noexcept { swap(e); } + ~pqentry_t() = default; + + pqentry_t& operator=(pqentry_t && other) noexcept + { + swap(other); + return *this; + } + + pqentry_t& operator=(const pqentry_t &other) noexcept + { + pqentry_t t(other); + swap(t); + return *this; + } - struct entry_t final + void swap(pqentry_t &other) noexcept { - constexpr entry_t() noexcept : m_exec_time(), m_object(nullptr) { } - constexpr entry_t(const Time &t, const Element &o) noexcept : m_exec_time(t), m_object(o) { } - constexpr entry_t(const entry_t &e) noexcept : m_exec_time(e.m_exec_time), m_object(e.m_object) { } - entry_t(entry_t &&e) noexcept { swap(e); } - ~entry_t() = default; + std::swap(m_exec_time, other.m_exec_time); + std::swap(m_object, other.m_object); + } - entry_t& operator=(entry_t && other) noexcept + struct QueueOp + { + static constexpr bool less(const pqentry_t &lhs, const pqentry_t &rhs) noexcept { - swap(other); - return *this; + return (lhs.m_exec_time < rhs.m_exec_time); } - entry_t& operator=(const entry_t &other) noexcept + static constexpr bool equal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept { - entry_t t(other); - swap(t); - return *this; + return lhs.m_object == rhs.m_object; } - void swap(entry_t &other) noexcept + static constexpr bool equal(const pqentry_t &lhs, const Element &rhs) noexcept { - std::swap(m_exec_time, other.m_exec_time); - std::swap(m_object, other.m_object); + return lhs.m_object == rhs; } - Time m_exec_time; - Element m_object; + static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); } }; + Time m_exec_time; + Element m_object; + }; + +#if !USE_HEAP + template <class T, class QueueOp = typename T::QueueOp> + class timed_queue : plib::nocopyassignmove + { + public: + timed_queue(const std::size_t list_size) : m_list(list_size) { @@ -95,12 +116,12 @@ namespace netlist constexpr std::size_t capacity() const noexcept { return m_list.capacity() - 1; } constexpr bool empty() const noexcept { return (m_end == &m_list[1]); } - void push(entry_t &&e) noexcept + void push(T &&e) noexcept { /* Lock */ tqlock lck(m_lock); - entry_t * i = m_end; - for (; e.m_exec_time > (i - 1)->m_exec_time; --i) + T * i = m_end; + for (; QueueOp::less(*(i - 1), e); --i) { *(i) = *(i-1); m_prof_sortmove.inc(); @@ -110,16 +131,17 @@ namespace netlist m_prof_call.inc(); } - entry_t pop() noexcept { return *(--m_end); } - const entry_t &top() const noexcept { return *(m_end-1); } + void pop() noexcept { --m_end; } + const T &top() const noexcept { return *(m_end-1); } - void remove(const Element &elem) noexcept + template <class R> + void remove(const R &elem) noexcept { /* Lock */ tqlock lck(m_lock); - for (entry_t * i = m_end - 1; i > &m_list[0]; i--) + for (T * i = m_end - 1; i > &m_list[0]; i--) { - if (i->m_object == elem) + if (QueueOp::equal(*i, elem)) { m_end--; for (;i < m_end; i++) @@ -129,21 +151,21 @@ namespace netlist } } - void retime(const Element &elem, const Time t) noexcept + void retime(const T &elem) noexcept { /* Lock */ tqlock lck(m_lock); - for (entry_t * i = m_end - 1; i > &m_list[0]; i--) + for (T * i = m_end - 1; i > &m_list[0]; i--) { - if (i->m_object == elem) + if (QueueOp::equal(*i, elem)) // partial equal! { - i->m_exec_time = t; - while ((i-1)->m_exec_time < i->m_exec_time) + *i = elem; + while (QueueOp::less(*(i-1), *i)) { std::swap(*(i-1), *i); i--; } - while (i < m_end && (i+1)->m_exec_time > i->m_exec_time) + while (i < m_end && QueueOp::less(*i, *(i+1))) { std::swap(*(i+1), *i); i++; @@ -161,15 +183,15 @@ namespace netlist * the insert algo above will run into this element and doesn't * need a comparison with queue start. */ - m_list[0] = { Time::never(), Element(0) }; + m_list[0] = QueueOp::never(); m_end++; } // save state support & mame disasm - constexpr const entry_t *listptr() const { return &m_list[1]; } + constexpr const T *listptr() const { return &m_list[1]; } constexpr std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); } - constexpr const entry_t & operator[](const std::size_t index) const { return m_list[ 1 + index]; } + constexpr const T & operator[](const std::size_t index) const { return m_list[ 1 + index]; } private: #if HAS_OPENMP && USE_OPENMP using tqmutex = pspin_mutex<true>; @@ -179,8 +201,8 @@ namespace netlist using tqlock = std::lock_guard<tqmutex>; tqmutex m_lock; - entry_t * m_end; - std::vector<entry_t> m_list; + T * m_end; + std::vector<T> m_list; public: // profiling @@ -188,45 +210,14 @@ namespace netlist nperfcount_t m_prof_call; }; #else - template <class Element, class Time> + template <class T, class QueueOp = typename T::QueueOp> class timed_queue : plib::nocopyassignmove { public: - struct entry_t final - { - constexpr entry_t() noexcept : m_exec_time(), m_object(nullptr) { } - constexpr entry_t(const Time &t, const Element &o) noexcept : m_exec_time(t), m_object(o) { } - constexpr entry_t(const entry_t &e) noexcept : m_exec_time(e.m_exec_time), m_object(e.m_object) { } - entry_t(entry_t &&e) noexcept { swap(e); } - ~entry_t() = default; - - entry_t& operator=(entry_t && other) noexcept - { - swap(other); - return *this; - } - - entry_t& operator=(const entry_t &other) noexcept - { - entry_t t(other); - swap(t); - return *this; - } - - void swap(entry_t &other) noexcept - { - std::swap(m_exec_time, other.m_exec_time); - std::swap(m_object, other.m_object); - } - - Time m_exec_time; - Element m_object; - }; - struct compare { - bool operator()(const entry_t &a, const entry_t &b) { return a.m_exec_time > b.m_exec_time; } + bool operator()(const T &a, const T &b) { return QueueOp::less(b,a); } }; timed_queue(const std::size_t list_size) @@ -238,7 +229,7 @@ namespace netlist constexpr std::size_t capacity() const noexcept { return m_list.capacity(); } constexpr bool empty() const noexcept { return &m_list[0] == m_end; } - void push(entry_t &&e) noexcept + void push(T &&e) noexcept { /* Lock */ tqlock lck(m_lock); @@ -247,23 +238,22 @@ namespace netlist m_prof_call.inc(); } - entry_t pop() noexcept + void pop() noexcept { - entry_t t(m_list[0]); std::pop_heap(&m_list[0], m_end, compare()); m_end--; - return t; } - const entry_t &top() const noexcept { return m_list[0]; } + const T &top() const noexcept { return m_list[0]; } - void remove(const Element &elem) noexcept + template <class R> + void remove(const R &elem) noexcept { /* Lock */ tqlock lck(m_lock); - for (entry_t * i = m_end - 1; i >= &m_list[0]; i--) + for (T * i = m_end - 1; i >= &m_list[0]; i--) { - if (i->m_object == elem) + if (QueueOp::equal(*i, elem)) { m_end--; for (;i < m_end; i++) @@ -274,15 +264,15 @@ namespace netlist } } - void retime(const Element &elem, const Time t) noexcept + void retime(const T &elem) noexcept { /* Lock */ tqlock lck(m_lock); - for (entry_t * i = m_end - 1; i >= &m_list[0]; i--) + for (T * i = m_end - 1; i >= &m_list[0]; i--) { - if (i->m_object == elem) + if (QueueOp::equal(*i, elem)) // partial equal! { - i->m_exec_time = t; + *i = elem; std::make_heap(&m_list[0], m_end, compare()); return; } @@ -298,9 +288,9 @@ namespace netlist // save state support & mame disasm - constexpr const entry_t *listptr() const { return &m_list[0]; } + constexpr const T *listptr() const { return &m_list[0]; } constexpr std::size_t size() const noexcept { return m_list.size(); } - constexpr const entry_t & operator[](const std::size_t index) const { return m_list[ 0 + index]; } + constexpr const T & operator[](const std::size_t index) const { return m_list[ 0 + index]; } private: #if HAS_OPENMP && USE_OPENMP using tqmutex = pspin_mutex<true>; @@ -310,8 +300,8 @@ namespace netlist using tqlock = std::lock_guard<tqmutex>; tqmutex m_lock; - std::vector<entry_t> m_list; - entry_t *m_end; + std::vector<T> m_list; + T *m_end; public: // profiling diff --git a/src/mame/machine/nl_breakout.cpp b/src/mame/machine/nl_breakout.cpp index 8fc703e105a..30a9934fe1b 100644 --- a/src/mame/machine/nl_breakout.cpp +++ b/src/mame/machine/nl_breakout.cpp @@ -91,6 +91,7 @@ CIRCUIT_LAYOUT( breakout ) #if (SLOW_BUT_ACCURATE) SOLVER(Solver, 48000) PARAM(Solver.ACCURACY, 1e-8) // less accuracy and diode will not work + PARAM(Solver.METHOD, "MAT_CR") #else SOLVER(Solver, 48000) PARAM(Solver.ACCURACY, 1e-6) @@ -128,7 +129,7 @@ CIRCUIT_LAYOUT( breakout ) //---------------------------------------------------------------- // Clock circuit //---------------------------------------------------------------- -#if 0 || (SLOW_BUT_ACCURATE) +#if (SLOW_BUT_ACCURATE) MAINCLOCK(Y1, 14318000.0) CHIP("F1", 9316) NET_C(Y1.Q, F1.2) |