diff options
author | Siva Chandra Reddy <sivachandra@google.com> | 2022-03-01 08:54:46 +0000 |
---|---|---|
committer | Siva Chandra Reddy <sivachandra@google.com> | 2022-03-01 17:12:39 +0000 |
commit | 75747c73946546fb9f9163b9a813b54f96874948 (patch) | |
tree | 50f5defbb40f1c5d901816be27ff62328b2a8938 /libc/src/threads/linux | |
parent | c809c9bd3b75962c9fc7ab90c8e90d3be317b43b (diff) | |
download | llvm-75747c73946546fb9f9163b9a813b54f96874948.zip llvm-75747c73946546fb9f9163b9a813b54f96874948.tar.gz llvm-75747c73946546fb9f9163b9a813b54f96874948.tar.bz2 |
[libc] Remove the remaining uses of stdatomic.h.
New methods to the Atomic class have been added as required. Futex
related types have been consolidated at a common place.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D120705
Diffstat (limited to 'libc/src/threads/linux')
-rw-r--r-- | libc/src/threads/linux/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libc/src/threads/linux/Futex.h | 21 | ||||
-rw-r--r-- | libc/src/threads/linux/Mutex.h | 10 | ||||
-rw-r--r-- | libc/src/threads/linux/Thread.h | 1 | ||||
-rw-r--r-- | libc/src/threads/linux/call_once.cpp | 31 | ||||
-rw-r--r-- | libc/src/threads/linux/thrd_create.cpp | 8 | ||||
-rw-r--r-- | libc/src/threads/linux/thrd_join.cpp | 19 |
7 files changed, 48 insertions, 44 deletions
diff --git a/libc/src/threads/linux/CMakeLists.txt b/libc/src/threads/linux/CMakeLists.txt index d25b23c..6fdca98 100644 --- a/libc/src/threads/linux/CMakeLists.txt +++ b/libc/src/threads/linux/CMakeLists.txt @@ -18,6 +18,7 @@ add_entrypoint_object( .threads_utils libc.include.sys_syscall libc.include.threads + libc.src.__support.CPP.atomic libc.src.__support.OSUtil.osutil ) @@ -67,6 +68,7 @@ add_entrypoint_object( .threads_utils libc.include.sys_syscall libc.include.threads + libc.src.__support.CPP.atomic libc.src.__support.common libc.src.__support.OSUtil.osutil libc.src.sys.mman.munmap diff --git a/libc/src/threads/linux/Futex.h b/libc/src/threads/linux/Futex.h index e80816f..fab1b6d 100644 --- a/libc/src/threads/linux/Futex.h +++ b/libc/src/threads/linux/Futex.h @@ -9,19 +9,22 @@ #ifndef LLVM_LIBC_SRC_THREADS_LINUX_FUTEX_H #define LLVM_LIBC_SRC_THREADS_LINUX_FUTEX_H -#include <stdatomic.h> +#include "src/__support/architectures.h" // Architecture macros namespace __llvm_libc { +#if (defined(LLVM_LIBC_ARCH_AARCH64) || defined(LLVM_LIBC_ARCH_X86_64)) // The futex data has to be exactly 4 bytes long. However, we use a uint type -// here as we do not want to use `_Atomic uint32_t` as the _Atomic keyword which -// is C only. The header stdatomic.h does not define an atomic type -// corresponding to `uint32_t` or to something which is exactly 4 bytes wide. -using FutexWord = atomic_uint; -static_assert(sizeof(atomic_uint) == 4, - "Size of the `atomic_uint` type is not 4 bytes on your platform. " - "The implementation of the standard threads library for linux " - "requires that size of `atomic_uint` be 4 bytes."); +// here as we do not want to use `uint32_t` type to match the public definitions +// of types which include a field for a futex word. With public definitions, we +// cannot include <stdint.h> so we stick to the `unsigned int` type for x86_64 +// and aarch64 +using FutexWordType = unsigned int; +static_assert(sizeof(FutexWordType) == 4, + "Unexpected size of unsigned int type."); +#else +#error "Futex word base type not defined for the target architecture." +#endif } // namespace __llvm_libc diff --git a/libc/src/threads/linux/Mutex.h b/libc/src/threads/linux/Mutex.h index c32bd39..a8fe853 100644 --- a/libc/src/threads/linux/Mutex.h +++ b/libc/src/threads/linux/Mutex.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC_SRC_THREADS_LINUX_MUTEX_H #define LLVM_LIBC_SRC_THREADS_LINUX_MUTEX_H +#include "Futex.h" + #include "include/sys/syscall.h" // For syscall numbers. #include "include/threads.h" // For values like thrd_success etc. #include "src/__support/CPP/atomic.h" // For atomics support @@ -18,14 +20,6 @@ namespace __llvm_libc { -#if (defined(LLVM_LIBC_ARCH_AARCH64) || defined(LLVM_LIBC_ARCH_X86_64)) -static_assert(sizeof(unsigned int) == 4, - "Unexpected size of unsigned int type."); -typedef unsigned int FutexWordType; -#else -#error "Futex word base type not defined for the target architecture." -#endif - struct Mutex { enum Status : FutexWordType { MS_Free, diff --git a/libc/src/threads/linux/Thread.h b/libc/src/threads/linux/Thread.h index 55aa271..a14ed49 100644 --- a/libc/src/threads/linux/Thread.h +++ b/libc/src/threads/linux/Thread.h @@ -11,7 +11,6 @@ #include "thread_start_args.h" -#include <stdatomic.h> #include <stdint.h> namespace __llvm_libc { diff --git a/libc/src/threads/linux/call_once.cpp b/libc/src/threads/linux/call_once.cpp index 9b96646..e04c4e4 100644 --- a/libc/src/threads/linux/call_once.cpp +++ b/libc/src/threads/linux/call_once.cpp @@ -6,27 +6,32 @@ // //===----------------------------------------------------------------------===// -#include "src/threads/call_once.h" +#include "Futex.h" + #include "include/sys/syscall.h" // For syscall numbers. #include "include/threads.h" // For call_once related type definition. +#include "src/__support/CPP/atomic.h" #include "src/__support/OSUtil/syscall.h" // For syscall functions. #include "src/__support/common.h" +#include "src/threads/call_once.h" #include "src/threads/linux/Futex.h" #include <limits.h> #include <linux/futex.h> -#include <stdatomic.h> namespace __llvm_libc { -static constexpr unsigned START = 0x11; -static constexpr unsigned WAITING = 0x22; -static constexpr unsigned FINISH = 0x33; +static constexpr FutexWordType START = 0x11; +static constexpr FutexWordType WAITING = 0x22; +static constexpr FutexWordType FINISH = 0x33; +static constexpr once_flag ONCE_FLAG_INIT_VAL = ONCE_FLAG_INIT; LLVM_LIBC_FUNCTION(void, call_once, (once_flag * flag, __call_once_func_t func)) { - FutexWord *futex_word = reinterpret_cast<FutexWord *>(flag); - unsigned int not_called = ONCE_FLAG_INIT; + auto *futex_word = reinterpret_cast<cpp::Atomic<FutexWordType> *>(flag); + static_assert(sizeof(*futex_word) == sizeof(once_flag)); + + FutexWordType not_called = ONCE_FLAG_INIT_VAL.__word; // The C standard wording says: // @@ -37,21 +42,21 @@ LLVM_LIBC_FUNCTION(void, call_once, // What this means is that, the call_once call can return only after // the called function |func| returns. So, we use futexes to synchronize // calls with the same flag value. - if (::atomic_compare_exchange_strong(futex_word, ¬_called, START)) { + if (futex_word->compare_exchange_strong(not_called, START)) { func(); - auto status = ::atomic_exchange(futex_word, FINISH); + auto status = futex_word->exchange(FINISH); if (status == WAITING) { - __llvm_libc::syscall(SYS_futex, futex_word, FUTEX_WAKE_PRIVATE, + __llvm_libc::syscall(SYS_futex, &futex_word->val, FUTEX_WAKE_PRIVATE, INT_MAX, // Wake all waiters. 0, 0, 0); } return; } - unsigned int status = START; - if (::atomic_compare_exchange_strong(futex_word, &status, WAITING) || + FutexWordType status = START; + if (futex_word->compare_exchange_strong(status, WAITING) || status == WAITING) { - __llvm_libc::syscall(SYS_futex, futex_word, FUTEX_WAIT_PRIVATE, + __llvm_libc::syscall(SYS_futex, &futex_word->val, FUTEX_WAIT_PRIVATE, WAITING, // Block only if status is still |WAITING|. 0, 0, 0); } diff --git a/libc/src/threads/linux/thrd_create.cpp b/libc/src/threads/linux/thrd_create.cpp index 5421c96..34b5039 100644 --- a/libc/src/threads/linux/thrd_create.cpp +++ b/libc/src/threads/linux/thrd_create.cpp @@ -6,7 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "src/threads/thrd_create.h" +#include "Futex.h" + #include "include/errno.h" // For E* error values. #include "include/sys/mman.h" // For PROT_* and MAP_* definitions. #include "include/sys/syscall.h" // For syscall numbers. @@ -16,8 +17,8 @@ #include "src/errno/llvmlibc_errno.h" #include "src/sys/mman/mmap.h" #include "src/sys/mman/munmap.h" -#include "src/threads/linux/Futex.h" #include "src/threads/linux/Thread.h" +#include "src/threads/thrd_create.h" #include <linux/sched.h> // For CLONE_* flags. #include <stdint.h> @@ -61,8 +62,7 @@ LLVM_LIBC_FUNCTION(int, thrd_create, thread->__stack = stack; thread->__stack_size = ThreadParams::DEFAULT_STACK_SIZE; thread->__retval = -1; - FutexWord *clear_tid_address = - reinterpret_cast<FutexWord *>(thread->__clear_tid); + FutexWordType *clear_tid_address = &thread->__clear_tid.__word; *clear_tid_address = ThreadParams::CLEAR_TID_VALUE; // When the new thread is spawned by the kernel, the new thread gets the diff --git a/libc/src/threads/linux/thrd_join.cpp b/libc/src/threads/linux/thrd_join.cpp index f55f5a3..361c587 100644 --- a/libc/src/threads/linux/thrd_join.cpp +++ b/libc/src/threads/linux/thrd_join.cpp @@ -6,31 +6,32 @@ // //===----------------------------------------------------------------------===// -#include "src/threads/thrd_join.h" -#include "include/sys/syscall.h" // For syscall numbers. -#include "include/threads.h" // For thrd_* type definitions. +#include "Futex.h" + +#include "include/sys/syscall.h" // For syscall numbers. +#include "include/threads.h" // For thrd_* type definitions. +#include "src/__support/CPP/atomic.h" #include "src/__support/OSUtil/syscall.h" // For syscall function. #include "src/__support/common.h" #include "src/sys/mman/munmap.h" -#include "src/threads/linux/Futex.h" #include "src/threads/linux/Thread.h" +#include "src/threads/thrd_join.h" #include <linux/futex.h> // For futex operations. -#include <stdatomic.h> // For atomic_load. namespace __llvm_libc { LLVM_LIBC_FUNCTION(int, thrd_join, (thrd_t * thread, int *retval)) { - FutexWord *clear_tid_address = - reinterpret_cast<FutexWord *>(thread->__clear_tid); + auto *clear_tid_address = + reinterpret_cast<cpp::Atomic<FutexWordType> *>(&thread->__clear_tid); // The kernel should set the value at the clear tid address to zero. // If not, it is a spurious wake and we should continue to wait on // the futex. - while (atomic_load(clear_tid_address) != 0) { + while (clear_tid_address->load() != 0) { // We cannot do a FUTEX_WAIT_PRIVATE here as the kernel does a // FUTEX_WAKE and not a FUTEX_WAKE_PRIVATE. - __llvm_libc::syscall(SYS_futex, clear_tid_address, FUTEX_WAIT, + __llvm_libc::syscall(SYS_futex, &clear_tid_address->val, FUTEX_WAIT, ThreadParams::CLEAR_TID_VALUE, nullptr); } |