Wildmeshing Toolkit
Loading...
Searching...
No Matches
serial_priority_queue.hpp
1#pragma once
2
3#include <deque>
4#include <queue>
5#include <utility>
6#include <vector>
7
8namespace wmtk::threading {
9// ---------------------------------------------------------------------------
10// serial_priority_queue: the same (used) interface as concurrent_priority_queue,
11// minus the mutex, for queues that only ever have one thread touching them.
12//
13// The scheduler gives every task its own queue and only ever pops from, and pushes
14// renewed operations back into, that one queue; the single queue that genuinely
15// crosses threads is the overflow queue drained after the barrier. Paying for a
16// lock/unlock pair on every pop and every renewal of a thread-private heap is pure
17// overhead, so the private ones use this and only the shared one stays concurrent.
18//
19// Both are std::priority_queue underneath with the same comparator, so swapping one
20// for the other cannot change pop order.
21// ---------------------------------------------------------------------------
22template <typename T, typename Compare = std::less<T>>
24{
25 // A deque underneath, not a vector. std::priority_queue runs the same push_heap /
26 // pop_heap index arithmetic on either, so the heap layout -- and the pop order -- is
27 // identical; what changes is that a deque grows in fixed blocks instead of doubling.
28 // The queues are at their largest on the first pass after construction, when the mesh is
29 // too, and a vector there both carried up to 2x unused capacity and, at each doubling,
30 // held the old and the new buffer at once.
31 std::priority_queue<T, std::deque<T>, Compare> m_queue;
32
33public:
34 bool try_pop(T& out)
35 {
36 if (m_queue.empty()) {
37 return false;
38 }
39 out = m_queue.top();
40 m_queue.pop();
41 return true;
42 }
43
44 void push(const T& v) { m_queue.push(v); }
45
46 template <typename... Args>
47 void emplace(Args&&... args)
48 {
49 m_queue.emplace(std::forward<Args>(args)...);
50 }
51
52 std::size_t size() const { return m_queue.size(); }
53 bool empty() const { return m_queue.empty(); }
54};
55
56} // namespace wmtk::threading
Definition serial_priority_queue.hpp:24