@@ -42,7 +42,28 @@ class sequence {
42
42
T* head_;
43
43
};
44
44
45
- template <typename T,typename Mutex = std::mutex>
45
+ class spin_lock {
46
+ public:
47
+ void lock ()noexcept {
48
+ while (flag_.test_and_set (std::memory_order_acquire)) {
49
+ #if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L
50
+ flag_.wait (true , std::memory_order_relaxed);
51
+ #endif
52
+ }
53
+ }
54
+
55
+ void unlock ()noexcept {
56
+ flag_.clear (std::memory_order_release);
57
+ #if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L
58
+ flag_.notify_one ();
59
+ #endif
60
+ }
61
+
62
+ private:
63
+ std::atomic_flag flag_ = ATOMIC_FLAG_INIT;
64
+ };
65
+
66
+ template <typename T,typename Mutex = spin_lock>
46
67
class queue {
47
68
public:
48
69
sequence<T>extract () {
@@ -113,7 +134,7 @@ class mpsc_stack {
113
134
114
135
sequence<T>extract ()noexcept {
115
136
do {
116
- T* top = head_.load ();
137
+ T* top = head_.load (std::memory_order_relaxed );
117
138
118
139
if (top ==nullptr ) {
119
140
return sequence<T>{nullptr };
@@ -126,7 +147,7 @@ class mpsc_stack {
126
147
127
148
void push (T*const node)noexcept {
128
149
do {
129
- T* top = head_.load ();
150
+ T* top = head_.load (std::memory_order_relaxed );
130
151
node->next = top;
131
152
if (head_.compare_exchange_weak (top, node)) {
132
153
return ;
@@ -142,17 +163,17 @@ class mpsc_stack {
142
163
143
164
T*pop ()noexcept {
144
165
do {
145
- T* top = head_.load ();
146
-
166
+ T* top = head_.load (std::memory_order_consume );
167
+ // Check the stack is empty.
147
168
if (top ==nullptr ) {
148
169
return nullptr ;
149
- }else {
150
- T* next = top->next ;
170
+ }
151
171
152
- if (head_.compare_exchange_weak (top, next)) {
153
- top->next =nullptr ;
154
- return top;
155
- }
172
+ T* next = top->next ;
173
+ // Pop the item.
174
+ if (head_.compare_exchange_weak (top, next)) {
175
+ top->next =nullptr ;
176
+ return top;
156
177
}
157
178
}while (true );
158
179
}