diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -262,6 +262,7 @@ __string __support/android/locale_bionic.h __support/fuchsia/xlocale.h + __support/ibm/ceeedb.h __support/ibm/gettod_zos.h __support/ibm/limits.h __support/ibm/locale_mgmt_zos.h diff --git a/libcxx/include/__support/ibm/ceeedb.h b/libcxx/include/__support/ibm/ceeedb.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__support/ibm/ceeedb.h @@ -0,0 +1,55 @@ +// -*- 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 _LIBCPP_SUPPORT_IBM_CEEEDB_H +#define _LIBCPP_SUPPORT_IBM_CEEEDB_H + +#ifndef __MVS__ +# error This header should only be included on z/OS +#endif + +#include <__config> +#include <__gfunc.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +static inline unsigned char __libcpp_ceeedb_flags() { + // Offsets can be found in the z/OS Language Environment Vendor Interfaces book + // https://www-01.ibm.com/servers/resourcelink/svc00100.nsf/pages/zOSV2R4sa380688?OpenDocument +#ifndef __64BIT__ + enum { OFFSET_CEECAAEDB = 0x2f0 }; + enum { OFFSET_CEEEDBFLAG1 = 0x08 }; +#else + enum { OFFSET_CEECAAEDB = 0x388 }; + enum { OFFSET_CEEEDBFLAG1 = 0x100 }; +#endif + + // See the zOS Language Environment Vendor Interfaces book for a description + // of the Common Anchor Area (CEECAA), the Enclave Data Block (CEECAAEDB), + // and the EDB flags (CEEEDBFLAG1). + const unsigned char* CEECAA = static_cast(__gtca()); + const unsigned char* CEECAAEDB = + *static_cast(const_cast(static_cast(CEECAA + OFFSET_CEECAAEDB))); + const unsigned char* CEEEDBFLAG1 = (CEECAAEDB + OFFSET_CEEEDBFLAG1); + return *CEEEDBFLAG1; +} + +static inline bool __libcpp_ceeedb_multithread() { + const unsigned char CEEEDBMULTITHREAD = 0x02; + return __libcpp_ceeedb_flags() & CEEEDBMULTITHREAD; +} + +static inline bool __libcpp_ceeedb_posix() { + const unsigned char CEEEDB_POSIX = 0x04; + return __libcpp_ceeedb_flags() & CEEEDB_POSIX; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_SUPPORT_IBM_CEEEDB_H diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -19,6 +19,7 @@ #ifdef __MVS__ # include <__support/ibm/nanosleep.h> +# include <__support/ibm/ceeedb.h> #endif #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER @@ -249,6 +250,21 @@ _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); +#if defined(__MVS__) +// On z/OS some posix functions can be enabled/disabled at runtime. +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_is_threading_api_enabled(); + +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_might_have_multiple_threads(); +#else +_LIBCPP_THREAD_ABI_VISIBILITY +_LIBCPP_CONSTEXPR bool __libcpp_is_threading_api_enabled(); + +_LIBCPP_THREAD_ABI_VISIBILITY +_LIBCPP_CONSTEXPR bool __libcpp_might_have_multiple_threads(); +#endif + #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) struct __libcpp_timed_backoff_policy { @@ -320,6 +336,20 @@ } +#if defined(__MVS__) +/// On z/OS some posix functions can be enabled/disabled at runtime. +/// However, the enabled/disabled status should not change over the life of the process. +bool __libcpp_is_threading_api_enabled() { + static bool __posix_on = __libcpp_ceeedb_posix(); + return __posix_on; +} +bool __libcpp_might_have_multiple_threads() { return __libcpp_ceeedb_multithread(); } +#else +_LIBCPP_CONSTEXPR bool __libcpp_is_threading_api_enabled() { return true; } +// Without any way of checking, we are forced to assume other threads have been spawned. +_LIBCPP_CONSTEXPR bool __libcpp_might_have_multiple_threads() { return true; } +#endif + #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn --- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn +++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn @@ -321,6 +321,7 @@ "__string", "__support/android/locale_bionic.h", "__support/fuchsia/xlocale.h", + "__support/ibm/ceeedb.h", "__support/ibm/gettod_zos.h", "__support/ibm/limits.h", "__support/ibm/locale_mgmt_zos.h",