llvm-project/libc/src/errno/libc_errno.cpp
Joseph Huber d9f033146b [libc] Ignore 'errno' on the GPU and support 'atoi'
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
2023-04-25 12:41:20 -05:00

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