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<const unsigned char*>(__gtca());
+  const unsigned char* CEECAAEDB =
+      *static_cast<const unsigned char**>(const_cast<void*>(static_cast<const void*>(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",