[libc-commits] [libc] 82bddc3 - [libc] Mutex implementation for single-threaded baremetal (#145358)
via libc-commits
libc-commits at lists.llvm.org
Thu Jul 31 04:16:48 PDT 2025
Author: William Huynh
Date: 2025-07-31T12:16:44+01:00
New Revision: 82bddc3e64e03ec4bb07ad9c757d2a06b5acb0c0
URL: https://github.com/llvm/llvm-project/commit/82bddc3e64e03ec4bb07ad9c757d2a06b5acb0c0
DIFF: https://github.com/llvm/llvm-project/commit/82bddc3e64e03ec4bb07ad9c757d2a06b5acb0c0.diff
LOG: [libc] Mutex implementation for single-threaded baremetal (#145358)
Part of https://github.com/llvm/llvm-project/issues/145349. Required to
allow `atexit` to work. As part of `HermeticTestUtils.cpp`, there is a
reference to `atexit()`, which eventually instantiates an instance of a
Mutex.
Instead of copying the implementation from
`libc/src/__support/threads/gpu/mutex.h`, we allow platforms to select
an implementation based on configurations, allowing the GPU and
single-threaded baremetal platforms to share an implementation. This can
be configured or overridden.
Later, when the threading API is more complete, we can add an option to
support multithreading (or set it as the default), but having
single-threading (in tandem) is in line with other libraries for
embedded devices.
Added:
Modified:
libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
libc/config/baremetal/config.json
libc/config/config.json
libc/config/gpu/amdgpu/config.json
libc/config/gpu/nvptx/config.json
libc/docs/configure.rst
libc/src/__support/threads/CMakeLists.txt
libc/src/__support/threads/mutex.h
Removed:
libc/src/__support/threads/gpu/CMakeLists.txt
libc/src/__support/threads/gpu/mutex.h
################################################################################
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 2478fde64d430..d85c3930474ab 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -108,6 +108,10 @@ function(_get_compile_options_from_config output_var)
list(APPEND config_options "-DLIBC_ERRNO_MODE=${LIBC_CONF_ERRNO_MODE}")
endif()
+ if(LIBC_CONF_THREAD_MODE)
+ list(APPEND config_options "-DLIBC_THREAD_MODE=${LIBC_CONF_THREAD_MODE}")
+ endif()
+
set(${output_var} ${config_options} PARENT_SCOPE)
endfunction(_get_compile_options_from_config)
diff --git a/libc/config/baremetal/config.json b/libc/config/baremetal/config.json
index 105e417d165f0..f01e5084b9695 100644
--- a/libc/config/baremetal/config.json
+++ b/libc/config/baremetal/config.json
@@ -4,6 +4,11 @@
"value": "LIBC_ERRNO_MODE_EXTERNAL"
}
},
+ "threads": {
+ "LIBC_CONF_THREAD_MODE": {
+ "value": "LIBC_THREAD_MODE_SINGLE"
+ }
+ },
"printf": {
"LIBC_CONF_PRINTF_DISABLE_FIXED_POINT": {
"value": true
diff --git a/libc/config/config.json b/libc/config/config.json
index d53b2936edb07..1b0546980e6ba 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -5,6 +5,12 @@
"doc": "The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, LIBC_ERRNO_MODE_SYSTEM, and LIBC_ERRNO_MODE_SYSTEM_INLINE."
}
},
+ "threads": {
+ "LIBC_CONF_THREAD_MODE": {
+ "value": "LIBC_THREAD_MODE_PLATFORM",
+ "doc": "The implementation used for Mutex, acceptable values are LIBC_THREAD_MODE_PLATFORM, LIBC_THREAD_MODE_SINGLE, and LIBC_THREAD_MODE_EXTERNAL."
+ }
+ },
"printf": {
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
"value": false,
diff --git a/libc/config/gpu/amdgpu/config.json b/libc/config/gpu/amdgpu/config.json
index 30ae10e2cfd61..fa179b849dcf7 100644
--- a/libc/config/gpu/amdgpu/config.json
+++ b/libc/config/gpu/amdgpu/config.json
@@ -4,6 +4,11 @@
"value": "LIBC_ERRNO_MODE_SHARED"
}
},
+ "threads": {
+ "LIBC_CONF_THREAD_MODE": {
+ "value": "LIBC_THREAD_MODE_SINGLE"
+ }
+ },
"printf": {
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
"value": true
diff --git a/libc/config/gpu/nvptx/config.json b/libc/config/gpu/nvptx/config.json
index 30ae10e2cfd61..fa179b849dcf7 100644
--- a/libc/config/gpu/nvptx/config.json
+++ b/libc/config/gpu/nvptx/config.json
@@ -4,6 +4,11 @@
"value": "LIBC_ERRNO_MODE_SHARED"
}
},
+ "threads": {
+ "LIBC_CONF_THREAD_MODE": {
+ "value": "LIBC_THREAD_MODE_SINGLE"
+ }
+ },
"printf": {
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
"value": true
diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst
index 109412225634f..95c51b8517e64 100644
--- a/libc/docs/configure.rst
+++ b/libc/docs/configure.rst
@@ -60,5 +60,7 @@ to learn about the defaults for your platform and target.
* **"string" options**
- ``LIBC_CONF_MEMSET_X86_USE_SOFTWARE_PREFETCHING``: Inserts prefetch for write instructions (PREFETCHW) for memset on x86 to recover performance when hardware prefetcher is disabled.
- ``LIBC_CONF_STRING_UNSAFE_WIDE_READ``: Read more than a byte at a time to perform byte-string operations like strlen.
+* **"threads" options**
+ - ``LIBC_CONF_THREAD_MODE``: The implementation used for Mutex, acceptable values are LIBC_THREAD_MODE_PLATFORM, LIBC_THREAD_MODE_SINGLE, and LIBC_THREAD_MODE_EXTERNAL.
* **"time" options**
- ``LIBC_CONF_TIME_64BIT``: Force the size of time_t to 64 bits, even on platforms where compatibility considerations would otherwise make it 32-bit.
diff --git a/libc/src/__support/threads/CMakeLists.txt b/libc/src/__support/threads/CMakeLists.txt
index b0843463e5321..f8a44937721b4 100644
--- a/libc/src/__support/threads/CMakeLists.txt
+++ b/libc/src/__support/threads/CMakeLists.txt
@@ -42,6 +42,14 @@ if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.mutex)
.mutex
libc.src.__support.CPP.mutex
)
+elseif(NOT (LIBC_CONF_THREAD_MODE STREQUAL LIBC_THREAD_MODE_PLATFORM))
+ add_header_library(
+ mutex
+ HDRS
+ mutex.h
+ DEPENDS
+ .mutex_common
+ )
endif()
add_header_library(
diff --git a/libc/src/__support/threads/gpu/CMakeLists.txt b/libc/src/__support/threads/gpu/CMakeLists.txt
deleted file mode 100644
index ea89feb0c5c68..0000000000000
--- a/libc/src/__support/threads/gpu/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-add_header_library(
- mutex
- HDRS
- mutex.h
-)
diff --git a/libc/src/__support/threads/gpu/mutex.h b/libc/src/__support/threads/gpu/mutex.h
deleted file mode 100644
index c8c484ed2b794..0000000000000
--- a/libc/src/__support/threads/gpu/mutex.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===--- Implementation of a GPU mutex class --------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H
-#define LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H
-
-#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/threads/mutex_common.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-/// Implementation of a simple passthrough mutex which guards nothing. A
-/// complete Mutex locks in general cannot be implemented on the GPU. We simply
-/// define the Mutex interface and require that only a single thread executes
-/// code requiring a mutex lock.
-struct Mutex {
- LIBC_INLINE constexpr Mutex(bool, bool, bool, bool) {}
-
- LIBC_INLINE MutexError lock() { return MutexError::NONE; }
- LIBC_INLINE MutexError unlock() { return MutexError::NONE; }
- LIBC_INLINE MutexError reset() { return MutexError::NONE; }
-};
-
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H
diff --git a/libc/src/__support/threads/mutex.h b/libc/src/__support/threads/mutex.h
index 392b38984dc0a..cbef0d00009b2 100644
--- a/libc/src/__support/threads/mutex.h
+++ b/libc/src/__support/threads/mutex.h
@@ -9,10 +9,35 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H
-#include "src/__support/macros/properties/architectures.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+// Uses the platform specific specialization
+#define LIBC_THREAD_MODE_PLATFORM 0
+
+// Mutex guards nothing, used in single-threaded implementations
+#define LIBC_THREAD_MODE_SINGLE 1
+
+// Vendor provides implementation
+#define LIBC_THREAD_MODE_EXTERNAL 2
+
+#if !defined(LIBC_THREAD_MODE)
+#error LIBC_THREAD_MODE is undefined
+#endif // LIBC_THREAD_MODE
+
+#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \
+ LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \
+ LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL
+#error LIBC_THREAD_MODE must be one of the following values: \
+LIBC_THREAD_MODE_PLATFORM, \
+LIBC_THREAD_MODE_SINGLE, \
+LIBC_THREAD_MODE_EXTERNAL.
+#endif
+
+#if LIBC_THREAD_MODE == LIBC_THREAD_MODE_PLATFORM
// Platform independent code will include this header file which pulls
-// the platfrom specific specializations using platform macros.
+// the platform specific specializations using platform macros.
//
// The platform specific specializations should define a class by name
// Mutex with non-static methods having the following signature:
@@ -39,8 +64,32 @@
#if defined(__linux__)
#include "src/__support/threads/linux/mutex.h"
-#elif defined(LIBC_TARGET_ARCH_IS_GPU)
-#include "src/__support/threads/gpu/mutex.h"
#endif // __linux__
+#elif LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE
+
+#include "src/__support/threads/mutex_common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+/// Implementation of a simple passthrough mutex which guards nothing. A
+/// complete Mutex locks in general cannot be implemented on the GPU, or on some
+/// baremetal platforms. We simply define the Mutex interface and require that
+/// only a single thread executes code requiring a mutex lock.
+struct Mutex {
+ LIBC_INLINE constexpr Mutex(bool, bool, bool, bool) {}
+
+ LIBC_INLINE MutexError lock() { return MutexError::NONE; }
+ LIBC_INLINE MutexError unlock() { return MutexError::NONE; }
+ LIBC_INLINE MutexError reset() { return MutexError::NONE; }
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#elif LIBC_THREAD_MODE == LIBC_THREAD_MODE_EXTERNAL
+
+// TODO: Implement the interfacing, if necessary, e.g. "extern struct Mutex;"
+
+#endif // LIBC_THREAD_MODE == LIBC_THREAD_MODE_PLATFORM
+
#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H
More information about the libc-commits
mailing list