Semaphore is a portable way to park/unpark threads.
The plan is to use it to implement a portable blocking
mutex in subsequent changes. Semaphore can also be used
to efficiently wait for other things (e.g. we currently
spin to synchronize thread creation and start).
Details
- Reviewers
vitalybuka melver - Commits
- rG6a4054ef060b: sanitizer_common: add Semaphore
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I've separated this from actual mutex implementation because this contains lots of OS-dependent code, which has higher risks of breaking things and being reverted. So I want to land and secure this first.
Looking into adding tests.
FTR the mutex change that uses this semaphore is implemented here:
https://github.com/dvyukov/llvm-project/pull/3/files
(but it's a huge uncleaned change that I am slowly merging)
compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp | ||
---|---|---|
512 | So we just spin here? | |
compiler-rt/lib/sanitizer_common/sanitizer_mutex.cpp | ||
22–34 | isn't this the same? void Semaphore::Wait() { for(;;) { u32 count = atomic_load(&state_, memory_order_relaxed); if (count == 0) { FutexWait(&state_, 0); continue; } if (atomic_compare_exchange_weak(&state_, &count, count - 1, memory_order_acquire)) break; }; } |
compiler-rt/lib/sanitizer_common/sanitizer_mutex.cpp | ||
---|---|---|
38 | Do we care if count==0? My guess is we probably don't, but just checking. | |
compiler-rt/lib/sanitizer_common/sanitizer_mutex.h | ||
77 | Depending on how early they should be initialized, it might be worth it to make this a constexpr constructor. Probably would mean inline initializing state_ below. | |
compiler-rt/lib/tsan/go/buildgo.sh | ||
31 | s/ /\t/ |
addressed comments
compiler-rt/lib/sanitizer_common/sanitizer_mutex.cpp | ||
---|---|---|
22–34 | It's subtly different. | |
38 | Added CHECK_NE(count, 0). Callers should not increment by 0. |
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp | ||
---|---|---|
817 | This adds a dependency on API-MS-Win-Core-Synch-l1-2-0.dll, which according to https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress is only available on Windows 8 and later. This is a problem for Chrome, which still supports Windows 7. Is there some way this could be done without depending on a new API? See https://bugs.chromium.org/p/chromium/issues/detail?id=1236586 |
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp | ||
---|---|---|
817 | Actually, Reid pointed out to me that I'm wrong about shipping Chrome/ASan builds anywhere outside our own testing infrastructure, in which case this is not a problem. |
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp | ||
---|---|---|
817 | Does Chrome need to support Windows 7 _with_ TSAN? I assume TSAN build is only used by few developers and on bots. |
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp | ||
---|---|---|
817 | I thought we shipped our ASan builds to some small subset of users, but it turns out I was mistaken. Sorry for the noise. |
There's a bug report https://github.com/llvm/llvm-project/issues/63786 mentioning Windows 7; I guess it's the same WaitOnAddress thing discussed previously? Maybe someone can reply on the bug report.
So we just spin here?
maybe TODO?