Issue #22043: time.monotonic() is now always available

threading.Lock.acquire(), threading.RLock.acquire() and socket operations now
use a monotonic clock, instead of the system clock, when a timeout is used.
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index b68c177..8f59e03 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -57,7 +57,7 @@
 
 
     if (microseconds > 0) {
-        _PyTime_gettimeofday(&endtime);
+        _PyTime_monotonic(&endtime);
         endtime.tv_sec += microseconds / (1000 * 1000);
         endtime.tv_usec += microseconds % (1000 * 1000);
     }
@@ -83,7 +83,7 @@
             /* If we're using a timeout, recompute the timeout after processing
              * signals, since those can take time.  */
             if (microseconds > 0) {
-                _PyTime_gettimeofday(&curtime);
+                _PyTime_monotonic(&curtime);
                 microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 +
                                 (endtime.tv_usec - curtime.tv_usec));
 
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 5e8e17b..142687b 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -25,7 +25,7 @@
 
 #include "Python.h"
 #include "frameobject.h"        /* for PyFrame_ClearFreeList */
-#include "pytime.h"           /* for _PyTime_gettimeofday, _PyTime_INTERVAL */
+#include "pytime.h"             /* for _PyTime_monotonic, _PyTime_INTERVAL */
 
 /* Get an object's GC head */
 #define AS_GC(o) ((PyGC_Head *)(o)-1)
@@ -919,7 +919,7 @@
         for (i = 0; i < NUM_GENERATIONS; i++)
             PySys_FormatStderr(" %zd",
                               gc_list_size(GEN_HEAD(i)));
-        _PyTime_gettimeofday(&t1);
+        _PyTime_monotonic(&t1);
 
         PySys_WriteStderr("\n");
     }
@@ -1025,7 +1025,7 @@
     }
     if (debug & DEBUG_STATS) {
         _PyTime_timeval t2;
-        _PyTime_gettimeofday(&t2);
+        _PyTime_monotonic(&t2);
 
         if (m == 0 && n == 0)
             PySys_WriteStderr("gc: done");
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index abadd8a..db69d6e 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -680,7 +680,7 @@
         double interval = s->sock_timeout; \
         int has_timeout = s->sock_timeout > 0.0; \
         if (has_timeout) { \
-            _PyTime_gettimeofday(&now); \
+            _PyTime_monotonic(&now); \
             deadline = now; \
             _PyTime_ADD_SECONDS(deadline, s->sock_timeout); \
         } \
@@ -691,7 +691,7 @@
             if (!has_timeout || \
                 (!CHECK_ERRNO(EWOULDBLOCK) && !CHECK_ERRNO(EAGAIN))) \
                 break; \
-            _PyTime_gettimeofday(&now); \
+            _PyTime_monotonic(&now); \
             interval = _PyTime_INTERVAL(now, deadline); \
         } \
     } \
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index c90d8f9..16f4f6d 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -37,10 +37,6 @@
 #endif /* MS_WINDOWS */
 #endif /* !__WATCOMC__ || __QNX__ */
 
-#if defined(__APPLE__)
-#include <mach/mach_time.h>
-#endif
-
 /* Forward declarations */
 static int floatsleep(double);
 static PyObject* floattime(_Py_clock_info_t *info);
@@ -899,122 +895,15 @@
 should not be relied on.");
 #endif /* HAVE_WORKING_TZSET */
 
