Home | History | Annotate | Download | only in Modules
      1 /* Time module */
      2 
      3 #include "Python.h"
      4 
      5 #include <ctype.h>
      6 
      7 #ifdef HAVE_SYS_TIMES_H
      8 #include <sys/times.h>
      9 #endif
     10 
     11 #ifdef HAVE_SYS_TYPES_H
     12 #include <sys/types.h>
     13 #endif
     14 
     15 #if defined(HAVE_SYS_RESOURCE_H)
     16 #include <sys/resource.h>
     17 #endif
     18 
     19 #ifdef QUICKWIN
     20 #include <io.h>
     21 #endif
     22 
     23 #if defined(HAVE_PTHREAD_H)
     24 #  include <pthread.h>
     25 #endif
     26 
     27 #if defined(__WATCOMC__) && !defined(__QNX__)
     28 #include <i86.h>
     29 #else
     30 #ifdef MS_WINDOWS
     31 #define WIN32_LEAN_AND_MEAN
     32 #include <windows.h>
     33 #include "pythread.h"
     34 #endif /* MS_WINDOWS */
     35 #endif /* !__WATCOMC__ || __QNX__ */
     36 
     37 #ifdef _Py_MEMORY_SANITIZER
     38 # include <sanitizer/msan_interface.h>
     39 #endif
     40 
     41 #ifdef _MSC_VER
     42 #define _Py_timezone _timezone
     43 #define _Py_daylight _daylight
     44 #define _Py_tzname _tzname
     45 #else
     46 #define _Py_timezone timezone
     47 #define _Py_daylight daylight
     48 #define _Py_tzname tzname
     49 #endif
     50 
     51 #define SEC_TO_NS (1000 * 1000 * 1000)
     52 
     53 /* Forward declarations */
     54 static int pysleep(_PyTime_t);
     55 
     56 
     57 static PyObject*
     58 _PyFloat_FromPyTime(_PyTime_t t)
     59 {
     60     double d = _PyTime_AsSecondsDouble(t);
     61     return PyFloat_FromDouble(d);
     62 }
     63 
     64 
     65 static PyObject *
     66 time_time(PyObject *self, PyObject *unused)
     67 {
     68     _PyTime_t t = _PyTime_GetSystemClock();
     69     return _PyFloat_FromPyTime(t);
     70 }
     71 
     72 
     73 PyDoc_STRVAR(time_doc,
     74 "time() -> floating point number\n\
     75 \n\
     76 Return the current time in seconds since the Epoch.\n\
     77 Fractions of a second may be present if the system clock provides them.");
     78 
     79 static PyObject *
     80 time_time_ns(PyObject *self, PyObject *unused)
     81 {
     82     _PyTime_t t = _PyTime_GetSystemClock();
     83     return _PyTime_AsNanosecondsObject(t);
     84 }
     85 
     86 PyDoc_STRVAR(time_ns_doc,
     87 "time_ns() -> int\n\
     88 \n\
     89 Return the current time in nanoseconds since the Epoch.");
     90 
     91 #if defined(HAVE_CLOCK)
     92 
     93 #ifndef CLOCKS_PER_SEC
     94 #  ifdef CLK_TCK
     95 #    define CLOCKS_PER_SEC CLK_TCK
     96 #  else
     97 #    define CLOCKS_PER_SEC 1000000
     98 #  endif
     99 #endif
    100 
    101 static int
    102 _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
    103 {
    104     static int initialized = 0;
    105     clock_t ticks;
    106 
    107     if (!initialized) {
    108         initialized = 1;
    109 
    110         /* must sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC)
    111            above cannot overflow */
    112         if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) {
    113             PyErr_SetString(PyExc_OverflowError,
    114                             "CLOCKS_PER_SEC is too large");
    115             return -1;
    116         }
    117     }
    118 
    119     if (info) {
    120         info->implementation = "clock()";
    121         info->resolution = 1.0 / (double)CLOCKS_PER_SEC;
    122         info->monotonic = 1;
    123         info->adjustable = 0;
    124     }
    125 
    126     ticks = clock();
    127     if (ticks == (clock_t)-1) {
    128         PyErr_SetString(PyExc_RuntimeError,
    129                         "the processor time used is not available "
    130                         "or its value cannot be represented");
    131         return -1;
    132     }
    133     *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC);
    134     return 0;
    135 }
    136 #endif /* HAVE_CLOCK */
    137 
    138 static PyObject*
    139 perf_counter(_Py_clock_info_t *info)
    140 {
    141     _PyTime_t t;
    142     if (_PyTime_GetPerfCounterWithInfo(&t, info) < 0) {
    143         return NULL;
    144     }
    145     return _PyFloat_FromPyTime(t);
    146 }
    147 
    148 #if defined(MS_WINDOWS) || defined(HAVE_CLOCK)
    149 #define PYCLOCK
    150 static PyObject*
    151 pyclock(_Py_clock_info_t *info)
    152 {
    153     if (PyErr_WarnEx(PyExc_DeprecationWarning,
    154                       "time.clock has been deprecated in Python 3.3 and will "
    155                       "be removed from Python 3.8: "
    156                       "use time.perf_counter or time.process_time "
    157                       "instead", 1) < 0) {
    158         return NULL;
    159     }
    160 
    161 #ifdef MS_WINDOWS
    162     return perf_counter(info);
    163 #else
    164     _PyTime_t t;
    165     if (_PyTime_GetClockWithInfo(&t, info) < 0) {
    166         return NULL;
    167     }
    168     return _PyFloat_FromPyTime(t);
    169 #endif
    170 }
    171 
    172 static PyObject *
    173 time_clock(PyObject *self, PyObject *unused)
    174 {
    175     return pyclock(NULL);
    176 }
    177 
    178 PyDoc_STRVAR(clock_doc,
    179 "clock() -> floating point number\n\
    180 \n\
    181 Return the CPU time or real time since the start of the process or since\n\
    182 the first call to clock().  This has as much precision as the system\n\
    183 records.");
    184 #endif
    185 
    186 #ifdef HAVE_CLOCK_GETTIME
    187 static PyObject *
    188 time_clock_gettime(PyObject *self, PyObject *args)
    189 {
    190     int ret;
    191     int clk_id;
    192     struct timespec tp;
    193 
    194     if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
    195         return NULL;
    196     }
    197 
    198     ret = clock_gettime((clockid_t)clk_id, &tp);
    199     if (ret != 0) {
    200         PyErr_SetFromErrno(PyExc_OSError);
    201         return NULL;
    202     }
    203     return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
    204 }
    205 
    206 PyDoc_STRVAR(clock_gettime_doc,
    207 "clock_gettime(clk_id) -> float\n\
    208 \n\
    209 Return the time of the specified clock clk_id.");
    210 
    211 static PyObject *
    212 time_clock_gettime_ns(PyObject *self, PyObject *args)
    213 {
    214     int ret;
    215     int clk_id;
    216     struct timespec ts;
    217     _PyTime_t t;
    218 
    219     if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
    220         return NULL;
    221     }
    222 
    223     ret = clock_gettime((clockid_t)clk_id, &ts);
    224     if (ret != 0) {
    225         PyErr_SetFromErrno(PyExc_OSError);
    226         return NULL;
    227     }
    228     if (_PyTime_FromTimespec(&t, &ts) < 0) {
    229         return NULL;
    230     }
    231     return _PyTime_AsNanosecondsObject(t);
    232 }
    233 
    234 PyDoc_STRVAR(clock_gettime_ns_doc,
    235 "clock_gettime_ns(clk_id) -> int\n\
    236 \n\
    237 Return the time of the specified clock clk_id as nanoseconds.");
    238 #endif   /* HAVE_CLOCK_GETTIME */
    239 
    240 #ifdef HAVE_CLOCK_SETTIME
    241 static PyObject *
    242 time_clock_settime(PyObject *self, PyObject *args)
    243 {
    244     int clk_id;
    245     PyObject *obj;
    246     _PyTime_t t;
    247     struct timespec tp;
    248     int ret;
    249 
    250     if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj))
    251         return NULL;
    252 
    253     if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0)
    254         return NULL;
    255 
    256     if (_PyTime_AsTimespec(t, &tp) == -1)
    257         return NULL;
    258 
    259     ret = clock_settime((clockid_t)clk_id, &tp);
    260     if (ret != 0) {
    261         PyErr_SetFromErrno(PyExc_OSError);
    262         return NULL;
    263     }
    264     Py_RETURN_NONE;
    265 }
    266 
    267 PyDoc_STRVAR(clock_settime_doc,
    268 "clock_settime(clk_id, time)\n\
    269 \n\
    270 Set the time of the specified clock clk_id.");
    271 
    272 static PyObject *
    273 time_clock_settime_ns(PyObject *self, PyObject *args)
    274 {
    275     int clk_id;
    276     PyObject *obj;
    277     _PyTime_t t;
    278     struct timespec ts;
    279     int ret;
    280 
    281     if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) {
    282         return NULL;
    283     }
    284 
    285     if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
    286         return NULL;
    287     }
    288     if (_PyTime_AsTimespec(t, &ts) == -1) {
    289         return NULL;
    290     }
    291 
    292     ret = clock_settime((clockid_t)clk_id, &ts);
    293     if (ret != 0) {
    294         PyErr_SetFromErrno(PyExc_OSError);
    295         return NULL;
    296     }
    297     Py_RETURN_NONE;
    298 }
    299 
    300 PyDoc_STRVAR(clock_settime_ns_doc,
    301 "clock_settime_ns(clk_id, time)\n\
    302 \n\
    303 Set the time of the specified clock clk_id with nanoseconds.");
    304 #endif   /* HAVE_CLOCK_SETTIME */
    305 
    306 #ifdef HAVE_CLOCK_GETRES
    307 static PyObject *
    308 time_clock_getres(PyObject *self, PyObject *args)
    309 {
    310     int ret;
    311     int clk_id;
    312     struct timespec tp;
    313 
    314     if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id))
    315         return NULL;
    316 
    317     ret = clock_getres((clockid_t)clk_id, &tp);
    318     if (ret != 0) {
    319         PyErr_SetFromErrno(PyExc_OSError);
    320         return NULL;
    321     }
    322 
    323     return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
    324 }
    325 
    326 PyDoc_STRVAR(clock_getres_doc,
    327 "clock_getres(clk_id) -> floating point number\n\
    328 \n\
    329 Return the resolution (precision) of the specified clock clk_id.");
    330 #endif   /* HAVE_CLOCK_GETRES */
    331 
    332 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
    333 static PyObject *
    334 time_pthread_getcpuclockid(PyObject *self, PyObject *args)
    335 {
    336     unsigned long thread_id;
    337     int err;
    338     clockid_t clk_id;
    339     if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) {
    340         return NULL;
    341     }
    342     err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id);
    343     if (err) {
    344         errno = err;
    345         PyErr_SetFromErrno(PyExc_OSError);
    346         return NULL;
    347     }
    348 #ifdef _Py_MEMORY_SANITIZER
    349     __msan_unpoison(&clk_id, sizeof(clk_id));
    350 #endif
    351     return PyLong_FromLong(clk_id);
    352 }
    353 
    354 PyDoc_STRVAR(pthread_getcpuclockid_doc,
    355 "pthread_getcpuclockid(thread_id) -> int\n\
    356 \n\
    357 Return the clk_id of a thread's CPU time clock.");
    358 #endif /* HAVE_PTHREAD_GETCPUCLOCKID */
    359 
    360 static PyObject *
    361 time_sleep(PyObject *self, PyObject *obj)
    362 {
    363     _PyTime_t secs;
    364     if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_TIMEOUT))
    365         return NULL;
    366     if (secs < 0) {
    367         PyErr_SetString(PyExc_ValueError,
    368                         "sleep length must be non-negative");
    369         return NULL;
    370     }
    371     if (pysleep(secs) != 0)
    372         return NULL;
    373     Py_RETURN_NONE;
    374 }
    375 
    376 PyDoc_STRVAR(sleep_doc,
    377 "sleep(seconds)\n\
    378 \n\
    379 Delay execution for a given number of seconds.  The argument may be\n\
    380 a floating point number for subsecond precision.");
    381 
    382 static PyStructSequence_Field struct_time_type_fields[] = {
    383     {"tm_year", "year, for example, 1993"},
    384     {"tm_mon", "month of year, range [1, 12]"},
    385     {"tm_mday", "day of month, range [1, 31]"},
    386     {"tm_hour", "hours, range [0, 23]"},
    387     {"tm_min", "minutes, range [0, 59]"},
    388     {"tm_sec", "seconds, range [0, 61])"},
    389     {"tm_wday", "day of week, range [0, 6], Monday is 0"},
    390     {"tm_yday", "day of year, range [1, 366]"},
    391     {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"},
    392     {"tm_zone", "abbreviation of timezone name"},
    393     {"tm_gmtoff", "offset from UTC in seconds"},
    394     {0}
    395 };
    396 
    397 static PyStructSequence_Desc struct_time_type_desc = {
    398     "time.struct_time",
    399     "The time value as returned by gmtime(), localtime(), and strptime(), and\n"
    400     " accepted by asctime(), mktime() and strftime().  May be considered as a\n"
    401     " sequence of 9 integers.\n\n"
    402     " Note that several fields' values are not the same as those defined by\n"
    403     " the C language standard for struct tm.  For example, the value of the\n"
    404     " field tm_year is the actual year, not year - 1900.  See individual\n"
    405     " fields' descriptions for details.",
    406     struct_time_type_fields,
    407     9,
    408 };
    409 
    410 static int initialized;
    411 static PyTypeObject StructTimeType;
    412 
    413 
    414 static PyObject *
    415 tmtotuple(struct tm *p
    416 #ifndef HAVE_STRUCT_TM_TM_ZONE
    417         , const char *zone, time_t gmtoff
    418 #endif
    419 )
    420 {
    421     PyObject *v = PyStructSequence_New(&StructTimeType);
    422     if (v == NULL)
    423         return NULL;
    424 
    425 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
    426 
    427     SET(0, p->tm_year + 1900);
    428     SET(1, p->tm_mon + 1);         /* Want January == 1 */
    429     SET(2, p->tm_mday);
    430     SET(3, p->tm_hour);
    431     SET(4, p->tm_min);
    432     SET(5, p->tm_sec);
    433     SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
    434     SET(7, p->tm_yday + 1);        /* Want January, 1 == 1 */
    435     SET(8, p->tm_isdst);
    436 #ifdef HAVE_STRUCT_TM_TM_ZONE
    437     PyStructSequence_SET_ITEM(v, 9,
    438         PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape"));
    439     SET(10, p->tm_gmtoff);
    440 #else
    441     PyStructSequence_SET_ITEM(v, 9,
    442         PyUnicode_DecodeLocale(zone, "surrogateescape"));
    443     PyStructSequence_SET_ITEM(v, 10, _PyLong_FromTime_t(gmtoff));
    444 #endif /* HAVE_STRUCT_TM_TM_ZONE */
    445 #undef SET
    446     if (PyErr_Occurred()) {
    447         Py_XDECREF(v);
    448         return NULL;
    449     }
    450 
    451     return v;
    452 }
    453 
    454 /* Parse arg tuple that can contain an optional float-or-None value;
    455    format needs to be "|O:name".
    456    Returns non-zero on success (parallels PyArg_ParseTuple).
    457 */
    458 static int
    459 parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
    460 {
    461     PyObject *ot = NULL;
    462     time_t whent;
    463 
    464     if (!PyArg_ParseTuple(args, format, &ot))
    465         return 0;
    466     if (ot == NULL || ot == Py_None) {
    467         whent = time(NULL);
    468     }
    469     else {
    470         if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1)
    471             return 0;
    472     }
    473     *pwhen = whent;
    474     return 1;
    475 }
    476 
    477 static PyObject *
    478 time_gmtime(PyObject *self, PyObject *args)
    479 {
    480     time_t when;
    481     struct tm buf;
    482 
    483     if (!parse_time_t_args(args, "|O:gmtime", &when))
    484         return NULL;
    485 
    486     errno = 0;
    487     if (_PyTime_gmtime(when, &buf) != 0)
    488         return NULL;
    489 #ifdef HAVE_STRUCT_TM_TM_ZONE
    490     return tmtotuple(&buf);
    491 #else
    492     return tmtotuple(&buf, "UTC", 0);
    493 #endif
    494 }
    495 
    496 #ifndef HAVE_TIMEGM
    497 static time_t
    498 timegm(struct tm *p)
    499 {
    500     /* XXX: the following implementation will not work for tm_year < 1970.
    501        but it is likely that platforms that don't have timegm do not support
    502        negative timestamps anyways. */
    503     return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 +
    504         (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 -
    505         ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400;
    506 }
    507 #endif
    508 
    509 PyDoc_STRVAR(gmtime_doc,
    510 "gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\
    511                        tm_sec, tm_wday, tm_yday, tm_isdst)\n\
    512 \n\
    513 Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
    514 GMT).  When 'seconds' is not passed in, convert the current time instead.\n\
    515 \n\
    516 If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
    517 attributes only.");
    518 
    519 static PyObject *
    520 time_localtime(PyObject *self, PyObject *args)
    521 {
    522     time_t when;
    523     struct tm buf;
    524 
    525     if (!parse_time_t_args(args, "|O:localtime", &when))
    526         return NULL;
    527     if (_PyTime_localtime(when, &buf) != 0)
    528         return NULL;
    529 #ifdef HAVE_STRUCT_TM_TM_ZONE
    530     return tmtotuple(&buf);
    531 #else
    532     {
    533         struct tm local = buf;
    534         char zone[100];
    535         time_t gmtoff;
    536         strftime(zone, sizeof(zone), "%Z", &buf);
    537         gmtoff = timegm(&buf) - when;
    538         return tmtotuple(&local, zone, gmtoff);
    539     }
    540 #endif
    541 }
    542 
    543 PyDoc_STRVAR(localtime_doc,
    544 "localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
    545                           tm_sec,tm_wday,tm_yday,tm_isdst)\n\
    546 \n\
    547 Convert seconds since the Epoch to a time tuple expressing local time.\n\
    548 When 'seconds' is not passed in, convert the current time instead.");
    549 
    550 /* Convert 9-item tuple to tm structure.  Return 1 on success, set
    551  * an exception and return 0 on error.
    552  */
    553 static int
    554 gettmarg(PyObject *args, struct tm *p, const char *format)
    555 {
    556     int y;
    557 
    558     memset((void *) p, '\0', sizeof(struct tm));
    559 
    560     if (!PyTuple_Check(args)) {
    561         PyErr_SetString(PyExc_TypeError,
    562                         "Tuple or struct_time argument required");
    563         return 0;
    564     }
    565 
    566     if (!PyArg_ParseTuple(args, format,
    567                           &y, &p->tm_mon, &p->tm_mday,
    568                           &p->tm_hour, &p->tm_min, &p->tm_sec,
    569                           &p->tm_wday, &p->tm_yday, &p->tm_isdst))
    570         return 0;
    571 
    572     if (y < INT_MIN + 1900) {
    573         PyErr_SetString(PyExc_OverflowError, "year out of range");
    574         return 0;
    575     }
    576 
    577     p->tm_year = y - 1900;
    578     p->tm_mon--;
    579     p->tm_wday = (p->tm_wday + 1) % 7;
    580     p->tm_yday--;
    581 #ifdef HAVE_STRUCT_TM_TM_ZONE
    582     if (Py_TYPE(args) == &StructTimeType) {
    583         PyObject *item;
    584         item = PyTuple_GET_ITEM(args, 9);
    585         p->tm_zone = item == Py_None ? NULL : (char*)PyUnicode_AsUTF8(item);
    586         item = PyTuple_GET_ITEM(args, 10);
    587         p->tm_gmtoff = item == Py_None ? 0 : PyLong_AsLong(item);
    588         if (PyErr_Occurred())
    589             return 0;
    590     }
    591 #endif /* HAVE_STRUCT_TM_TM_ZONE */
    592     return 1;
    593 }
    594 
    595 /* Check values of the struct tm fields before it is passed to strftime() and
    596  * asctime().  Return 1 if all values are valid, otherwise set an exception
    597  * and returns 0.
    598  */
    599 static int
    600 checktm(struct tm* buf)
    601 {
    602     /* Checks added to make sure strftime() and asctime() does not crash Python by
    603        indexing blindly into some array for a textual representation
    604        by some bad index (fixes bug #897625 and #6608).
    605 
    606        Also support values of zero from Python code for arguments in which
    607        that is out of range by forcing that value to the lowest value that
    608        is valid (fixed bug #1520914).
    609 
    610        Valid ranges based on what is allowed in struct tm:
    611 
    612        - tm_year: [0, max(int)] (1)
    613        - tm_mon: [0, 11] (2)
    614        - tm_mday: [1, 31]
    615        - tm_hour: [0, 23]
    616        - tm_min: [0, 59]
    617        - tm_sec: [0, 60]
    618        - tm_wday: [0, 6] (1)
    619        - tm_yday: [0, 365] (2)
    620        - tm_isdst: [-max(int), max(int)]
    621 
    622        (1) gettmarg() handles bounds-checking.
    623        (2) Python's acceptable range is one greater than the range in C,
    624        thus need to check against automatic decrement by gettmarg().
    625     */
    626     if (buf->tm_mon == -1)
    627         buf->tm_mon = 0;
    628     else if (buf->tm_mon < 0 || buf->tm_mon > 11) {
    629         PyErr_SetString(PyExc_ValueError, "month out of range");
    630         return 0;
    631     }
    632     if (buf->tm_mday == 0)
    633         buf->tm_mday = 1;
    634     else if (buf->tm_mday < 0 || buf->tm_mday > 31) {
    635         PyErr_SetString(PyExc_ValueError, "day of month out of range");
    636         return 0;
    637     }
    638     if (buf->tm_hour < 0 || buf->tm_hour > 23) {
    639         PyErr_SetString(PyExc_ValueError, "hour out of range");
    640         return 0;
    641     }
    642     if (buf->tm_min < 0 || buf->tm_min > 59) {
    643         PyErr_SetString(PyExc_ValueError, "minute out of range");
    644         return 0;
    645     }
    646     if (buf->tm_sec < 0 || buf->tm_sec > 61) {
    647         PyErr_SetString(PyExc_ValueError, "seconds out of range");
    648         return 0;
    649     }
    650     /* tm_wday does not need checking of its upper-bound since taking
    651     ``% 7`` in gettmarg() automatically restricts the range. */
    652     if (buf->tm_wday < 0) {
    653         PyErr_SetString(PyExc_ValueError, "day of week out of range");
    654         return 0;
    655     }
    656     if (buf->tm_yday == -1)
    657         buf->tm_yday = 0;
    658     else if (buf->tm_yday < 0 || buf->tm_yday > 365) {
    659         PyErr_SetString(PyExc_ValueError, "day of year out of range");
    660         return 0;
    661     }
    662     return 1;
    663 }
    664 
    665 #ifdef MS_WINDOWS
    666    /* wcsftime() doesn't format correctly time zones, see issue #10653 */
    667 #  undef HAVE_WCSFTIME
    668 #endif
    669 #define STRFTIME_FORMAT_CODES \
    670 "Commonly used format codes:\n\
    671 \n\
    672 %Y  Year with century as a decimal number.\n\
    673 %m  Month as a decimal number [01,12].\n\
    674 %d  Day of the month as a decimal number [01,31].\n\
    675 %H  Hour (24-hour clock) as a decimal number [00,23].\n\
    676 %M  Minute as a decimal number [00,59].\n\
    677 %S  Second as a decimal number [00,61].\n\
    678 %z  Time zone offset from UTC.\n\
    679 %a  Locale's abbreviated weekday name.\n\
    680 %A  Locale's full weekday name.\n\
    681 %b  Locale's abbreviated month name.\n\
    682 %B  Locale's full month name.\n\
    683 %c  Locale's appropriate date and time representation.\n\
    684 %I  Hour (12-hour clock) as a decimal number [01,12].\n\
    685 %p  Locale's equivalent of either AM or PM.\n\
    686 \n\
    687 Other codes may be available on your platform.  See documentation for\n\
    688 the C library strftime function.\n"
    689 
    690 #ifdef HAVE_STRFTIME
    691 #ifdef HAVE_WCSFTIME
    692 #define time_char wchar_t
    693 #define format_time wcsftime
    694 #define time_strlen wcslen
    695 #else
    696 #define time_char char
    697 #define format_time strftime
    698 #define time_strlen strlen
    699 #endif
    700 
    701 static PyObject *
    702 time_strftime(PyObject *self, PyObject *args)
    703 {
    704     PyObject *tup = NULL;
    705     struct tm buf;
    706     const time_char *fmt;
    707 #ifdef HAVE_WCSFTIME
    708     wchar_t *format;
    709 #else
    710     PyObject *format;
    711 #endif
    712     PyObject *format_arg;
    713     size_t fmtlen, buflen;
    714     time_char *outbuf = NULL;
    715     size_t i;
    716     PyObject *ret = NULL;
    717 
    718     memset((void *) &buf, '\0', sizeof(buf));
    719 
    720     /* Will always expect a unicode string to be passed as format.
    721        Given that there's no str type anymore in py3k this seems safe.
    722     */
    723     if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup))
    724         return NULL;
    725 
    726     if (tup == NULL) {
    727         time_t tt = time(NULL);
    728         if (_PyTime_localtime(tt, &buf) != 0)
    729             return NULL;
    730     }
    731     else if (!gettmarg(tup, &buf,
    732                        "iiiiiiiii;strftime(): illegal time tuple argument") ||
    733              !checktm(&buf))
    734     {
    735         return NULL;
    736     }
    737 
    738 #if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX)
    739     if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
    740         PyErr_SetString(PyExc_ValueError,
    741                         "strftime() requires year in [1; 9999]");
    742         return NULL;
    743     }
    744 #endif
    745 
    746     /* Normalize tm_isdst just in case someone foolishly implements %Z
    747        based on the assumption that tm_isdst falls within the range of
    748        [-1, 1] */
    749     if (buf.tm_isdst < -1)
    750         buf.tm_isdst = -1;
    751     else if (buf.tm_isdst > 1)
    752         buf.tm_isdst = 1;
    753 
    754 #ifdef HAVE_WCSFTIME
    755     format = PyUnicode_AsWideCharString(format_arg, NULL);
    756     if (format == NULL)
    757         return NULL;
    758     fmt = format;
    759 #else
    760     /* Convert the unicode string to an ascii one */
    761     format = PyUnicode_EncodeLocale(format_arg, "surrogateescape");
    762     if (format == NULL)
    763         return NULL;
    764     fmt = PyBytes_AS_STRING(format);
    765 #endif
    766 
    767 #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME)
    768     /* check that the format string contains only valid directives */
    769     for (outbuf = strchr(fmt, '%');
    770         outbuf != NULL;
    771         outbuf = strchr(outbuf+2, '%'))
    772     {
    773         if (outbuf[1] == '#')
    774             ++outbuf; /* not documented by python, */
    775         if (outbuf[1] == '\0')
    776             break;
    777         if ((outbuf[1] == 'y') && buf.tm_year < 0) {
    778             PyErr_SetString(PyExc_ValueError,
    779                         "format %y requires year >= 1900 on Windows");
    780             Py_DECREF(format);
    781             return NULL;
    782         }
    783     }
    784 #elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME)
    785     for (outbuf = wcschr(fmt, '%');
    786         outbuf != NULL;
    787         outbuf = wcschr(outbuf+2, '%'))
    788     {
    789         if (outbuf[1] == L'\0')
    790             break;
    791         /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0))
    792            returns "0/" instead of "99" */
    793         if (outbuf[1] == L'y' && buf.tm_year < 0) {
    794             PyErr_SetString(PyExc_ValueError,
    795                             "format %y requires year >= 1900 on AIX");
    796             PyMem_Free(format);
    797             return NULL;
    798         }
    799     }
    800 #endif
    801 
    802     fmtlen = time_strlen(fmt);
    803 
    804     /* I hate these functions that presume you know how big the output
    805      * will be ahead of time...
    806      */
    807     for (i = 1024; ; i += i) {
    808         outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
    809         if (outbuf == NULL) {
    810             PyErr_NoMemory();
    811             break;
    812         }
    813 #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
    814         errno = 0;
    815 #endif
    816         _Py_BEGIN_SUPPRESS_IPH
    817         buflen = format_time(outbuf, i, fmt, &buf);
    818         _Py_END_SUPPRESS_IPH
    819 #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
    820         /* VisualStudio .NET 2005 does this properly */
    821         if (buflen == 0 && errno == EINVAL) {
    822             PyErr_SetString(PyExc_ValueError, "Invalid format string");
    823             PyMem_Free(outbuf);
    824             break;
    825         }
    826 #endif
    827         if (buflen > 0 || i >= 256 * fmtlen) {
    828             /* If the buffer is 256 times as long as the format,
    829                it's probably not failing for lack of room!
    830                More likely, the format yields an empty result,
    831                e.g. an empty format, or %Z when the timezone
    832                is unknown. */
    833 #ifdef HAVE_WCSFTIME
    834             ret = PyUnicode_FromWideChar(outbuf, buflen);
    835 #else
    836             ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape");
    837 #endif
    838             PyMem_Free(outbuf);
    839             break;
    840         }
    841         PyMem_Free(outbuf);
    842     }
    843 #ifdef HAVE_WCSFTIME
    844     PyMem_Free(format);
    845 #else
    846     Py_DECREF(format);
    847 #endif
    848     return ret;
    849 }
    850 
    851 #undef time_char
    852 #undef format_time
    853 PyDoc_STRVAR(strftime_doc,
    854 "strftime(format[, tuple]) -> string\n\
    855 \n\
    856 Convert a time tuple to a string according to a format specification.\n\
    857 See the library reference manual for formatting codes. When the time tuple\n\
    858 is not present, current time as returned by localtime() is used.\n\
    859 \n" STRFTIME_FORMAT_CODES);
    860 #endif /* HAVE_STRFTIME */
    861 
    862 static PyObject *
    863 time_strptime(PyObject *self, PyObject *args)
    864 {
    865     PyObject *module, *func, *result;
    866     _Py_IDENTIFIER(_strptime_time);
    867 
    868     module = PyImport_ImportModuleNoBlock("_strptime");
    869     if (!module)
    870         return NULL;
    871 
    872     func = _PyObject_GetAttrId(module, &PyId__strptime_time);
    873     Py_DECREF(module);
    874     if (!func) {
    875         return NULL;
    876     }
    877 
    878     result = PyObject_Call(func, args, NULL);
    879     Py_DECREF(func);
    880     return result;
    881 }
    882 
    883 
    884 PyDoc_STRVAR(strptime_doc,
    885 "strptime(string, format) -> struct_time\n\
    886 \n\
    887 Parse a string to a time tuple according to a format specification.\n\
    888 See the library reference manual for formatting codes (same as\n\
    889 strftime()).\n\
    890 \n" STRFTIME_FORMAT_CODES);
    891 
    892 static PyObject *
    893 _asctime(struct tm *timeptr)
    894 {
    895     /* Inspired by Open Group reference implementation available at
    896      * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */
    897     static const char wday_name[7][4] = {
    898         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
    899     };
    900     static const char mon_name[12][4] = {
    901         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    902         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    903     };
    904     return PyUnicode_FromFormat(
    905         "%s %s%3d %.2d:%.2d:%.2d %d",
    906         wday_name[timeptr->tm_wday],
    907         mon_name[timeptr->tm_mon],
    908         timeptr->tm_mday, timeptr->tm_hour,
    909         timeptr->tm_min, timeptr->tm_sec,
    910         1900 + timeptr->tm_year);
    911 }
    912 
    913 static PyObject *
    914 time_asctime(PyObject *self, PyObject *args)
    915 {
    916     PyObject *tup = NULL;
    917     struct tm buf;
    918 
    919     if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
    920         return NULL;
    921     if (tup == NULL) {
    922         time_t tt = time(NULL);
    923         if (_PyTime_localtime(tt, &buf) != 0)
    924             return NULL;
    925     }
    926     else if (!gettmarg(tup, &buf,
    927                        "iiiiiiiii;asctime(): illegal time tuple argument") ||
    928              !checktm(&buf))
    929     {
    930         return NULL;
    931     }
    932     return _asctime(&buf);
    933 }
    934 
    935 PyDoc_STRVAR(asctime_doc,
    936 "asctime([tuple]) -> string\n\
    937 \n\
    938 Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
    939 When the time tuple is not present, current time as returned by localtime()\n\
    940 is used.");
    941 
    942 static PyObject *
    943 time_ctime(PyObject *self, PyObject *args)
    944 {
    945     time_t tt;
    946     struct tm buf;
    947     if (!parse_time_t_args(args, "|O:ctime", &tt))
    948         return NULL;
    949     if (_PyTime_localtime(tt, &buf) != 0)
    950         return NULL;
    951     return _asctime(&buf);
    952 }
    953 
    954 PyDoc_STRVAR(ctime_doc,
    955 "ctime(seconds) -> string\n\
    956 \n\
    957 Convert a time in seconds since the Epoch to a string in local time.\n\
    958 This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
    959 not present, current time as returned by localtime() is used.");
    960 
    961 #ifdef HAVE_MKTIME
    962 static PyObject *
    963 time_mktime(PyObject *self, PyObject *tup)
    964 {
    965     struct tm buf;
    966     time_t tt;
    967     if (!gettmarg(tup, &buf,
    968                   "iiiiiiiii;mktime(): illegal time tuple argument"))
    969     {
    970         return NULL;
    971     }
    972 #ifdef _AIX
    973     /* year < 1902 or year > 2037 */
    974     if (buf.tm_year < 2 || buf.tm_year > 137) {
    975         /* Issue #19748: On AIX, mktime() doesn't report overflow error for
    976          * timestamp < -2^31 or timestamp > 2**31-1. */
    977         PyErr_SetString(PyExc_OverflowError,
    978                         "mktime argument out of range");
    979         return NULL;
    980     }
    981 #else
    982     buf.tm_wday = -1;  /* sentinel; original value ignored */
    983 #endif
    984     tt = mktime(&buf);
    985     /* Return value of -1 does not necessarily mean an error, but tm_wday
    986      * cannot remain set to -1 if mktime succeeded. */
    987     if (tt == (time_t)(-1)
    988 #ifndef _AIX
    989         /* Return value of -1 does not necessarily mean an error, but
    990          * tm_wday cannot remain set to -1 if mktime succeeded. */
    991         && buf.tm_wday == -1
    992 #else
    993         /* on AIX, tm_wday is always sets, even on error */
    994 #endif
    995        )
    996     {
    997         PyErr_SetString(PyExc_OverflowError,
    998                         "mktime argument out of range");
    999         return NULL;
   1000     }
   1001     return PyFloat_FromDouble((double)tt);
   1002 }
   1003 
   1004 PyDoc_STRVAR(mktime_doc,
   1005 "mktime(tuple) -> floating point number\n\
   1006 \n\
   1007 Convert a time tuple in local time to seconds since the Epoch.\n\
   1008 Note that mktime(gmtime(0)) will not generally return zero for most\n\
   1009 time zones; instead the returned value will either be equal to that\n\
   1010 of the timezone or altzone attributes on the time module.");
   1011 #endif /* HAVE_MKTIME */
   1012 
   1013 #ifdef HAVE_WORKING_TZSET
   1014 static int init_timezone(PyObject *module);
   1015 
   1016 static PyObject *
   1017 time_tzset(PyObject *self, PyObject *unused)
   1018 {
   1019     PyObject* m;
   1020 
   1021     m = PyImport_ImportModuleNoBlock("time");
   1022     if (m == NULL) {
   1023         return NULL;
   1024     }
   1025 
   1026     tzset();
   1027 
   1028     /* Reset timezone, altzone, daylight and tzname */
   1029     if (init_timezone(m) < 0) {
   1030          return NULL;
   1031     }
   1032     Py_DECREF(m);
   1033     if (PyErr_Occurred())
   1034         return NULL;
   1035 
   1036     Py_RETURN_NONE;
   1037 }
   1038 
   1039 PyDoc_STRVAR(tzset_doc,
   1040 "tzset()\n\
   1041 \n\
   1042 Initialize, or reinitialize, the local timezone to the value stored in\n\
   1043 os.environ['TZ']. The TZ environment variable should be specified in\n\
   1044 standard Unix timezone format as documented in the tzset man page\n\
   1045 (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
   1046 fall back to UTC. If the TZ environment variable is not set, the local\n\
   1047 timezone is set to the systems best guess of wallclock time.\n\
   1048 Changing the TZ environment variable without calling tzset *may* change\n\
   1049 the local timezone used by methods such as localtime, but this behaviour\n\
   1050 should not be relied on.");
   1051 #endif /* HAVE_WORKING_TZSET */
   1052 
   1053 static PyObject *
   1054 time_monotonic(PyObject *self, PyObject *unused)
   1055 {
   1056     _PyTime_t t = _PyTime_GetMonotonicClock();
   1057     return _PyFloat_FromPyTime(t);
   1058 }
   1059 
   1060 PyDoc_STRVAR(monotonic_doc,
   1061 "monotonic() -> float\n\
   1062 \n\
   1063 Monotonic clock, cannot go backward.");
   1064 
   1065 static PyObject *
   1066 time_monotonic_ns(PyObject *self, PyObject *unused)
   1067 {
   1068     _PyTime_t t = _PyTime_GetMonotonicClock();
   1069     return _PyTime_AsNanosecondsObject(t);
   1070 }
   1071 
   1072 PyDoc_STRVAR(monotonic_ns_doc,
   1073 "monotonic_ns() -> int\n\
   1074 \n\
   1075 Monotonic clock, cannot go backward, as nanoseconds.");
   1076 
   1077 static PyObject *
   1078 time_perf_counter(PyObject *self, PyObject *unused)
   1079 {
   1080     return perf_counter(NULL);
   1081 }
   1082 
   1083 PyDoc_STRVAR(perf_counter_doc,
   1084 "perf_counter() -> float\n\
   1085 \n\
   1086 Performance counter for benchmarking.");
   1087 
   1088 static PyObject *
   1089 time_perf_counter_ns(PyObject *self, PyObject *unused)
   1090 {
   1091     _PyTime_t t = _PyTime_GetPerfCounter();
   1092     return _PyTime_AsNanosecondsObject(t);
   1093 }
   1094 
   1095 PyDoc_STRVAR(perf_counter_ns_doc,
   1096 "perf_counter_ns() -> int\n\
   1097 \n\
   1098 Performance counter for benchmarking as nanoseconds.");
   1099 
   1100 static int
   1101 _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
   1102 {
   1103 #if defined(MS_WINDOWS)
   1104     HANDLE process;
   1105     FILETIME creation_time, exit_time, kernel_time, user_time;
   1106     ULARGE_INTEGER large;
   1107     _PyTime_t ktime, utime, t;
   1108     BOOL ok;
   1109 
   1110     process = GetCurrentProcess();
   1111     ok = GetProcessTimes(process, &creation_time, &exit_time,
   1112                          &kernel_time, &user_time);
   1113     if (!ok) {
   1114         PyErr_SetFromWindowsErr(0);
   1115         return -1;
   1116     }
   1117 
   1118     if (info) {
   1119         info->implementation = "GetProcessTimes()";
   1120         info->resolution = 1e-7;
   1121         info->monotonic = 1;
   1122         info->adjustable = 0;
   1123     }
   1124 
   1125     large.u.LowPart = kernel_time.dwLowDateTime;
   1126     large.u.HighPart = kernel_time.dwHighDateTime;
   1127     ktime = large.QuadPart;
   1128 
   1129     large.u.LowPart = user_time.dwLowDateTime;
   1130     large.u.HighPart = user_time.dwHighDateTime;
   1131     utime = large.QuadPart;
   1132 
   1133     /* ktime and utime have a resolution of 100 nanoseconds */
   1134     t = _PyTime_FromNanoseconds((ktime + utime) * 100);
   1135     *tp = t;
   1136     return 0;
   1137 #else
   1138 
   1139     /* clock_gettime */
   1140 #if defined(HAVE_CLOCK_GETTIME) \
   1141     && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF))
   1142     struct timespec ts;
   1143 #ifdef CLOCK_PROF
   1144     const clockid_t clk_id = CLOCK_PROF;
   1145     const char *function = "clock_gettime(CLOCK_PROF)";
   1146 #else
   1147     const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
   1148     const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
   1149 #endif
   1150 
   1151     if (clock_gettime(clk_id, &ts) == 0) {
   1152         if (info) {
   1153             struct timespec res;
   1154             info->implementation = function;
   1155             info->monotonic = 1;
   1156             info->adjustable = 0;
   1157             if (clock_getres(clk_id, &res)) {
   1158                 PyErr_SetFromErrno(PyExc_OSError);
   1159                 return -1;
   1160             }
   1161             info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
   1162         }
   1163 
   1164         if (_PyTime_FromTimespec(tp, &ts) < 0) {
   1165             return -1;
   1166         }
   1167         return 0;
   1168     }
   1169 #endif
   1170 
   1171     /* getrusage(RUSAGE_SELF) */
   1172 #if defined(HAVE_SYS_RESOURCE_H)
   1173     struct rusage ru;
   1174 
   1175     if (getrusage(RUSAGE_SELF, &ru) == 0) {
   1176         _PyTime_t utime, stime;
   1177 
   1178         if (info) {
   1179             info->implementation = "getrusage(RUSAGE_SELF)";
   1180             info->monotonic = 1;
   1181             info->adjustable = 0;
   1182             info->resolution = 1e-6;
   1183         }
   1184 
   1185         if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) {
   1186             return -1;
   1187         }
   1188         if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) {
   1189             return -1;
   1190         }
   1191 
   1192         _PyTime_t total = utime + utime;
   1193         *tp = total;
   1194         return 0;
   1195     }
   1196 #endif
   1197 
   1198     /* times() */
   1199 #ifdef HAVE_TIMES
   1200     struct tms t;
   1201 
   1202     if (times(&t) != (clock_t)-1) {
   1203         static long ticks_per_second = -1;
   1204 
   1205         if (ticks_per_second == -1) {
   1206             long freq;
   1207 #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
   1208             freq = sysconf(_SC_CLK_TCK);
   1209             if (freq < 1) {
   1210                 freq = -1;
   1211             }
   1212 #elif defined(HZ)
   1213             freq = HZ;
   1214 #else
   1215             freq = 60; /* magic fallback value; may be bogus */
   1216 #endif
   1217 
   1218             if (freq != -1) {
   1219                 /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second)
   1220                    cannot overflow below */
   1221 #if LONG_MAX > _PyTime_MAX / SEC_TO_NS
   1222                 if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) {
   1223                     PyErr_SetString(PyExc_OverflowError,
   1224                                     "_SC_CLK_TCK is too large");
   1225                     return -1;
   1226                 }
   1227 #endif
   1228 
   1229                 ticks_per_second = freq;
   1230             }
   1231         }
   1232 
   1233         if (ticks_per_second != -1) {
   1234             if (info) {
   1235                 info->implementation = "times()";
   1236                 info->monotonic = 1;
   1237                 info->adjustable = 0;
   1238                 info->resolution = 1.0 / (double)ticks_per_second;
   1239             }
   1240 
   1241             _PyTime_t total;
   1242             total = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second);
   1243             total += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second);
   1244             *tp = total;
   1245             return 0;
   1246         }
   1247     }
   1248 #endif
   1249 
   1250     /* clock */
   1251     /* Currently, Python 3 requires clock() to build: see issue #22624 */
   1252     return _PyTime_GetClockWithInfo(tp, info);
   1253 #endif
   1254 }
   1255 
   1256 static PyObject *
   1257 time_process_time(PyObject *self, PyObject *unused)
   1258 {
   1259     _PyTime_t t;
   1260     if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
   1261         return NULL;
   1262     }
   1263     return _PyFloat_FromPyTime(t);
   1264 }
   1265 
   1266 PyDoc_STRVAR(process_time_doc,
   1267 "process_time() -> float\n\
   1268 \n\
   1269 Process time for profiling: sum of the kernel and user-space CPU time.");
   1270 
   1271 static PyObject *
   1272 time_process_time_ns(PyObject *self, PyObject *unused)
   1273 {
   1274     _PyTime_t t;
   1275     if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
   1276         return NULL;
   1277     }
   1278     return _PyTime_AsNanosecondsObject(t);
   1279 }
   1280 
   1281 PyDoc_STRVAR(process_time_ns_doc,
   1282 "process_time() -> int\n\
   1283 \n\
   1284 Process time for profiling as nanoseconds:\n\
   1285 sum of the kernel and user-space CPU time.");
   1286 
   1287 
   1288 #if defined(MS_WINDOWS)
   1289 #define HAVE_THREAD_TIME
   1290 static int
   1291 _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
   1292 {
   1293     HANDLE thread;
   1294     FILETIME creation_time, exit_time, kernel_time, user_time;
   1295     ULARGE_INTEGER large;
   1296     _PyTime_t ktime, utime, t;
   1297     BOOL ok;
   1298 
   1299     thread =  GetCurrentThread();
   1300     ok = GetThreadTimes(thread, &creation_time, &exit_time,
   1301                         &kernel_time, &user_time);
   1302     if (!ok) {
   1303         PyErr_SetFromWindowsErr(0);
   1304         return -1;
   1305     }
   1306 
   1307     if (info) {
   1308         info->implementation = "GetThreadTimes()";
   1309         info->resolution = 1e-7;
   1310         info->monotonic = 1;
   1311         info->adjustable = 0;
   1312     }
   1313 
   1314     large.u.LowPart = kernel_time.dwLowDateTime;
   1315     large.u.HighPart = kernel_time.dwHighDateTime;
   1316     ktime = large.QuadPart;
   1317 
   1318     large.u.LowPart = user_time.dwLowDateTime;
   1319     large.u.HighPart = user_time.dwHighDateTime;
   1320     utime = large.QuadPart;
   1321 
   1322     /* ktime and utime have a resolution of 100 nanoseconds */
   1323     t = _PyTime_FromNanoseconds((ktime + utime) * 100);
   1324     *tp = t;
   1325     return 0;
   1326 }
   1327 
   1328 #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
   1329 #define HAVE_THREAD_TIME
   1330 static int
   1331 _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
   1332 {
   1333     struct timespec ts;
   1334     const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID;
   1335     const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)";
   1336 
   1337     if (clock_gettime(clk_id, &ts)) {
   1338         PyErr_SetFromErrno(PyExc_OSError);
   1339         return -1;
   1340     }
   1341     if (info) {
   1342         struct timespec res;
   1343         info->implementation = function;
   1344         info->monotonic = 1;
   1345         info->adjustable = 0;
   1346         if (clock_getres(clk_id, &res)) {
   1347             PyErr_SetFromErrno(PyExc_OSError);
   1348             return -1;
   1349         }
   1350         info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
   1351     }
   1352 
   1353     if (_PyTime_FromTimespec(tp, &ts) < 0) {
   1354         return -1;
   1355     }
   1356     return 0;
   1357 }
   1358 #endif
   1359 
   1360 #ifdef HAVE_THREAD_TIME
   1361 static PyObject *
   1362 time_thread_time(PyObject *self, PyObject *unused)
   1363 {
   1364     _PyTime_t t;
   1365     if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
   1366         return NULL;
   1367     }
   1368     return _PyFloat_FromPyTime(t);
   1369 }
   1370 
   1371 PyDoc_STRVAR(thread_time_doc,
   1372 "thread_time() -> float\n\
   1373 \n\
   1374 Thread time for profiling: sum of the kernel and user-space CPU time.");
   1375 
   1376 static PyObject *
   1377 time_thread_time_ns(PyObject *self, PyObject *unused)
   1378 {
   1379     _PyTime_t t;
   1380     if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
   1381         return NULL;
   1382     }
   1383     return _PyTime_AsNanosecondsObject(t);
   1384 }
   1385 
   1386 PyDoc_STRVAR(thread_time_ns_doc,
   1387 "thread_time() -> int\n\
   1388 \n\
   1389 Thread time for profiling as nanoseconds:\n\
   1390 sum of the kernel and user-space CPU time.");
   1391 #endif
   1392 
   1393 
   1394 static PyObject *
   1395 time_get_clock_info(PyObject *self, PyObject *args)
   1396 {
   1397     char *name;
   1398     _Py_clock_info_t info;
   1399     PyObject *obj = NULL, *dict, *ns;
   1400     _PyTime_t t;
   1401 
   1402     if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) {
   1403         return NULL;
   1404     }
   1405 
   1406 #ifdef Py_DEBUG
   1407     info.implementation = NULL;
   1408     info.monotonic = -1;
   1409     info.adjustable = -1;
   1410     info.resolution = -1.0;
   1411 #else
   1412     info.implementation = "";
   1413     info.monotonic = 0;
   1414     info.adjustable = 0;
   1415     info.resolution = 1.0;
   1416 #endif
   1417 
   1418     if (strcmp(name, "time") == 0) {
   1419         if (_PyTime_GetSystemClockWithInfo(&t, &info) < 0) {
   1420             return NULL;
   1421         }
   1422     }
   1423 #ifdef PYCLOCK
   1424     else if (strcmp(name, "clock") == 0) {
   1425         obj = pyclock(&info);
   1426         if (obj == NULL) {
   1427             return NULL;
   1428         }
   1429         Py_DECREF(obj);
   1430     }
   1431 #endif
   1432     else if (strcmp(name, "monotonic") == 0) {
   1433         if (_PyTime_GetMonotonicClockWithInfo(&t, &info) < 0) {
   1434             return NULL;
   1435         }
   1436     }
   1437     else if (strcmp(name, "perf_counter") == 0) {
   1438         if (_PyTime_GetPerfCounterWithInfo(&t, &info) < 0) {
   1439             return NULL;
   1440         }
   1441     }
   1442     else if (strcmp(name, "process_time") == 0) {
   1443         if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) {
   1444             return NULL;
   1445         }
   1446     }
   1447 #ifdef HAVE_THREAD_TIME
   1448     else if (strcmp(name, "thread_time") == 0) {
   1449         if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) {
   1450             return NULL;
   1451         }
   1452     }
   1453 #endif
   1454     else {
   1455         PyErr_SetString(PyExc_ValueError, "unknown clock");
   1456         return NULL;
   1457     }
   1458 
   1459     dict = PyDict_New();
   1460     if (dict == NULL) {
   1461         return NULL;
   1462     }
   1463 
   1464     assert(info.implementation != NULL);
   1465     obj = PyUnicode_FromString(info.implementation);
   1466     if (obj == NULL) {
   1467         goto error;
   1468     }
   1469     if (PyDict_SetItemString(dict, "implementation", obj) == -1) {
   1470         goto error;
   1471     }
   1472     Py_CLEAR(obj);
   1473 
   1474     assert(info.monotonic != -1);
   1475     obj = PyBool_FromLong(info.monotonic);
   1476     if (obj == NULL) {
   1477         goto error;
   1478     }
   1479     if (PyDict_SetItemString(dict, "monotonic", obj) == -1) {
   1480         goto error;
   1481     }
   1482     Py_CLEAR(obj);
   1483 
   1484     assert(info.adjustable != -1);
   1485     obj = PyBool_FromLong(info.adjustable);
   1486     if (obj == NULL) {
   1487         goto error;
   1488     }
   1489     if (PyDict_SetItemString(dict, "adjustable", obj) == -1) {
   1490         goto error;
   1491     }
   1492     Py_CLEAR(obj);
   1493 
   1494     assert(info.resolution > 0.0);
   1495     assert(info.resolution <= 1.0);
   1496     obj = PyFloat_FromDouble(info.resolution);
   1497     if (obj == NULL) {
   1498         goto error;
   1499     }
   1500     if (PyDict_SetItemString(dict, "resolution", obj) == -1) {
   1501         goto error;
   1502     }
   1503     Py_CLEAR(obj);
   1504 
   1505     ns = _PyNamespace_New(dict);
   1506     Py_DECREF(dict);
   1507     return ns;
   1508 
   1509 error:
   1510     Py_DECREF(dict);
   1511     Py_XDECREF(obj);
   1512     return NULL;
   1513 }
   1514 
   1515 PyDoc_STRVAR(get_clock_info_doc,
   1516 "get_clock_info(name: str) -> dict\n\
   1517 \n\
   1518 Get information of the specified clock.");
   1519 
   1520 #if !defined(HAVE_TZNAME) || defined(__GLIBC__) || defined(__CYGWIN__)
   1521 static void
   1522 get_zone(char *zone, int n, struct tm *p)
   1523 {
   1524 #ifdef HAVE_STRUCT_TM_TM_ZONE
   1525     strncpy(zone, p->tm_zone ? p->tm_zone : "   ", n);
   1526 #else
   1527     tzset();
   1528     strftime(zone, n, "%Z", p);
   1529 #endif
   1530 }
   1531 
   1532 static time_t
   1533 get_gmtoff(time_t t, struct tm *p)
   1534 {
   1535 #ifdef HAVE_STRUCT_TM_TM_ZONE
   1536     return p->tm_gmtoff;
   1537 #else
   1538     return timegm(p) - t;
   1539 #endif
   1540 }
   1541 #endif /* !defined(HAVE_TZNAME) || defined(__GLIBC__) || defined(__CYGWIN__) */
   1542 
   1543 static int
   1544 init_timezone(PyObject *m)
   1545 {
   1546     assert(!PyErr_Occurred());
   1547 
   1548     /* This code moved from PyInit_time wholesale to allow calling it from
   1549     time_tzset. In the future, some parts of it can be moved back
   1550     (for platforms that don't HAVE_WORKING_TZSET, when we know what they
   1551     are), and the extraneous calls to tzset(3) should be removed.
   1552     I haven't done this yet, as I don't want to change this code as
   1553     little as possible when introducing the time.tzset and time.tzsetwall
   1554     methods. This should simply be a method of doing the following once,
   1555     at the top of this function and removing the call to tzset() from
   1556     time_tzset():
   1557 
   1558         #ifdef HAVE_TZSET
   1559         tzset()
   1560         #endif
   1561 
   1562     And I'm lazy and hate C so nyer.
   1563      */
   1564 #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
   1565     PyObject *otz0, *otz1;
   1566     tzset();
   1567     PyModule_AddIntConstant(m, "timezone", _Py_timezone);
   1568 #ifdef HAVE_ALTZONE
   1569     PyModule_AddIntConstant(m, "altzone", altzone);
   1570 #else
   1571     PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600);
   1572 #endif
   1573     PyModule_AddIntConstant(m, "daylight", _Py_daylight);
   1574     otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape");
   1575     if (otz0 == NULL) {
   1576         return -1;
   1577     }
   1578     otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape");
   1579     if (otz1 == NULL) {
   1580         Py_DECREF(otz0);
   1581         return -1;
   1582     }
   1583     PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1);
   1584     if (tzname_obj == NULL) {
   1585         return -1;
   1586     }
   1587     PyModule_AddObject(m, "tzname", tzname_obj);
   1588 #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
   1589     {
   1590 #define YEAR ((time_t)((365 * 24 + 6) * 3600))
   1591         time_t t;
   1592         struct tm p;
   1593         time_t janzone_t, julyzone_t;
   1594         char janname[10], julyname[10];
   1595         t = (time((time_t *)0) / YEAR) * YEAR;
   1596         _PyTime_localtime(t, &p);
   1597         get_zone(janname, 9, &p);
   1598         janzone_t = -get_gmtoff(t, &p);
   1599         janname[9] = '\0';
   1600         t += YEAR/2;
   1601         _PyTime_localtime(t, &p);
   1602         get_zone(julyname, 9, &p);
   1603         julyzone_t = -get_gmtoff(t, &p);
   1604         julyname[9] = '\0';
   1605 
   1606         /* Sanity check, don't check for the validity of timezones.
   1607            In practice, it should be more in range -12 hours .. +14 hours. */
   1608 #define MAX_TIMEZONE (48 * 3600)
   1609         if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE
   1610             || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE)
   1611         {
   1612             PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset");
   1613             return -1;
   1614         }
   1615         int janzone = (int)janzone_t;
   1616         int julyzone = (int)julyzone_t;
   1617 
   1618         if( janzone < julyzone ) {
   1619             /* DST is reversed in the southern hemisphere */
   1620             PyModule_AddIntConstant(m, "timezone", julyzone);
   1621             PyModule_AddIntConstant(m, "altzone", janzone);
   1622             PyModule_AddIntConstant(m, "daylight",
   1623                                     janzone != julyzone);
   1624             PyModule_AddObject(m, "tzname",
   1625                                Py_BuildValue("(zz)",
   1626                                              julyname, janname));
   1627         } else {
   1628             PyModule_AddIntConstant(m, "timezone", janzone);
   1629             PyModule_AddIntConstant(m, "altzone", julyzone);
   1630             PyModule_AddIntConstant(m, "daylight",
   1631                                     janzone != julyzone);
   1632             PyModule_AddObject(m, "tzname",
   1633                                Py_BuildValue("(zz)",
   1634                                              janname, julyname));
   1635         }
   1636     }
   1637 #ifdef __CYGWIN__
   1638     tzset();
   1639     PyModule_AddIntConstant(m, "timezone", _timezone);
   1640     PyModule_AddIntConstant(m, "altzone", _timezone-3600);
   1641     PyModule_AddIntConstant(m, "daylight", _daylight);
   1642     PyModule_AddObject(m, "tzname",
   1643                        Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
   1644 #endif /* __CYGWIN__ */
   1645 #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
   1646 
   1647     if (PyErr_Occurred()) {
   1648         return -1;
   1649     }
   1650     return 0;
   1651 }
   1652 
   1653 
   1654 static PyMethodDef time_methods[] = {
   1655     {"time",            time_time, METH_NOARGS, time_doc},
   1656     {"time_ns",         time_time_ns, METH_NOARGS, time_ns_doc},
   1657 #ifdef PYCLOCK
   1658     {"clock",           time_clock, METH_NOARGS, clock_doc},
   1659 #endif
   1660 #ifdef HAVE_CLOCK_GETTIME
   1661     {"clock_gettime",   time_clock_gettime, METH_VARARGS, clock_gettime_doc},
   1662     {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc},
   1663 #endif
   1664 #ifdef HAVE_CLOCK_SETTIME
   1665     {"clock_settime",   time_clock_settime, METH_VARARGS, clock_settime_doc},
   1666     {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc},
   1667 #endif
   1668 #ifdef HAVE_CLOCK_GETRES
   1669     {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
   1670 #endif
   1671 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
   1672     {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc},
   1673 #endif
   1674     {"sleep",           time_sleep, METH_O, sleep_doc},
   1675     {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
   1676     {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
   1677     {"asctime",         time_asctime, METH_VARARGS, asctime_doc},
   1678     {"ctime",           time_ctime, METH_VARARGS, ctime_doc},
   1679 #ifdef HAVE_MKTIME
   1680     {"mktime",          time_mktime, METH_O, mktime_doc},
   1681 #endif
   1682 #ifdef HAVE_STRFTIME
   1683     {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
   1684 #endif
   1685     {"strptime",        time_strptime, METH_VARARGS, strptime_doc},
   1686 #ifdef HAVE_WORKING_TZSET
   1687     {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
   1688 #endif
   1689     {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
   1690     {"monotonic_ns",    time_monotonic_ns, METH_NOARGS, monotonic_ns_doc},
   1691     {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
   1692     {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc},
   1693 #ifdef HAVE_THREAD_TIME
   1694     {"thread_time",     time_thread_time, METH_NOARGS, thread_time_doc},
   1695     {"thread_time_ns",  time_thread_time_ns, METH_NOARGS, thread_time_ns_doc},
   1696 #endif
   1697     {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
   1698     {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc},
   1699     {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},
   1700     {NULL,              NULL}           /* sentinel */
   1701 };
   1702 
   1703 
   1704 PyDoc_STRVAR(module_doc,
   1705 "This module provides various functions to manipulate time values.\n\
   1706 \n\
   1707 There are two standard representations of time.  One is the number\n\
   1708 of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\n\
   1709 or a floating point number (to represent fractions of seconds).\n\
   1710 The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
   1711 The actual value can be retrieved by calling gmtime(0).\n\
   1712 \n\
   1713 The other representation is a tuple of 9 integers giving local time.\n\
   1714 The tuple items are:\n\
   1715   year (including century, e.g. 1998)\n\
   1716   month (1-12)\n\
   1717   day (1-31)\n\
   1718   hours (0-23)\n\
   1719   minutes (0-59)\n\
   1720   seconds (0-59)\n\
   1721   weekday (0-6, Monday is 0)\n\
   1722   Julian day (day in the year, 1-366)\n\
   1723   DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
   1724 If the DST flag is 0, the time is given in the regular time zone;\n\
   1725 if it is 1, the time is given in the DST time zone;\n\
   1726 if it is -1, mktime() should guess based on the date and time.\n");
   1727 
   1728 
   1729 
   1730 static struct PyModuleDef timemodule = {
   1731     PyModuleDef_HEAD_INIT,
   1732     "time",
   1733     module_doc,
   1734     -1,
   1735     time_methods,
   1736     NULL,
   1737     NULL,
   1738     NULL,
   1739     NULL
   1740 };
   1741 
   1742 PyMODINIT_FUNC
   1743 PyInit_time(void)
   1744 {
   1745     PyObject *m;
   1746     m = PyModule_Create(&timemodule);
   1747     if (m == NULL)
   1748         return NULL;
   1749 
   1750     /* Set, or reset, module variables like time.timezone */
   1751     if (init_timezone(m) < 0) {
   1752         return NULL;
   1753     }
   1754 
   1755 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES)
   1756 
   1757 #ifdef CLOCK_REALTIME
   1758     PyModule_AddIntMacro(m, CLOCK_REALTIME);
   1759 #endif
   1760 #ifdef CLOCK_MONOTONIC
   1761     PyModule_AddIntMacro(m, CLOCK_MONOTONIC);
   1762 #endif
   1763 #ifdef CLOCK_MONOTONIC_RAW
   1764     PyModule_AddIntMacro(m, CLOCK_MONOTONIC_RAW);
   1765 #endif
   1766 #ifdef CLOCK_HIGHRES
   1767     PyModule_AddIntMacro(m, CLOCK_HIGHRES);
   1768 #endif
   1769 #ifdef CLOCK_PROCESS_CPUTIME_ID
   1770     PyModule_AddIntMacro(m, CLOCK_PROCESS_CPUTIME_ID);
   1771 #endif
   1772 #ifdef CLOCK_THREAD_CPUTIME_ID
   1773     PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID);
   1774 #endif
   1775 #ifdef CLOCK_PROF
   1776     PyModule_AddIntMacro(m, CLOCK_PROF);
   1777 #endif
   1778 #ifdef CLOCK_BOOTTIME
   1779     PyModule_AddIntMacro(m, CLOCK_BOOTTIME);
   1780 #endif
   1781 #ifdef CLOCK_UPTIME
   1782     PyModule_AddIntMacro(m, CLOCK_UPTIME);
   1783 #endif
   1784 
   1785 #endif  /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */
   1786 
   1787     if (!initialized) {
   1788         if (PyStructSequence_InitType2(&StructTimeType,
   1789                                        &struct_time_type_desc) < 0)
   1790             return NULL;
   1791     }
   1792     Py_INCREF(&StructTimeType);
   1793     PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 11);
   1794     PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
   1795     initialized = 1;
   1796 
   1797     if (PyErr_Occurred()) {
   1798         return NULL;
   1799     }
   1800     return m;
   1801 }
   1802 
   1803 /* Implement pysleep() for various platforms.
   1804    When interrupted (or when another error occurs), return -1 and
   1805    set an exception; else return 0. */
   1806 
   1807 static int
   1808 pysleep(_PyTime_t secs)
   1809 {
   1810     _PyTime_t deadline, monotonic;
   1811 #ifndef MS_WINDOWS
   1812     struct timeval timeout;
   1813     int err = 0;
   1814 #else
   1815     _PyTime_t millisecs;
   1816     unsigned long ul_millis;
   1817     DWORD rc;
   1818     HANDLE hInterruptEvent;
   1819 #endif
   1820 
   1821     deadline = _PyTime_GetMonotonicClock() + secs;
   1822 
   1823     do {
   1824 #ifndef MS_WINDOWS
   1825         if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0)
   1826             return -1;
   1827 
   1828         Py_BEGIN_ALLOW_THREADS
   1829         err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
   1830         Py_END_ALLOW_THREADS
   1831 
   1832         if (err == 0)
   1833             break;
   1834 
   1835         if (errno != EINTR) {
   1836             PyErr_SetFromErrno(PyExc_OSError);
   1837             return -1;
   1838         }
   1839 #else
   1840         millisecs = _PyTime_AsMilliseconds(secs, _PyTime_ROUND_CEILING);
   1841         if (millisecs > (double)ULONG_MAX) {
   1842             PyErr_SetString(PyExc_OverflowError,
   1843                             "sleep length is too large");
   1844             return -1;
   1845         }
   1846 
   1847         /* Allow sleep(0) to maintain win32 semantics, and as decreed
   1848          * by Guido, only the main thread can be interrupted.
   1849          */
   1850         ul_millis = (unsigned long)millisecs;
   1851         if (ul_millis == 0 || !_PyOS_IsMainThread()) {
   1852             Py_BEGIN_ALLOW_THREADS
   1853             Sleep(ul_millis);
   1854             Py_END_ALLOW_THREADS
   1855             break;
   1856         }
   1857 
   1858         hInterruptEvent = _PyOS_SigintEvent();
   1859         ResetEvent(hInterruptEvent);
   1860 
   1861         Py_BEGIN_ALLOW_THREADS
   1862         rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
   1863         Py_END_ALLOW_THREADS
   1864 
   1865         if (rc != WAIT_OBJECT_0)
   1866             break;
   1867 #endif
   1868 
   1869         /* sleep was interrupted by SIGINT */
   1870         if (PyErr_CheckSignals())
   1871             return -1;
   1872 
   1873         monotonic = _PyTime_GetMonotonicClock();
   1874         secs = deadline - monotonic;
   1875         if (secs < 0)
   1876             break;
   1877         /* retry with the recomputed delay */
   1878     } while (1);
   1879 
   1880     return 0;
   1881 }
   1882