aboutsummaryrefslogtreecommitdiff
path: root/libc/src/threads/linux
diff options
context:
space:
mode:
authorSiva Chandra Reddy <sivachandra@google.com>2021-08-21 04:46:32 +0000
committerSiva Chandra Reddy <sivachandra@google.com>2021-08-23 05:47:30 +0000
commit8e488c3cc0da71afbe75963033e86bf32ee56c11 (patch)
tree8f52fbafa41a21e1e9dfc23887d8cd23776488d2 /libc/src/threads/linux
parent175139b6fd59f62d4ecbabde3906f88236a293fa (diff)
downloadllvm-8e488c3cc0da71afbe75963033e86bf32ee56c11.zip
llvm-8e488c3cc0da71afbe75963033e86bf32ee56c11.tar.gz
llvm-8e488c3cc0da71afbe75963033e86bf32ee56c11.tar.bz2
[libc] Add a multi-waiter mutex test.
A corresponding adjustment to mtx_lock has also been made.
Diffstat (limited to 'libc/src/threads/linux')
-rw-r--r--libc/src/threads/linux/mtx_lock.cpp8
1 files changed, 7 insertions, 1 deletions
diff --git a/libc/src/threads/linux/mtx_lock.cpp b/libc/src/threads/linux/mtx_lock.cpp
index 7ae30a7..39bd329 100644
--- a/libc/src/threads/linux/mtx_lock.cpp
+++ b/libc/src/threads/linux/mtx_lock.cpp
@@ -21,12 +21,16 @@ namespace __llvm_libc {
// The implementation currently handles only plain mutexes.
LLVM_LIBC_FUNCTION(int, mtx_lock, (mtx_t * mutex)) {
FutexData *futex_data = reinterpret_cast<FutexData *>(mutex->__internal_data);
+ bool was_waiting = false;
while (true) {
uint32_t mutex_status = MS_Free;
uint32_t locked_status = MS_Locked;
- if (atomic_compare_exchange_strong(futex_data, &mutex_status, MS_Locked))
+ if (atomic_compare_exchange_strong(futex_data, &mutex_status, MS_Locked)) {
+ if (was_waiting)
+ atomic_store(futex_data, MS_Waiting);
return thrd_success;
+ }
switch (mutex_status) {
case MS_Waiting:
@@ -35,6 +39,7 @@ LLVM_LIBC_FUNCTION(int, mtx_lock, (mtx_t * mutex)) {
// 4th argument to the syscall function below.)
__llvm_libc::syscall(SYS_futex, futex_data, FUTEX_WAIT_PRIVATE,
MS_Waiting, 0, 0, 0);
+ was_waiting = true;
// Once woken up/unblocked, try everything all over.
continue;
case MS_Locked:
@@ -47,6 +52,7 @@ LLVM_LIBC_FUNCTION(int, mtx_lock, (mtx_t * mutex)) {
// syscall will block only if the futex data is still `MS_Waiting`.
__llvm_libc::syscall(SYS_futex, futex_data, FUTEX_WAIT_PRIVATE,
MS_Waiting, 0, 0, 0);
+ was_waiting = true;
}
continue;
case MS_Free: