Skip to content

Commit f8b54d9

Browse files
committed
Work around missing notify / wait on std::atomic
1 parent 8452782 commit f8b54d9

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

spinlock.h

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
#include "visibility.h"
22
#include <atomic>
3+
#include <chrono>
34
#include <mutex>
5+
#include <thread>
6+
7+
8+
// Not all supported targets implement the wait / notify instructions on
9+
// atomics. Provide simple spinning fallback for ones that don't.
10+
template<typename T>
11+
concept Waitable = requires(T t)
12+
{
13+
t.notify_all();
14+
};
415

516
/**
617
* Lightweight spinlock that falls back to using the operating system's futex
@@ -20,6 +31,35 @@ class ThinLock
2031
};
2132
// The lock word
2233
std::atomic<LockState> lockWord;
34+
35+
// Call notify if it exists
36+
template<typename T>
37+
static void notify(T &atomic) requires (Waitable<T>)
38+
{
39+
atomic.notify_all();
40+
}
41+
42+
// Simply ignore notify if we don't have one.
43+
template<typename T>
44+
static void notify(T &atomic) requires (!Waitable<T>)
45+
{
46+
}
47+
48+
// Wait if we have a wait method.
49+
template<typename T>
50+
static void wait(T &atomic, LockState expected) requires (Waitable<T>)
51+
{
52+
atomic.wait(expected);
53+
}
54+
55+
// Short sleep if we don't.
56+
template<typename T>
57+
static void wait(T &atomic, LockState expected) requires (!Waitable<T>)
58+
{
59+
using namespace std::chrono_literals;
60+
std::this_thread::sleep_for(1ms);
61+
}
62+
2363
public:
2464
// Acquire the lock
2565
void lock()
@@ -41,7 +81,7 @@ class ThinLock
4181
continue;
4282
}
4383
}
44-
lockWord.wait(LockState::LockedWithWaiters);
84+
wait(lockWord, LockState::LockedWithWaiters);
4585
}
4686
}
4787

@@ -51,7 +91,7 @@ class ThinLock
5191
auto old = lockWord.exchange(LockState::Unlocked);
5292
if (old == LockState::LockedWithWaiters)
5393
{
54-
lockWord.notify_all();
94+
notify(lockWord);
5595
}
5696
}
5797

0 commit comments

Comments
 (0)