Skip to content

Commit 82bddc3

Browse files
authored
[libc] Mutex implementation for single-threaded baremetal (#145358)
Part of #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.
1 parent b7d00b8 commit 82bddc3

File tree

10 files changed

+88
-41
lines changed

10 files changed

+88
-41
lines changed

libc/cmake/modules/LLVMLibCCompileOptionRules.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ function(_get_compile_options_from_config output_var)
108108
list(APPEND config_options "-DLIBC_ERRNO_MODE=${LIBC_CONF_ERRNO_MODE}")
109109
endif()
110110

111+
if(LIBC_CONF_THREAD_MODE)
112+
list(APPEND config_options "-DLIBC_THREAD_MODE=${LIBC_CONF_THREAD_MODE}")
113+
endif()
114+
111115
set(${output_var} ${config_options} PARENT_SCOPE)
112116
endfunction(_get_compile_options_from_config)
113117

libc/config/baremetal/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"value": "LIBC_ERRNO_MODE_EXTERNAL"
55
}
66
},
7+
"threads": {
8+
"LIBC_CONF_THREAD_MODE": {
9+
"value": "LIBC_THREAD_MODE_SINGLE"
10+
}
11+
},
712
"printf": {
813
"LIBC_CONF_PRINTF_DISABLE_FIXED_POINT": {
914
"value": true

libc/config/config.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
"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."
66
}
77
},
8+
"threads": {
9+
"LIBC_CONF_THREAD_MODE": {
10+
"value": "LIBC_THREAD_MODE_PLATFORM",
11+
"doc": "The implementation used for Mutex, acceptable values are LIBC_THREAD_MODE_PLATFORM, LIBC_THREAD_MODE_SINGLE, and LIBC_THREAD_MODE_EXTERNAL."
12+
}
13+
},
814
"printf": {
915
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
1016
"value": false,

libc/config/gpu/amdgpu/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"value": "LIBC_ERRNO_MODE_SHARED"
55
}
66
},
7+
"threads": {
8+
"LIBC_CONF_THREAD_MODE": {
9+
"value": "LIBC_THREAD_MODE_SINGLE"
10+
}
11+
},
712
"printf": {
813
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
914
"value": true

libc/config/gpu/nvptx/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"value": "LIBC_ERRNO_MODE_SHARED"
55
}
66
},
7+
"threads": {
8+
"LIBC_CONF_THREAD_MODE": {
9+
"value": "LIBC_THREAD_MODE_SINGLE"
10+
}
11+
},
712
"printf": {
813
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
914
"value": true

libc/docs/configure.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,7 @@ to learn about the defaults for your platform and target.
6060
* **"string" options**
6161
- ``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.
6262
- ``LIBC_CONF_STRING_UNSAFE_WIDE_READ``: Read more than a byte at a time to perform byte-string operations like strlen.
63+
* **"threads" options**
64+
- ``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.
6365
* **"time" options**
6466
- ``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.

libc/src/__support/threads/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.mutex)
4242
.mutex
4343
libc.src.__support.CPP.mutex
4444
)
45+
elseif(NOT (LIBC_CONF_THREAD_MODE STREQUAL LIBC_THREAD_MODE_PLATFORM))
46+
add_header_library(
47+
mutex
48+
HDRS
49+
mutex.h
50+
DEPENDS
51+
.mutex_common
52+
)
4553
endif()
4654

4755
add_header_library(

libc/src/__support/threads/gpu/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

libc/src/__support/threads/gpu/mutex.h

Lines changed: 0 additions & 32 deletions
This file was deleted.

libc/src/__support/threads/mutex.h

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,35 @@
99
#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H
1010
#define LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H
1111

12-
#include "src/__support/macros/properties/architectures.h"
12+
#include "src/__support/macros/attributes.h"
13+
#include "src/__support/macros/config.h"
14+
15+
// Uses the platform specific specialization
16+
#define LIBC_THREAD_MODE_PLATFORM 0
17+
18+
// Mutex guards nothing, used in single-threaded implementations
19+
#define LIBC_THREAD_MODE_SINGLE 1
20+
21+
// Vendor provides implementation
22+
#define LIBC_THREAD_MODE_EXTERNAL 2
23+
24+
#if !defined(LIBC_THREAD_MODE)
25+
#error LIBC_THREAD_MODE is undefined
26+
#endif // LIBC_THREAD_MODE
27+
28+
#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \
29+
LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \
30+
LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL
31+
#error LIBC_THREAD_MODE must be one of the following values: \
32+
LIBC_THREAD_MODE_PLATFORM, \
33+
LIBC_THREAD_MODE_SINGLE, \
34+
LIBC_THREAD_MODE_EXTERNAL.
35+
#endif
36+
37+
#if LIBC_THREAD_MODE == LIBC_THREAD_MODE_PLATFORM
1338

1439
// Platform independent code will include this header file which pulls
15-
// the platfrom specific specializations using platform macros.
40+
// the platform specific specializations using platform macros.
1641
//
1742
// The platform specific specializations should define a class by name
1843
// Mutex with non-static methods having the following signature:
@@ -39,8 +64,32 @@
3964

4065
#if defined(__linux__)
4166
#include "src/__support/threads/linux/mutex.h"
42-
#elif defined(LIBC_TARGET_ARCH_IS_GPU)
43-
#include "src/__support/threads/gpu/mutex.h"
4467
#endif // __linux__
4568

69+
#elif LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE
70+
71+
#include "src/__support/threads/mutex_common.h"
72+
73+
namespace LIBC_NAMESPACE_DECL {
74+
75+
/// Implementation of a simple passthrough mutex which guards nothing. A
76+
/// complete Mutex locks in general cannot be implemented on the GPU, or on some
77+
/// baremetal platforms. We simply define the Mutex interface and require that
78+
/// only a single thread executes code requiring a mutex lock.
79+
struct Mutex {
80+
LIBC_INLINE constexpr Mutex(bool, bool, bool, bool) {}
81+
82+
LIBC_INLINE MutexError lock() { return MutexError::NONE; }
83+
LIBC_INLINE MutexError unlock() { return MutexError::NONE; }
84+
LIBC_INLINE MutexError reset() { return MutexError::NONE; }
85+
};
86+
87+
} // namespace LIBC_NAMESPACE_DECL
88+
89+
#elif LIBC_THREAD_MODE == LIBC_THREAD_MODE_EXTERNAL
90+
91+
// TODO: Implement the interfacing, if necessary, e.g. "extern struct Mutex;"
92+
93+
#endif // LIBC_THREAD_MODE == LIBC_THREAD_MODE_PLATFORM
94+
4695
#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H

0 commit comments

Comments
 (0)