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