[libcxx-commits] [libcxx] 6a8099e - [libc++] Port the time functions to z/OS
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Nov 13 07:48:12 PST 2020
Author: Zbigniew Sarbinowski
Date: 2020-11-13T10:47:57-05:00
New Revision: 6a8099e0f61f5440c6a8b9327d255cb5e09e32b2
URL: https://github.com/llvm/llvm-project/commit/6a8099e0f61f5440c6a8b9327d255cb5e09e32b2
DIFF: https://github.com/llvm/llvm-project/commit/6a8099e0f61f5440c6a8b9327d255cb5e09e32b2.diff
LOG: [libc++] Port the time functions to z/OS
This patch adds a shim for missing time functions on z/OS, and adds a
layer of indirection to account for differences in the timespec struct
on different systems.
This was originally committed as 173b51169b83 and reverted in 777ca48c9f08
because the original commit also checked-in unrelated changes.
Differential Revision: https://reviews.llvm.org/D87940
Added:
libcxx/include/support/ibm/nanosleep.h
Modified:
libcxx/include/CMakeLists.txt
libcxx/include/__threading_support
libcxx/src/filesystem/filesystem_common.h
Removed:
################################################################################
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index aab02768e5b7..1c3468e7f595 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -149,6 +149,7 @@ set(files
support/fuchsia/xlocale.h
support/ibm/limits.h
support/ibm/locale_mgmt_aix.h
+ support/ibm/nanosleep.h
support/ibm/support.h
support/ibm/xlocale.h
support/musl/xlocale.h
diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support
index fe770a81c115..bae6fe0b9558 100644
--- a/libcxx/include/__threading_support
+++ b/libcxx/include/__threading_support
@@ -16,6 +16,10 @@
#include <iosfwd>
#include <errno.h>
+#ifdef __MVS__
+# include <support/ibm/nanosleep.h>
+#endif
+
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
#pragma GCC system_header
#endif
diff --git a/libcxx/include/support/ibm/nanosleep.h b/libcxx/include/support/ibm/nanosleep.h
new file mode 100644
index 000000000000..c82f4eb0cd5b
--- /dev/null
+++ b/libcxx/include/support/ibm/nanosleep.h
@@ -0,0 +1,38 @@
+// -*- 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_NANOSLEEP_H
+#define _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
+
+#include <unistd.h>
+
+inline int nanosleep(const struct timespec* req, struct timespec* rem)
+{
+ // The nanosleep() function is not available on z/OS. Therefore, we will call
+ // sleep() to sleep for whole seconds and usleep() to sleep for any remaining
+ // fraction of a second. Any remaining nanoseconds will round up to the next
+ // microsecond.
+
+ useconds_t __micro_sec = (rem->tv_nsec + 999) / 1000;
+ if (__micro_sec > 999999)
+ {
+ ++rem->tv_sec;
+ __micro_sec -= 1000000;
+ }
+ while (rem->tv_sec)
+ rem->tv_sec = sleep(rem->tv_sec);
+ if (__micro_sec) {
+ rem->tv_nsec = __micro_sec * 1000;
+ return usleep(__micro_sec);
+ }
+ rem->tv_nsec = 0;
+ return 0;
+}
+
+#endif // _LIBCPP_SUPPORT_IBM_NANOSLEEP_H
diff --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h
index dc55f93da70c..a82f6511368a 100644
--- a/libcxx/src/filesystem/filesystem_common.h
+++ b/libcxx/src/filesystem/filesystem_common.h
@@ -198,7 +198,8 @@ struct ErrorHandler {
using chrono::duration;
using chrono::duration_cast;
-using TimeSpec = timespec;
+using TimeSpec = struct timespec;
+using TimeVal = struct timeval;
using StatT = struct stat;
template <class FileTimeT, class TimeT,
@@ -381,26 +382,38 @@ struct time_util : time_util_base<FileTimeT, TimeT> {
using fs_time = time_util<file_time_type, time_t, TimeSpec>;
#if defined(__APPLE__)
-TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
-TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
+inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
+inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
+#elif defined(__MVS__)
+inline TimeSpec extract_mtime(StatT const& st) {
+ TimeSpec TS = {st.st_mtime, 0};
+ return TS;
+}
+inline TimeSpec extract_atime(StatT const& st) {
+ TimeSpec TS = {st.st_atime, 0};
+ return TS;
+}
#else
-TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
-TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
+inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
+inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
#endif
-// allow the utimes implementation to compile even it we're not going
-// to use it.
-
-bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
- error_code& ec) {
+inline TimeVal make_timeval(TimeSpec const& ts) {
using namespace chrono;
auto Convert = [](long nsec) {
- using int_type = decltype(std::declval< ::timeval>().tv_usec);
+ using int_type = decltype(std::declval<TimeVal>().tv_usec);
auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
return static_cast<int_type>(dur);
};
- struct ::timeval ConvertedTS[2] = {{TS[0].tv_sec, Convert(TS[0].tv_nsec)},
- {TS[1].tv_sec, Convert(TS[1].tv_nsec)}};
+ TimeVal TV = {};
+ TV.tv_sec = ts.tv_sec;
+ TV.tv_usec = Convert(ts.tv_nsec);
+ return TV;
+}
+
+inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
+ TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])};
if (::utimes(p.c_str(), ConvertedTS) == -1) {
ec = capture_errno();
return true;
More information about the libcxx-commits
mailing list