aboutsummaryrefslogtreecommitdiff
path: root/libc/src/threads/linux
diff options
context:
space:
mode:
authorSiva Chandra Reddy <sivachandra@google.com>2022-03-01 08:54:46 +0000
committerSiva Chandra Reddy <sivachandra@google.com>2022-03-01 17:12:39 +0000
commit75747c73946546fb9f9163b9a813b54f96874948 (patch)
tree50f5defbb40f1c5d901816be27ff62328b2a8938 /libc/src/threads/linux
parentc809c9bd3b75962c9fc7ab90c8e90d3be317b43b (diff)
downloadllvm-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.txt2
-rw-r--r--libc/src/threads/linux/Futex.h21
-rw-r--r--libc/src/threads/linux/Mutex.h10
-rw-r--r--libc/src/threads/linux/Thread.h1
-rw-r--r--libc/src/threads/linux/call_once.cpp31
-rw-r--r--libc/src/threads/linux/thrd_create.cpp8
-rw-r--r--libc/src/threads/linux/thrd_join.cpp19
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, &not_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);
}