summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/nl_lists.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/nl_lists.h')
-rw-r--r--src/lib/netlist/nl_lists.h120
1 files changed, 65 insertions, 55 deletions
diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h
index f4b1c4e8ff5..27db664cc05 100644
--- a/src/lib/netlist/nl_lists.h
+++ b/src/lib/netlist/nl_lists.h
@@ -69,37 +69,34 @@ namespace netlist
std::swap(m_object, other.m_object);
}
#endif
- struct QueueOp
+ inline bool operator ==(const pqentry_t &rhs) const noexcept
{
- inline static constexpr bool less(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
- {
- return (lhs.m_exec_time < rhs.m_exec_time);
- }
+ return m_object == rhs.m_object;
+ }
- inline static constexpr bool lessequal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
- {
- return (lhs.m_exec_time <= rhs.m_exec_time);
- }
+ inline bool operator ==(const Element &rhs) const noexcept
+ {
+ return m_object == rhs;
+ }
- inline static constexpr bool equal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
- {
- return lhs.m_object == rhs.m_object;
- }
+ inline bool operator <=(const pqentry_t &rhs) const noexcept
+ {
+ return (m_exec_time <= rhs.m_exec_time);
+ }
- inline static constexpr bool equal(const pqentry_t &lhs, const Element &rhs) noexcept
- {
- return lhs.m_object == rhs;
- }
+ inline bool operator <(const pqentry_t &rhs) const noexcept
+ {
+ return (m_exec_time < rhs.m_exec_time);
+ }
- inline static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); }
- };
+ inline static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); }
Time m_exec_time;
Element m_object;
};
/* Use TS = true for a threadsafe queue */
- template <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
+ template <class T, bool TS>
class timed_queue_linear : plib::nocopyassignmove
{
public:
@@ -113,28 +110,31 @@ namespace netlist
std::size_t capacity() const noexcept { return m_list.capacity() - 1; }
bool empty() const noexcept { return (m_end == &m_list[1]); }
+ template<bool KEEPSTAT>
void push(T && e) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
T * i(m_end-1);
- for (; QueueOp::less(*(i), e); --i)
+ for (; *i < e; --i)
{
*(i+1) = *(i);
- m_prof_sortmove.inc();
+ if (KEEPSTAT)
+ m_prof_sortmove.inc();
}
*(i+1) = std::move(e);
++m_end;
- m_prof_call.inc();
+ if (KEEPSTAT)
+ m_prof_call.inc();
}
- void push_nostats(T && e) noexcept
+ void push_nostatsx(T && e) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
#if 1
T * i(m_end-1);
- for (; QueueOp::less(*(i), e); --i)
+ for (; *i < e; --i)
{
*(i+1) = *(i);
}
@@ -153,22 +153,18 @@ namespace netlist
T pop() noexcept { return *(--m_end); }
const T &top() const noexcept { return *(m_end-1); }
- template <class R>
+ template <bool KEEPSTAT, class R>
void remove(const R &elem) noexcept
{
- m_prof_remove.inc();
- remove_nostats(elem);
- }
-
- template <class R>
- void remove_nostats(const R &elem) noexcept
- {
/* Lock */
lock_guard_type lck(m_lock);
+ if (KEEPSTAT)
+ m_prof_remove.inc();
#if 1
for (T * i = m_end - 1; i > &m_list[0]; --i)
{
- if (QueueOp::equal(*i, elem))
+ // == operator ignores time!
+ if (*i == elem)
{
std::copy(i+1, m_end--, i);
return;
@@ -186,23 +182,25 @@ namespace netlist
#endif
}
- void retime(T && elem) noexcept
+ template <bool KEEPSTAT, class R>
+ void retime(R && elem) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
- m_prof_retime.inc();
+ if (KEEPSTAT)
+ m_prof_retime.inc();
- for (T * i = m_end - 1; i > &m_list[0]; --i)
+ for (R * i = m_end - 1; i > &m_list[0]; --i)
{
- if (QueueOp::equal(*i, elem)) // partial equal!
+ if (*i == elem) // partial equal!
{
*i = std::move(elem);
- while (QueueOp::less(*(i-1), *i))
+ while (*(i-1) < *i)
{
std::swap(*(i-1), *i);
--i;
}
- while (i < m_end && QueueOp::less(*i, *(i+1)))
+ while (i < m_end && *i < *(i+1))
{
std::swap(*(i+1), *i);
++i;
@@ -220,7 +218,7 @@ namespace netlist
* the insert algo above will run into this element and doesn't
* need a comparison with queue start.
*/
- m_list[0] = QueueOp::never();
+ m_list[0] = T::never();
m_end++;
}
@@ -241,20 +239,20 @@ namespace netlist
public:
// profiling
- nperfcount_t<KEEPSTAT> m_prof_sortmove;
- nperfcount_t<KEEPSTAT> m_prof_call;
- nperfcount_t<KEEPSTAT> m_prof_remove;
- nperfcount_t<KEEPSTAT> m_prof_retime;
+ nperfcount_t<true> m_prof_sortmove;
+ nperfcount_t<true> m_prof_call;
+ nperfcount_t<true> m_prof_remove;
+ nperfcount_t<true> m_prof_retime;
};
- template <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
+ template <class T, bool TS>
class timed_queue_heap : plib::nocopyassignmove
{
public:
struct compare
{
- constexpr bool operator()(const T &a, const T &b) const { return QueueOp::lessequal(b,a); }
+ constexpr bool operator()(const T &a, const T &b) const { return b <= a; }
};
explicit timed_queue_heap(const std::size_t list_size)
@@ -266,13 +264,15 @@ namespace netlist
std::size_t capacity() const noexcept { return m_list.capacity(); }
bool empty() const noexcept { return &m_list[0] == m_end; }
+ template <bool KEEPSTAT>
void push(T &&e) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
*m_end++ = e;
std::push_heap(&m_list[0], m_end, compare());
- m_prof_call.inc();
+ if (KEEPSTAT)
+ m_prof_call.inc();
}
T pop() noexcept
@@ -285,14 +285,16 @@ namespace netlist
const T &top() const noexcept { return m_list[0]; }
- template <class R>
+ template <bool KEEPSTAT, class R>
void remove(const R &elem) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
+ if (KEEPSTAT)
+ m_prof_remove.inc();
for (T * i = m_end - 1; i >= &m_list[0]; i--)
{
- if (QueueOp::equal(*i, elem))
+ if (*i == elem)
{
m_end--;
for (;i < m_end; i++)
@@ -303,13 +305,16 @@ namespace netlist
}
}
+ template <bool KEEPSTAT>
void retime(const T &elem) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
+ if (KEEPSTAT)
+ m_prof_retime.inc();
for (T * i = m_end - 1; i >= &m_list[0]; i--)
{
- if (QueueOp::equal(*i, elem)) // partial equal!
+ if (*i == elem) // partial equal!
{
*i = elem;
std::make_heap(&m_list[0], m_end, compare());
@@ -340,18 +345,23 @@ namespace netlist
public:
// profiling
- nperfcount_t<KEEPSTAT> m_prof_sortmove;
- nperfcount_t<KEEPSTAT> m_prof_call;
+ nperfcount_t<true> m_prof_sortmove;
+ nperfcount_t<true> m_prof_call;
+ nperfcount_t<true> m_prof_remove;
+ nperfcount_t<true> m_prof_retime;
};
+ template <class T, bool TS>
+ using timed_queue = timed_queue_linear<T, TS>;
+
/*
* Use timed_queue_heap to use stdc++ heap functions instead of linear processing.
*
* This slows down processing by about 25% on a Kaby Lake.
*/
- template <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
- using timed_queue = timed_queue_linear<T, TS, KEEPSTAT, QueueOp>;
+ //template <class T, bool TS>
+ //using timed_queue = timed_queue_heap<T, TS>;
} // namespace netlist