//===--- A platform independent indirection for a thread class --*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// #ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_H #define LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_H #include "src/__support/CPP/atomic.h" #include "src/__support/CPP/optional.h" #include "src/__support/CPP/string_view.h" #include "src/__support/CPP/stringstream.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/architectures.h" // TODO: fix this unguarded linux dep #include <linux/param.h> // for exec_pagesize. #include <stddef.h> // For size_t #include <stdint.h> namespace LIBC_NAMESPACE_DECL { ThreadRunnerPosix; ThreadRunnerStdc; ThreadRunner; ThreadReturnValue; #if (defined(LIBC_TARGET_ARCH_IS_AARCH64) || \ defined(LIBC_TARGET_ARCH_IS_X86_64) || \ defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)) constexpr unsigned int STACK_ALIGNMENT = …; #elif defined(LIBC_TARGET_ARCH_IS_ARM) // See Section 6.2.1.2 Stack constraints at a public interface of AAPCS32. constexpr unsigned int STACK_ALIGNMENT = 8; #endif // TODO: Provide stack alignment requirements for other architectures. enum class DetachState : uint32_t { … }; enum class ThreadStyle : uint8_t { … }; // Detach type is useful in testing the detach operation. enum class DetachType : int { … }; class ThreadAtExitCallbackMgr; // A data type to hold common thread attributes which have to be stored as // thread state. Note that this is different from public attribute types like // pthread_attr_t which might contain information which need not be saved as // part of a thread's state. For example, the stack guard size. // // Thread attributes are typically stored on the stack. So, we align as required // for the target architecture. struct alignas(STACK_ALIGNMENT) ThreadAttributes { … }; TSSDtor; // Create a new TSS key and associate the |dtor| as the corresponding // destructor. Can be used to implement public functions like // pthread_key_create. cpp::optional<unsigned int> new_tss_key(TSSDtor *dtor); // Delete the |key|. Can be used to implement public functions like // pthread_key_delete. // // Return true on success, false on failure. bool tss_key_delete(unsigned int key); // Set the value associated with |key| for the current thread. Can be used // to implement public functions like pthread_setspecific. // // Return true on success, false on failure. bool set_tss_value(unsigned int key, void *value); // Return the value associated with |key| for the current thread. Return // nullptr if |key| is invalid. Can be used to implement public functions like // pthread_getspecific. void *get_tss_value(unsigned int key); struct Thread { … }; LIBC_INLINE_VAR LIBC_THREAD_LOCAL Thread self; // Platforms should implement this function. [[noreturn]] void thread_exit(ThreadReturnValue retval, ThreadStyle style); namespace internal { // Internal namespace containing utilities which are to be used by platform // implementations of threads. // Return the current thread's atexit callback manager. After thread startup // but before running the thread function, platform implementations should // set the "atexit_callback_mgr" field of the thread's attributes to the value // returned by this function. ThreadAtExitCallbackMgr *get_thread_atexit_callback_mgr(); // Call the currently registered thread specific atexit callbacks. Useful for // implementing the thread_exit function. void call_atexit_callbacks(ThreadAttributes *attrib); } // namespace internal } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_H