diff options
author | Siva Chandra Reddy <sivachandra@google.com> | 2021-08-21 04:46:32 +0000 |
---|---|---|
committer | Siva Chandra Reddy <sivachandra@google.com> | 2021-08-23 05:47:30 +0000 |
commit | 8e488c3cc0da71afbe75963033e86bf32ee56c11 (patch) | |
tree | 8f52fbafa41a21e1e9dfc23887d8cd23776488d2 /libc/src/threads/linux | |
parent | 175139b6fd59f62d4ecbabde3906f88236a293fa (diff) | |
download | llvm-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.cpp | 8 |
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: |