-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[libc] Mutex implementation for single-threaded baremetal #145358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-backend-amdgpu @llvm/pr-subscribers-libc Author: William Huynh (saturn691) ChangesIn order to add, #145349, we need a Mutex, to allow Full diff: https://github.com/llvm/llvm-project/pull/145358.diff 3 Files Affected:
diff --git a/libc/src/__support/threads/baremetal/CMakeLists.txt b/libc/src/__support/threads/baremetal/CMakeLists.txt
new file mode 100644
index 0000000000000..ea89feb0c5c68
--- /dev/null
+++ b/libc/src/__support/threads/baremetal/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_header_library(
+ mutex
+ HDRS
+ mutex.h
+)
diff --git a/libc/src/__support/threads/baremetal/mutex.h b/libc/src/__support/threads/baremetal/mutex.h
new file mode 100644
index 0000000000000..77a0b61ea9f5b
--- /dev/null
+++ b/libc/src/__support/threads/baremetal/mutex.h
@@ -0,0 +1,32 @@
+//===--- Implementation of a mutex class for baremetal ----------*- 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_BAREMETAL_MUTEX_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_BAREMETAL_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. For
+/// single threaded processors, this is the implementation.
+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; }
+};
+
+// TODO: add multithreading support here
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_BAREMETAL_MUTEX_H
diff --git a/libc/src/__support/threads/mutex.h b/libc/src/__support/threads/mutex.h
index 392b38984dc0a..a600e2ff017f5 100644
--- a/libc/src/__support/threads/mutex.h
+++ b/libc/src/__support/threads/mutex.h
@@ -41,6 +41,8 @@
#include "src/__support/threads/linux/mutex.h"
#elif defined(LIBC_TARGET_ARCH_IS_GPU)
#include "src/__support/threads/gpu/mutex.h"
+#elif defined(__ELF__)
+#include "src/__support/threads/baremetal/mutex.h"
#endif // __linux__
#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H
|
|
I've been considering if it's possible to just make |
That would conflict with the C standard, right? |
I think glibc does a stack that allows this. Possible we'd want to be compatible with that. We currently aren't, because we just lock the interface... Doesn't that mean that if an atexit handler calls atexit it'll deadlock? |
Whoa, I'm out of date! That's interesting; C11 doesn't have the second sentence, which would ostensibly put it in scope for 7.1.4 (in the draft): Do we have a go-to policy for cases in libc/libc++ where the standard loosens its requirements from version to version? (Presuming that I'm interpreting things reasonably and that happened here; I haven't looked into this very far. Need to find the rationale doc for that change.) |
It shouldn't; the implementation explicitly unlocks the stack before calling a handler:
|
|
The main concern I have with this change is that it furthers the notion of baremetal as a singular platform whereas in practice there is a diverse set of baremetal platforms. For that reason, I'm starting to consider the existence of Rather than introducing
For baremetal build configuration we would default to I don't expect this to be significantly more complicated than the current PR, but it would more flexible and there might be other build configurations beyond baremetal where |
35ce1b7 to
d7d0433
Compare
On further thought, I wish to share some of the logic for |
|
ping |
|
Implemented changes as suggested from @petrhosek. cc: @michaelrj-google, @frobtech this PR has been here some time, how can I progress this issue further? Is anything lacking, if not who should review this? Thanks a lot! |
| #if !defined(LIBC_TARGET_OS_IS_FREEBSD) && \ | ||
| !defined(LIBC_TARGET_OS_IS_ANDROID) && \ | ||
| !defined(LIBC_TARGET_OS_IS_LINUX) && \ | ||
| !defined(LIBC_TARGET_OS_IS_WINDOWS) && \ | ||
| !defined(LIBC_TARGET_OS_IS_FUCHSIA) && defined(__ELF__) | ||
| #define LIBC_TARGET_OS_IS_BAREMETAL | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is error-prone, every time libc is ported to a new OS, we would need to update this list otherwise the baremetal build is going to break ("action at a distance"). I think a better approach would be to pass this value from the build system. I think it'd be also cleaner to introduce this in a separate PR since it's technically unrelated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll submit another PR to fix this, we can discuss that over there
|
Do you think it would be better to share the configuration of
If you're happy with that I can redo this PR in one go. |
I'd keep them separate since they're technically orthogonal and I think we should avoid overloading the meaning of I expect we'll redo the |
I'm not sure how libc should be configuring this in bazel, but for now
it seems like `LIBC_THREAD_MODE_PLATFORM` restores the default behavior.
Defining this param is required:
```
ERROR: /var/lib/buildkite-agent/.cache/bazel/_bazel_buildkite-agent/c9d34ded3a9d94cc250207948aceadfc/external/llvm-project/libc/BUILD.bazel:5788:14: Compiling libc/src/stdio/generic/vprintf.cpp failed: (Exit 1): clang failed: error executing CppCompile command (from target @@llvm-project//libc:vprintf) /usr/lib/llvm-18/bin/clang -U_FORTIFY_SOURCE -fstack-protector -Wall -Wthread-safety -Wself-assign -Wunused-but-set-parameter -Wno-free-nonheap-object -fcolor-diagnostics -fno-omit-frame-pointer ... (remaining 31 arguments skipped)
Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
In file included from external/llvm-project/libc/src/stdio/generic/vprintf.cpp:11:
In file included from external/llvm-project/libc/src/__support/File/file.h:19:
external/llvm-project/libc/src/__support/threads/mutex.h:25:2: error: LIBC_THREAD_MODE is undefined
25 | #error LIBC_THREAD_MODE is undefined
| ^
```
As an alternative to this PR, we could make the libc header default to
`LIBC_THREAD_MODE_PLATFORM` if not provided, instead of an `#error`
Part of #145349. Required to allow
atexitto work. As part ofHermeticTestUtils.cpp, there is a reference toatexit(), 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.