[SystemZ][ZOS] Provide CLOCK_MONOTONIC alternative

We need CLOCK_MONOTONIC equivalent implementation for z/OS within libc++. The default implementation is asserting.

On z/OS the lack of  'clock_gettime()' and 'time_point()' force us to look for alternatives.
The current proposal is to use `gettimeofday()` for CLOCK_MONOTONIC  which is also used in CLOCK_REALTIME.  This will allow us to skip the assertion with compromised CLOCK_MONOTONIC implementation which will not guarantee to never go back in time because it will use `gettimeofday()` but only when it's set.

Is this a good compromise for platforms which does not support monotonic clock?
Hopefully this will spark the discussion and agreement how to proceed in this situation.

Reviewed By: #libc, ldionne, hubert.reinterpretcast

Differential Revision: https://reviews.llvm.org/D93542

GitOrigin-RevId: cb2d2ae56ae3f0554c40c2d7f231ca5058e4d50c
diff --git a/src/chrono.cpp b/src/chrono.cpp
index 085fbfd..b586f6f 100644
--- a/src/chrono.cpp
+++ b/src/chrono.cpp
@@ -6,9 +6,20 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined(__MVS__)
+// As part of monotonic clock support on z/OS we need macro _LARGE_TIME_API
+// to be defined before any system header to include definition of struct timespec64.
+#define _LARGE_TIME_API
+#endif
+
 #include "chrono"
 #include "cerrno"        // errno
 #include "system_error"  // __throw_system_error
+
+#if defined(__MVS__)
+#include <__support/ibm/gettod_zos.h> // gettimeofdayMonotonic
+#endif
+
 #include <time.h>        // clock_gettime and CLOCK_{MONOTONIC,REALTIME,MONOTONIC_RAW}
 #include "include/apple_availability.h"
 
@@ -218,6 +229,16 @@
   return steady_clock::time_point(steady_clock::duration(dur));
 }
 
+#elif defined(__MVS__)
+
+static steady_clock::time_point __libcpp_steady_clock_now() {
+  struct timespec64 ts;
+  if (0 != gettimeofdayMonotonic(&ts))
+    __throw_system_error(errno, "failed to obtain time of day");
+
+  return steady_clock::time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec));
+}
+
 #elif defined(CLOCK_MONOTONIC)
 
 static steady_clock::time_point __libcpp_steady_clock_now() {