The 'errno' value is most likely not useful on the GPU and it prevents
us from providing certain functions on the GPU that depend on it, like
`atoi`. This patch makes the necessary changes to support `errno` by
simple replacing it with a consumer class.
Supporting `errno` on the GPU is possible in some aspects. The first
approach would be to use a buffer of shared memory that has enough space
for all threads. Another option would be to change code generation to
support `thread_local` using `address_space(5)` memory allocated at
kernel launch. The former could look like the following, which could be
implemented in a later patch:
```
template <typename T>
using SharedBuffer = T[gpu::MAX_THREADS] [[clang::address_space(3)]];
template <typename T> struct ErrnoSetter {
constexpr ErrnoSetter(SharedBuffer<T> &storage) : storage(storage) {}
SharedBuffer<T> &storage;
void operator=(const T &val) { storage[gpu::get_thread_id()] = val; }
};
static SharedBuffer<int> thread_local_buffer [[clang::loader_uninitialized]];
ErrnoSetter<int> __llvmlibc_internal_errno(thread_local_buffer);
```
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D149107
38 lines
1.4 KiB
C++
38 lines
1.4 KiB
C++
//===-- Implementation of errno -------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "src/__support/macros/properties/architectures.h"
|
|
|
|
namespace __llvm_libc {
|
|
|
|
extern "C" {
|
|
#ifdef LIBC_COPT_PUBLIC_PACKAGING
|
|
// TODO: Declare __llvmlibc_errno only under LIBC_COPT_PUBLIC_PACKAGING and
|
|
// __llvmlibc_internal_errno otherwise.
|
|
// In overlay mode, this will be an unused thread local variable as libc_errno
|
|
// will resolve to errno from the system libc's errno.h. In full build mode
|
|
// however, libc_errno will resolve to this thread local variable via the errno
|
|
// macro defined in LLVM libc's public errno.h header file.
|
|
// TODO: Use a macro to distinguish full build and overlay build which can be
|
|
// used to exclude __llvmlibc_errno under overlay build.
|
|
#ifdef LIBC_TARGET_ARCH_IS_GPU
|
|
ErrnoConsumer __llvmlibc_errno;
|
|
#else
|
|
thread_local int __llvmlibc_errno;
|
|
#endif // LIBC_TARGET_ARCH_IS_GPU
|
|
#else
|
|
#ifdef LIBC_TARGET_ARCH_IS_GPU
|
|
ErrnoConsumer __llvmlibc_internal_errno;
|
|
#else
|
|
thread_local int __llvmlibc_internal_errno;
|
|
#endif // LIBC_TARGET_ARCH_IS_GPU
|
|
#endif
|
|
} // extern "C"
|
|
|
|
} // namespace __llvm_libc
|