[libc-commits] [libc] [libc] Support configurable errno modes (PR #98287)

Roland McGrath via libc-commits libc-commits at lists.llvm.org
Wed Jul 10 16:34:01 PDT 2024


================
@@ -9,44 +9,91 @@
 #include "libc_errno.h"
 #include "src/__support/CPP/atomic.h"
 
-#ifdef LIBC_TARGET_ARCH_IS_GPU
-// LIBC_THREAD_LOCAL on GPU currently does nothing. So essentially this is just
-// a global errno for gpu to use for now.
+#define LIBC_ERRNO_MODE_UNDEFINED 0x01
+#define LIBC_ERRNO_MODE_THREAD_LOCAL 0x02
+#define LIBC_ERRNO_MODE_GLOBAL 0x04
+#define LIBC_ERRNO_MODE_EXTERNAL 0x08
+#define LIBC_ERRNO_MODE_SYSTEM 0x10
+
+#ifndef LIBC_ERRNO_MODE
+#ifndef LIBC_COPT_PUBLIC_PACKAGING
+// This mode is for unit testing. We just use our internal errno.
+#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_INTERNAL
+#elif defined(LIBC_FULL_BUILD)
+// In full build mode, we provide the errno storage ourselves.
+#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_THREAD_LOCAL
+#else
+#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM
+#endif
+#endif // LIBC_ERRNO_MODE
+
+#if LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_UNDEFINED &&                            \
+    LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_THREAD_LOCAL &&                         \
+    LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_GLOBAL &&                               \
+    LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_EXTERNAL &&                             \
+    LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM
+#error LIBC_ERRNO_MODE must be one of the following values: \
+LIBC_ERRNO_MODE_NONE, \
+LIBC_ERRNO_MODE_THREAD_LOCAL, \
+LIBC_ERRNO_MODE_GLOBAL, \
+LIBC_ERRNO_MODE_EXTERNAL, \
+LIBC_ERRNO_MODE_SYSTEM
+#endif
+
+namespace LIBC_NAMESPACE {
+
+// Define the global `libc_errno` instance.
+Errno libc_errno;
+
+#if LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_UNDEFINED
+
+void Errno::operator=(int) {}
+Errno::operator int() { return 0; }
+
+#elif LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_THREAD_LOCAL
+
+namespace {
+LIBC_THREAD_LOCAL int __libc_errno;
+}
+
 extern "C" {
-LIBC_THREAD_LOCAL LIBC_NAMESPACE::cpp::Atomic<int> __llvmlibc_errno;
+int *__llvm_libc_errno(void) { return &__libc_errno; }
----------------
frobtech wrote:

`extern "C"` is never necessary on/around definitions of things that have already been declared in the containing scope.  Since everything like this should already have been declared in some header file, I'm generally inclined just never to use `extern "C"` on the definitions.

The `(void)` is accepted and fine in C++, but it's generally only used in places where a declaration might be compiled as C.  It's fine to have it declared as `(void)` and then defined as `()` when the definition is in C++, and that's normal C++ style.


https://github.com/llvm/llvm-project/pull/98287


More information about the libc-commits mailing list