|
1 | | -//===-- Implementation of errno -------------------------------------------===// |
| 1 | +//===-- Implementation of libc_errno --------------------------------------===// |
2 | 2 | // |
3 | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | 4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | 6 | // |
7 | 7 | //===----------------------------------------------------------------------===// |
8 | 8 |
|
9 | | -#include "src/__support/macros/attributes.h" |
10 | | -#include "src/__support/macros/properties/architectures.h" |
11 | | - |
12 | | -namespace LIBC_NAMESPACE { |
| 9 | +#include "libc_errno.h" |
13 | 10 |
|
14 | 11 | #ifdef LIBC_TARGET_ARCH_IS_GPU |
15 | | -struct ErrnoConsumer { |
16 | | - void operator=(int) {} |
17 | | -}; |
18 | | -#endif |
| 12 | +// LIBC_THREAD_LOCAL on GPU currently does nothing. So essentially this is just |
| 13 | +// a global errno for gpu to use for now. |
| 14 | +extern "C" { |
| 15 | +LIBC_THREAD_LOCAL int __llvmlibc_gpu_errno; |
| 16 | +} |
19 | 17 |
|
| 18 | +void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_gpu_errno = a; } |
| 19 | +LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_gpu_errno; } |
| 20 | + |
| 21 | +#elif !defined(LIBC_COPT_PUBLIC_PACKAGING) |
| 22 | +// This mode is for unit testing. We just use our internal errno. |
| 23 | +LIBC_THREAD_LOCAL int __llvmlibc_internal_errno; |
| 24 | + |
| 25 | +void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_internal_errno = a; } |
| 26 | +LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_internal_errno; } |
| 27 | + |
| 28 | +#elif defined(LIBC_FULL_BUILD) |
| 29 | +// This mode is for public libc archive, hermetic, and integration tests. |
| 30 | +// In full build mode, we provide the errno storage ourselves. |
20 | 31 | extern "C" { |
21 | | -#ifdef LIBC_COPT_PUBLIC_PACKAGING |
22 | | -// TODO: Declare __llvmlibc_errno only under LIBC_COPT_PUBLIC_PACKAGING and |
23 | | -// __llvmlibc_internal_errno otherwise. |
24 | | -// In overlay mode, this will be an unused thread local variable as libc_errno |
25 | | -// will resolve to errno from the system libc's errno.h. In full build mode |
26 | | -// however, libc_errno will resolve to this thread local variable via the errno |
27 | | -// macro defined in LLVM libc's public errno.h header file. |
28 | | -// TODO: Use a macro to distinguish full build and overlay build which can be |
29 | | -// used to exclude __llvmlibc_errno under overlay build. |
30 | | -#ifdef LIBC_TARGET_ARCH_IS_GPU |
31 | | -ErrnoConsumer __llvmlibc_errno; |
32 | | -#else |
33 | 32 | LIBC_THREAD_LOCAL int __llvmlibc_errno; |
34 | | -#endif // LIBC_TARGET_ARCH_IS_GPU |
| 33 | +} |
| 34 | + |
| 35 | +void LIBC_NAMESPACE::Errno::operator=(int a) { __llvmlibc_errno = a; } |
| 36 | +LIBC_NAMESPACE::Errno::operator int() { return __llvmlibc_errno; } |
| 37 | + |
35 | 38 | #else |
36 | | -LIBC_THREAD_LOCAL int __llvmlibc_internal_errno; |
37 | | -#endif |
38 | | -} // extern "C" |
| 39 | +// In overlay mode, we simply use the system errno. |
| 40 | +#include <errno.h> |
| 41 | + |
| 42 | +void LIBC_NAMESPACE::Errno::operator=(int a) { errno = a; } |
| 43 | +LIBC_NAMESPACE::Errno::operator int() { return errno; } |
| 44 | + |
| 45 | +#endif // LIBC_FULL_BUILD |
39 | 46 |
|
40 | | -} // namespace LIBC_NAMESPACE |
| 47 | +// Define the global `libc_errno` instance. |
| 48 | +LIBC_NAMESPACE::Errno libc_errno; |
0 commit comments