Index: libcxx/include/thread =================================================================== --- libcxx/include/thread +++ libcxx/include/thread @@ -270,6 +270,10 @@ native_handle_type native_handle() _NOEXCEPT {return __t_;} static unsigned hardware_concurrency() _NOEXCEPT; +#ifdef __MVS__ + _LIBCPP_INLINE_VISIBILITY + static unsigned hardware_concurrency_zos() _NOEXCEPT; +#endif }; #ifndef _LIBCPP_CXX03_LANG Index: libcxx/src/CMakeLists.txt =================================================================== --- libcxx/src/CMakeLists.txt +++ libcxx/src/CMakeLists.txt @@ -112,6 +112,7 @@ support/ibm/mbsnrtowcs.cpp support/ibm/wcsnrtombs.cpp support/ibm/xlocale_zos.cpp + support/ibm/hardware_concurrency_zos.cpp ) endif() Index: libcxx/src/support/ibm/hardware_concurrency_zos.cpp =================================================================== --- /dev/null +++ libcxx/src/support/ibm/hardware_concurrency_zos.cpp @@ -0,0 +1,43 @@ +//===------------------------- hardware_concurrency_zos.cpp----------------------------------===// +// +// 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 <__config> + +#ifndef _LIBCPP_HAS_NO_THREADS +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +// The following offsets are from the MVS Data Areas Volumes 1 & 3: +// Volume 1: https://www-01.ibm.com/servers/resourcelink/svc00100.nsf/pages/ +// zosv2r3ga320935/$file/iead100_v2r3.pdf +// Volume 3: https://www-01.ibm.com/servers/resourcelink/svc00100.nsf/pages/ +// zosv2r3ga320938/$file/iead300_v2r3.pdf +// +// In Vol 1, CSD_NUMBER_ONLINE_CPUS is at decimal offset 212 in CSD Mapping +// (also Vol 1), which is pointed to by CVTCSD. +// +// CVTCSD is at decimal offset 660 in CVT Mapping (Vol 1), which is pointed +// to by FLCCVT field of the PSA data area. +// +// FLCCVT is at decimal offset 16 in PSA Mapping (Vol 3), and PSA is at +// address 0. +// +// So, with the 32-bit pointer casts, CSD_NUMBER_ONLINE_CPUS is at +// 0[16/4][660/4][212/4] which is 0[4][165][53]. +// +// Note: z/OS is always upward compatible, so these offsets won't change. + +unsigned +thread::hardware_concurrency_zos() noexcept { + return ((((int* __ptr32* __ptr32* __ptr32)0)[4])[165])[53]; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // !_LIBCPP_HAS_NO_THREADS Index: libcxx/src/thread.cpp =================================================================== --- libcxx/src/thread.cpp +++ libcxx/src/thread.cpp @@ -86,6 +86,8 @@ SYSTEM_INFO info; GetSystemInfo(&info); return info.dwNumberOfProcessors; +#elif defined(__MVS__) + return thread::hardware_concurrency_zos(); #else // defined(CTL_HW) && defined(HW_NCPU) // TODO: grovel through /proc or check cpuid on x86 and similar // instructions on other architectures.