Skip to content

Commit b7a7f43

Browse files
committed
[libc] Partially implement 'errno' on the GPU
Summary: The `errno` variable is expected to be `thread_local` by the standard. However, the GPU targets do not support `thread_local` and implementing that would be a large endeavor. Because of that, we previously didn't provide the `errno` symbol at all. However, to build some programs we at least need to be able to link against `errno`. Many things that would normally set `errno` completely ignore it currently (i.e. stdio) but some programs still need to be able to link against correct C programs. For this purpose this patch exports the `errno` symbol as a simple global. Internally, this will be updated atomically so it's at least not racy. Externally, this will be on the user. I've updated the documentation to state as such. This is required to get `libc++` to build.
1 parent 6ba764a commit b7a7f43

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

libc/include/errno.h.def

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,18 @@
2525
#include "llvm-libc-macros/generic-error-number-macros.h"
2626
#endif
2727

28-
#if !defined(__AMDGPU__) && !defined(__NVPTX__)
29-
28+
#if defined(__AMDGPU__) || defined(__NVPTX__)
29+
extern int __llvmlibc_errno; // Not thread_local!
30+
#else
3031
#ifdef __cplusplus
3132
extern "C" {
3233
extern thread_local int __llvmlibc_errno;
3334
}
3435
#else
3536
extern _Thread_local int __llvmlibc_errno;
3637
#endif // __cplusplus
38+
#endif
3739

3840
#define errno __llvmlibc_errno
39-
#endif
4041

4142
#endif // LLVM_LIBC_ERRNO_H

libc/src/errno/libc_errno.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "libc_errno.h"
10+
#include "src/__support/CPP/atomic.h"
1011

1112
#ifdef LIBC_TARGET_ARCH_IS_GPU
12-
// LIBC_THREAD_LOCAL on GPU currently does nothing. So essentially this is just
13+
// LIBC_THREAD_LOCAL on GPU currently does nothing. So essentially this is just
1314
// a global errno for gpu to use for now.
1415
extern "C" {
15-
LIBC_THREAD_LOCAL int __llvmlibc_gpu_errno;
16+
LIBC_THREAD_LOCAL LIBC_NAMESPACE::cpp::Atomic<int> __llvmlibc_errno;
1617
}
1718

18-
void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_gpu_errno = a; }
19-
LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_gpu_errno; }
19+
void LIBC_NAMESPACE::Errno::operator=(int a) {
20+
__llvmlibc_errno.store(a, cpp::MemoryOrder::RELAXED);
21+
}
22+
LIBC_NAMESPACE::Errno::operator int() {
23+
return __llvmlibc_errno.load(cpp::MemoryOrder::RELAXED);
24+
}
2025

2126
#elif !defined(LIBC_COPT_PUBLIC_PACKAGING)
2227
// This mode is for unit testing. We just use our internal errno.

0 commit comments

Comments
 (0)