-#if defined(MS_WINDOWS) || defined(__APPLE__) \
-    || (defined(HAVE_CLOCK_GETTIME) \
-        && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC)))
-#define PYMONOTONIC
-#endif
-
-#ifdef PYMONOTONIC
-static PyObject*
+static PyObject *
 pymonotonic(_Py_clock_info_t *info)
 {
-#if defined(MS_WINDOWS)
-    static ULONGLONG (*GetTickCount64) (void) = NULL;
-    static ULONGLONG (CALLBACK *Py_GetTickCount64)(void);
-    static int has_getickcount64 = -1;
-    double result;
-
-    if (has_getickcount64 == -1) {
-        /* GetTickCount64() was added to Windows Vista */
-        if (winver.dwMajorVersion >= 6) {
-            HINSTANCE hKernel32;
-            hKernel32 = GetModuleHandleW(L"KERNEL32");
-            *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32,
-                                                           "GetTickCount64");
-            has_getickcount64 = (Py_GetTickCount64 != NULL);
-        }
-        else
-            has_getickcount64 = 0;
-    }
-
-    if (has_getickcount64) {
-        ULONGLONG ticks;
-        ticks = Py_GetTickCount64();
-        result = (double)ticks * 1e-3;
-    }
-    else {
-        static DWORD last_ticks = 0;
-        static DWORD n_overflow = 0;
-        DWORD ticks;
-
-        ticks = GetTickCount();
-        if (ticks < last_ticks)
-            n_overflow++;
-        last_ticks = ticks;
-
-        result = ldexp(n_overflow, 32);
-        result += ticks;
-        result *= 1e-3;
-    }
-
-    if (info) {
-        DWORD timeAdjustment, timeIncrement;
-        BOOL isTimeAdjustmentDisabled, ok;
-        if (has_getickcount64)
-            info->implementation = "GetTickCount64()";
-        else
-            info->implementation = "GetTickCount()";
-        info->monotonic = 1;
-        ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
-                                     &isTimeAdjustmentDisabled);
-        if (!ok) {
-            PyErr_SetFromWindowsErr(0);
-            return NULL;
-        }
-        info->resolution = timeIncrement * 1e-7;
-        info->adjustable = 0;
-    }
-    return PyFloat_FromDouble(result);
-
-#elif defined(__APPLE__)
-    static mach_timebase_info_data_t timebase;
-    uint64_t time;
-    double secs;
-
-    if (timebase.denom == 0) {
-        /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
-           fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
-        (void)mach_timebase_info(&timebase);
-    }
-
-    time = mach_absolute_time();
-    secs = (double)time * timebase.numer / timebase.denom * 1e-9;
-    if (info) {
-        info->implementation = "mach_absolute_time()";
-        info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
-        info->monotonic = 1;
-        info->adjustable = 0;
-    }
-    return PyFloat_FromDouble(secs);
-
-#elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC))
-    struct timespec tp;
-#ifdef CLOCK_HIGHRES
-    const clockid_t clk_id = CLOCK_HIGHRES;
-    const char *function = "clock_gettime(CLOCK_HIGHRES)";
-#else
-    const clockid_t clk_id = CLOCK_MONOTONIC;
-    const char *function = "clock_gettime(CLOCK_MONOTONIC)";
-#endif
-
-    if (clock_gettime(clk_id, &tp) != 0) {
-        PyErr_SetFromErrno(PyExc_OSError);
+    _PyTime_timeval tv;
+    if (_PyTime_monotonic_info(&tv, info) < 0) {
+        assert(info != NULL);
         return NULL;
     }
-
-    if (info) {
-        struct timespec res;
-        info->monotonic = 1;
-        info->implementation = function;
-        info->adjustable = 0;
-        if (clock_getres(clk_id, &res) == 0)
-            info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
-        else
-            info->resolution = 1e-9;
-    }
-    return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
-#endif
+    return PyFloat_FromDouble((double)tv.tv_sec + tv.tv_usec * 1e-6);
 }
 
 static PyObject *
@@ -1027,7 +916,6 @@
 "monotonic() -> float\n\
 \n\
 Monotonic clock, cannot go backward.");
-#endif   /* PYMONOTONIC */
 
 static PyObject*
 perf_counter(_Py_clock_info_t *info)
@@ -1035,20 +923,7 @@
 #ifdef WIN32_PERF_COUNTER
     return win_perf_counter(info);
 #else
-
-#ifdef PYMONOTONIC
-    static int use_monotonic = 1;
-
-    if (use_monotonic) {
-        PyObject *res = pymonotonic(info);
-        if (res != NULL)
-            return res;
-        use_monotonic = 0;
-        PyErr_Clear();
-    }
-#endif
-    return floattime(info);
-
+    return pymonotonic(info);
 #endif
 }
 
@@ -1216,10 +1091,8 @@
     else if (strcmp(name, "clock") == 0)
         obj = pyclock(&info);
 #endif
-#ifdef PYMONOTONIC
     else if (strcmp(name, "monotonic") == 0)
         obj = pymonotonic(&info);
-#endif
     else if (strcmp(name, "perf_counter") == 0)
         obj = perf_counter(&info);
     else if (strcmp(name, "process_time") == 0)
@@ -1411,9 +1284,7 @@
 #ifdef HAVE_WORKING_TZSET
     {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
 #endif
-#ifdef PYMONOTONIC
     {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
-#endif
     {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
     {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
     {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},