Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Modules/timemodule.c
Line
Count
Source (jump to first uncovered line)
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 */
66
static int pysleep(_PyTime_t timeout);
67
68
69
typedef struct {
70
    PyTypeObject *struct_time_type;
71
} time_module_state;
72
73
static inline time_module_state*
74
get_time_state(PyObject *module)
75
{
76
    void *state = _PyModule_GetState(module);
77
    assert(state != NULL);
78
    return (time_module_state *)state;
79
}
80
81
82
static PyObject*
83
_PyFloat_FromPyTime(_PyTime_t t)
84
{
85
    double d = _PyTime_AsSecondsDouble(t);
86
    return PyFloat_FromDouble(d);
87
}
88
89
90
static int
91
get_system_time(_PyTime_t *t)
92
{
93
    // Avoid _PyTime_GetSystemClock() which silently ignores errors.
94
    return _PyTime_GetSystemClockWithInfo(t, NULL);
95
}
96
97
98
static PyObject *
99
time_time(PyObject *self, PyObject *unused)
100
{
101
    _PyTime_t t;
102
    if (get_system_time(&t) < 0) {
  Branch (102:9): [True: 0, False: 2.84M]
103
        return NULL;
104
    }
105
    return _PyFloat_FromPyTime(t);
106
}
107
108
109
PyDoc_STRVAR(time_doc,
110
"time() -> floating point number\n\
111
\n\
112
Return the current time in seconds since the Epoch.\n\
113
Fractions of a second may be present if the system clock provides them.");
114
115
static PyObject *
116
time_time_ns(PyObject *self, PyObject *unused)
117
{
118
    _PyTime_t t;
119
    if (get_system_time(&t) < 0) {
  Branch (119:9): [True: 0, False: 1.02k]
120
        return NULL;
121
    }
122
    return _PyTime_AsNanosecondsObject(t);
123
}
124
125
PyDoc_STRVAR(time_ns_doc,
126
"time_ns() -> int\n\
127
\n\
128
Return 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
140
static int
141
_PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
142
{
143
    static int initialized = 0;
144
145
    if (!initialized) {
  Branch (145:9): [True: 0, False: 0]
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) {
  Branch (150:13): [Folded - Ignored]
151
            PyErr_SetString(PyExc_OverflowError,
152
                            "CLOCKS_PER_SEC is too large");
153
            return -1;
154
        }
155
    }
156
157
    if (info) {
  Branch (157:9): [True: 0, False: 0]
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) {
  Branch (165:9): [True: 0, False: 0]
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
189
static PyObject *
190
time_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)) {
  Branch (200:9): [True: 0, False: 8]
201
#endif
202
        return NULL;
203
    }
204
205
    ret = clock_gettime((clockid_t)clk_id, &tp);
206
    if (ret != 0) {
  Branch (206:9): [True: 0, False: 8]
207
        PyErr_SetFromErrno(PyExc_OSError);
208
        return NULL;
209
    }
210
    return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
211
}
212
213
PyDoc_STRVAR(clock_gettime_doc,
214
"clock_gettime(clk_id) -> float\n\
215
\n\
216
Return the time of the specified clock clk_id.");
217
218
static PyObject *
219
time_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)) {
  Branch (226:9): [True: 0, False: 1]
227
        return NULL;
228
    }
229
230
    ret = clock_gettime((clockid_t)clk_id, &ts);
231
    if (ret != 0) {
  Branch (231:9): [True: 0, False: 1]
232
        PyErr_SetFromErrno(PyExc_OSError);
233
        return NULL;
234
    }
235
    if (_PyTime_FromTimespec(&t, &ts) < 0) {
  Branch (235:9): [True: 0, False: 1]
236
        return NULL;
237
    }
238
    return _PyTime_AsNanosecondsObject(t);
239
}
240
241
PyDoc_STRVAR(clock_gettime_ns_doc,
242
"clock_gettime_ns(clk_id) -> int\n\
243
\n\
244
Return the time of the specified clock clk_id as nanoseconds.");
245
#endif   /* HAVE_CLOCK_GETTIME */
246
247
#ifdef HAVE_CLOCK_SETTIME
248
static PyObject *
249
time_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))
  Branch (257:9): [True: 0, False: 3]
258
        return NULL;
259
260
    if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0)
  Branch (260:9): [True: 0, False: 3]
261
        return NULL;
262
263
    if (_PyTime_AsTimespec(t, &tp) == -1)
  Branch (263:9): [True: 0, False: 3]
264
        return NULL;
265
266
    ret = clock_settime((clockid_t)clk_id, &tp);
267
    if (ret != 0) {
  Branch (267:9): [True: 3, False: 0]
268
        PyErr_SetFromErrno(PyExc_OSError);
269
        return NULL;
270
    }
271
    
Py_RETURN_NONE0
;
272
}
273
274
PyDoc_STRVAR(clock_settime_doc,
275
"clock_settime(clk_id, time)\n\
276
\n\
277
Set the time of the specified clock clk_id.");
278
279
static PyObject *
280
time_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)) {
  Branch (288:9): [True: 0, False: 0]
289
        return NULL;
290
    }
291
292
    if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
  Branch (292:9): [True: 0, False: 0]
293
        return NULL;
294
    }
295
    if (_PyTime_AsTimespec(t, &ts) == -1) {
  Branch (295:9): [True: 0, False: 0]
296
        return NULL;
297
    }
298
299
    ret = clock_settime((clockid_t)clk_id, &ts);
300
    if (ret != 0) {
  Branch (300:9): [True: 0, False: 0]
301
        PyErr_SetFromErrno(PyExc_OSError);
302
        return NULL;
303
    }
304
    Py_RETURN_NONE;
305
}
306
307
PyDoc_STRVAR(clock_settime_ns_doc,
308
"clock_settime_ns(clk_id, time)\n\
309
\n\
310
Set the time of the specified clock clk_id with nanoseconds.");
311
#endif   /* HAVE_CLOCK_SETTIME */
312
313
#ifdef HAVE_CLOCK_GETRES
314
static PyObject *
315
time_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))
  Branch (321:9): [True: 0, False: 1]
322
        return NULL;
323
324
    ret = clock_getres((clockid_t)clk_id, &tp);
325
    if (ret != 0) {
  Branch (325:9): [True: 0, False: 1]
326
        PyErr_SetFromErrno(PyExc_OSError);
327
        return NULL;
328
    }
329
330
    return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
331
}
332
333
PyDoc_STRVAR(clock_getres_doc,
334
"clock_getres(clk_id) -> floating point number\n\
335
\n\
336
Return 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
345
static PyObject *
346
time_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)) {
  Branch (351:9): [True: 0, False: 1]
352
        return NULL;
353
    }
354
    err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id);
355
    if (err) {
  Branch (355:9): [True: 0, False: 1]
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
366
PyDoc_STRVAR(pthread_getcpuclockid_doc,
367
"pthread_getcpuclockid(thread_id) -> int\n\
368
\n\
369
Return the clk_id of a thread's CPU time clock.");
370
#endif /* HAVE_PTHREAD_GETCPUCLOCKID */
371
372
static PyObject *
373
time_sleep(PyObject *self, PyObject *timeout_obj)
374
{
375
    _PyTime_t timeout;
376
    if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT))
  Branch (376:9): [True: 1, False: 89.3k]
377
        return NULL;
378
    if (timeout < 0) {
  Branch (378:9): [True: 2, False: 89.3k]
379
        PyErr_SetString(PyExc_ValueError,
380
                        "sleep length must be non-negative");
381
        return NULL;
382
    }
383
    if (pysleep(timeout) != 0) {
  Branch (383:9): [True: 0, False: 89.3k]
384
        return NULL;
385
    }
386
    Py_RETURN_NONE;
387
}
388
389
PyDoc_STRVAR(sleep_doc,
390
"sleep(seconds)\n\
391
\n\
392
Delay execution for a given number of seconds.  The argument may be\n\
393
a floating point number for subsecond precision.");
394
395
static 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
410
static 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
428
static DWORD timer_flags = (DWORD)-1;
429
#endif
430
431
static PyObject *
432
tmtotuple(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)
  Branch (439:9): [True: 0, False: 15.9k]
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()) {
  Branch (463:9): [True: 0, False: 15.9k]
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
*/
475
static int
476
parse_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))
  Branch (481:9): [True: 0, False: 16.1k]
482
        return 0;
483
    if (ot == NULL || 
ot == 15.4k
Py_None15.4k
) {
  Branch (483:9): [True: 725, False: 15.4k]
  Branch (483:23): [True: 3, False: 15.4k]
484
        whent = time(NULL);
485
    }
486
    else {
487
        if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1)
  Branch (487:13): [True: 22, False: 15.4k]
488
            return 0;
489
    }
490
    *pwhen = whent;
491
    return 1;
492
}
493
494
static PyObject *
495
time_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))
  Branch (500:9): [True: 8, False: 1.89k]
501
        return NULL;
502
503
    errno = 0;
504
    if (_PyTime_gmtime(when, &buf) != 0)
  Branch (504:9): [True: 0, False: 1.89k]
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
516
static time_t
517
timegm(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
528
PyDoc_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\
532
Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
533
GMT).  When 'seconds' is not passed in, convert the current time instead.\n\
534
\n\
535
If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
536
attributes only.");
537
538
static PyObject *
539
time_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))
  Branch (544:9): [True: 11, False: 14.0k]
545
        return NULL;
546
    if (_PyTime_localtime(when, &buf) != 0)
  Branch (546:9): [True: 2, False: 14.0k]
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__)
565
static const char *utc_string = NULL;
566
#endif
567
568
PyDoc_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\
572
Convert seconds since the Epoch to a time tuple expressing local time.\n\
573
When '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
 */
578
static int
579
gettmarg(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)) {
  Branch (586:9): [True: 1, False: 15.2k]
587
        PyErr_SetString(PyExc_TypeError,
588
                        "Tuple or struct_time argument required");
589
        return 0;
590
    }
591
592
    if (!PyArg_ParseTuple(args, format,
  Branch (592:9): [True: 4, False: 15.2k]
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) {
  Branch (598:9): [True: 5, False: 15.2k]
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) {
  Branch (611:13): [True: 10.3k, False: 4.43k]
612
            p->tm_zone = (char *)PyUnicode_AsUTF8(item);
613
            if (p->tm_zone == NULL) {
  Branch (613:17): [True: 0, False: 10.3k]
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) {
  Branch (632:13): [True: 10.3k, False: 4.43k]
633
            p->tm_gmtoff = PyLong_AsLong(item);
634
            if (PyErr_Occurred())
  Branch (634:17): [True: 0, False: 10.3k]
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
 */
646
static int
647
checktm(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)
  Branch (673:9): [True: 41, False: 14.8k]
674
        buf->tm_mon = 0;
675
    else if (buf->tm_mon < 0 || 
buf->tm_mon > 1114.8k
) {
  Branch (675:14): [True: 2, False: 14.8k]
  Branch (675:33): [True: 2, False: 14.8k]
676
        PyErr_SetString(PyExc_ValueError, "month out of range");
677
        return 0;
678
    }
679
    if (buf->tm_mday == 0)
  Branch (679:9): [True: 41, False: 14.8k]
680
        buf->tm_mday = 1;
681
    else if (buf->tm_mday < 0 || 
buf->tm_mday > 3114.8k
) {
  Branch (681:14): [True: 2, False: 14.8k]
  Branch (681:34): [True: 2, False: 14.8k]
682
        PyErr_SetString(PyExc_ValueError, "day of month out of range");
683
        return 0;
684
    }
685
    if (buf->tm_hour < 0 || 
buf->tm_hour > 2314.9k
) {
  Branch (685:9): [True: 2, False: 14.9k]
  Branch (685:29): [True: 2, False: 14.9k]
686
        PyErr_SetString(PyExc_ValueError, "hour out of range");
687
        return 0;
688
    }
689
    if (buf->tm_min < 0 || 
buf->tm_min > 5914.9k
) {
  Branch (689:9): [True: 2, False: 14.9k]
  Branch (689:28): [True: 2, False: 14.8k]
690
        PyErr_SetString(PyExc_ValueError, "minute out of range");
691
        return 0;
692
    }
693
    if (buf->tm_sec < 0 || 
buf->tm_sec > 6114.8k
) {
  Branch (693:9): [True: 2, False: 14.8k]
  Branch (693:28): [True: 2, False: 14.8k]
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) {
  Branch (699:9): [True: 2, False: 14.8k]
700
        PyErr_SetString(PyExc_ValueError, "day of week out of range");
701
        return 0;
702
    }
703
    if (buf->tm_yday == -1)
  Branch (703:9): [True: 48, False: 14.8k]
704
        buf->tm_yday = 0;
705
    else if (buf->tm_yday < 0 || 
buf->tm_yday > 36514.8k
) {
  Branch (705:14): [True: 2, False: 14.8k]
  Branch (705:34): [True: 2, False: 14.8k]
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\
734
Other codes may be available on your platform.  See documentation for\n\
735
the 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
748
static PyObject *
749
time_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))
  Branch (770:9): [True: 1, False: 14.3k]
771
        return NULL;
772
773
    time_module_state *state = get_time_state(module);
774
    if (tup == NULL) {
  Branch (774:9): [True: 450, False: 13.9k]
775
        time_t tt = time(NULL);
776
        if (_PyTime_localtime(tt, &buf) != 0)
  Branch (776:13): [True: 0, False: 450]
777
            return NULL;
778
    }
779
    else if (!gettmarg(state, tup, &buf,
  Branch (779:14): [True: 3, False: 13.9k]
780
                       "iiiiiiiii;strftime(): illegal time tuple argument") ||
781
             
!checktm(&buf)13.9k
)
  Branch (781:14): [True: 13, False: 13.9k]
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)
  Branch (797:9): [True: 0, False: 14.3k]
798
        buf.tm_isdst = -1;
799
    else if (buf.tm_isdst > 1)
  Branch (799:14): [True: 0, False: 14.3k]
800
        buf.tm_isdst = 1;
801
802
#ifdef HAVE_WCSFTIME
803
    format = PyUnicode_AsWideCharString(format_arg, NULL);
804
    if (format == NULL)
  Branch (804:9): [True: 1, False: 14.3k]
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 += i0
) {
856
        outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
857
        if (outbuf == NULL) {
  Branch (857:13): [True: 0, False: 14.3k]
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 * fmtlen22
) {
  Branch (875:13): [True: 14.3k, False: 22]
  Branch (875:27): [True: 22, False: 0]
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
901
PyDoc_STRVAR(strftime_doc,
902
"strftime(format[, tuple]) -> string\n\
903
\n\
904
Convert a time tuple to a string according to a format specification.\n\
905
See the library reference manual for formatting codes. When the time tuple\n\
906
is not present, current time as returned by localtime() is used.\n\
907
\n" STRFTIME_FORMAT_CODES);
908
#endif /* HAVE_STRFTIME */
909
910
static PyObject *
911
time_strptime(PyObject *self, PyObject *args)
912
{
913
    PyObject *func, *result;
914
915
    func = _PyImport_GetModuleAttrString("_strptime", "_strptime_time");
916
    if (!func) {
  Branch (916:9): [True: 0, False: 144]
917
        return NULL;
918
    }
919
920
    result = PyObject_Call(func, args, NULL);
921
    Py_DECREF(func);
922
    return result;
923
}
924
925
926
PyDoc_STRVAR(strptime_doc,
927
"strptime(string, format) -> struct_time\n\
928
\n\
929
Parse a string to a time tuple according to a format specification.\n\
930
See the library reference manual for formatting codes (same as\n\
931
strftime()).\n\
932
\n" STRFTIME_FORMAT_CODES);
933
934
static PyObject *
935
_asctime(struct tm *timeptr)
936
{
937
    /* Inspired by Open Group reference implementation available at
938
     * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */
939
    static const char wday_name[7][4] = {
940
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
941
    };
942
    static const char mon_name[12][4] = {
943
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
944
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
945
    };
946
    return PyUnicode_FromFormat(
947
        "%s %s%3d %.2d:%.2d:%.2d %d",
948
        wday_name[timeptr->tm_wday],
949
        mon_name[timeptr->tm_mon],
950
        timeptr->tm_mday, timeptr->tm_hour,
951
        timeptr->tm_min, timeptr->tm_sec,
952
        1900 + timeptr->tm_year);
953
}
954
955
static PyObject *
956
time_asctime(PyObject *module, PyObject *args)
957
{
958
    PyObject *tup = NULL;
959
    struct tm buf;
960
961
    if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
  Branch (961:9): [True: 0, False: 994]
962
        return NULL;
963
964
    time_module_state *state = get_time_state(module);
965
    if (tup == NULL) {
  Branch (965:9): [True: 0, False: 994]
966
        time_t tt = time(NULL);
967
        if (_PyTime_localtime(tt, &buf) != 0)
  Branch (967:13): [True: 0, False: 0]
968
            return NULL;
969
    }
970
    else if (!gettmarg(state, tup, &buf,
  Branch (970:14): [True: 7, False: 987]
971
                       "iiiiiiiii;asctime(): illegal time tuple argument") ||
972
             
!checktm(&buf)987
)
  Branch (972:14): [True: 13, False: 974]
973
    {
974
        return NULL;
975
    }
976
    return _asctime(&buf);
977
}
978
979
PyDoc_STRVAR(asctime_doc,
980
"asctime([tuple]) -> string\n\
981
\n\
982
Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
983
When the time tuple is not present, current time as returned by localtime()\n\
984
is used.");
985
986
static PyObject *
987
time_ctime(PyObject *self, PyObject *args)
988
{
989
    time_t tt;
990
    struct tm buf;
991
    if (!parse_time_t_args(args, "|O:ctime", &tt))
  Branch (991:9): [True: 3, False: 243]
992
        return NULL;
993
    if (_PyTime_localtime(tt, &buf) != 0)
  Branch (993:9): [True: 1, False: 242]
994
        return NULL;
995
    return _asctime(&buf);
996
}
997
998
PyDoc_STRVAR(ctime_doc,
999
"ctime(seconds) -> string\n\
1000
\n\
1001
Convert a time in seconds since the Epoch to a string in local time.\n\
1002
This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
1003
not present, current time as returned by localtime() is used.");
1004
1005
#ifdef HAVE_MKTIME
1006
static PyObject *
1007
time_mktime(PyObject *module, PyObject *tm_tuple)
1008
{
1009
    struct tm tm;
1010
    time_t tt;
1011
1012
    time_module_state *state = get_time_state(module);
1013
    if (!gettmarg(state, tm_tuple, &tm,
  Branch (1013:9): [True: 0, False: 311]
1014
                  "iiiiiiiii;mktime(): illegal time tuple argument"))
1015
    {
1016
        return NULL;
1017
    }
1018
1019
#if defined(_AIX) || (defined(__VXWORKS__) && !defined(_WRS_CONFIG_LP64))
1020
    /* bpo-19748: AIX mktime() valid range is 00:00:00 UTC, January 1, 1970
1021
       to 03:14:07 UTC, January 19, 2038. Thanks to the workaround below,
1022
       it is possible to support years in range [1902; 2037] */
1023
    if (tm.tm_year < 2 || tm.tm_year > 137) {
1024
        /* bpo-19748: On AIX, mktime() does not report overflow error
1025
           for timestamp < -2^31 or timestamp > 2**31-1. VxWorks has the
1026
           same issue when working in 32 bit mode. */
1027
        PyErr_SetString(PyExc_OverflowError,
1028
                        "mktime argument out of range");
1029
        return NULL;
1030
    }
1031
#endif
1032
1033
#ifdef _AIX
1034
    /* bpo-34373: AIX mktime() has an integer overflow for years in range
1035
       [1902; 1969]. Workaround the issue by using a year greater or equal than
1036
       1970 (tm_year >= 70): mktime() behaves correctly in that case
1037
       (ex: properly report errors). tm_year and tm_wday are adjusted after
1038
       mktime() call. */
1039
    int orig_tm_year = tm.tm_year;
1040
    int delta_days = 0;
1041
    while (tm.tm_year < 70) {
1042
        /* Use 4 years to account properly leap years */
1043
        tm.tm_year += 4;
1044
        delta_days -= (366 + (365 * 3));
1045
    }
1046
#endif
1047
1048
    tm.tm_wday = -1;  /* sentinel; original value ignored */
1049
    tt = mktime(&tm);
1050
1051
    /* Return value of -1 does not necessarily mean an error, but tm_wday
1052
     * cannot remain set to -1 if mktime succeeded. */
1053
    if (tt == (time_t)(-1)
  Branch (1053:9): [True: 1, False: 310]
1054
        /* Return value of -1 does not necessarily mean an error, but
1055
         * tm_wday cannot remain set to -1 if mktime succeeded. */
1056
        && 
tm.tm_wday == -11
)
  Branch (1056:12): [True: 0, False: 1]
1057
    {
1058
        PyErr_SetString(PyExc_OverflowError,
1059
                        "mktime argument out of range");
1060
        return NULL;
1061
    }
1062
1063
#ifdef _AIX
1064
    if (delta_days != 0) {
1065
        tm.tm_year = orig_tm_year;
1066
        if (tm.tm_wday != -1) {
1067
            tm.tm_wday = (tm.tm_wday + delta_days) % 7;
1068
        }
1069
        tt += delta_days * (24 * 3600);
1070
    }
1071
#endif
1072
1073
    return PyFloat_FromDouble((double)tt);
1074
}
1075
1076
PyDoc_STRVAR(mktime_doc,
1077
"mktime(tuple) -> floating point number\n\
1078
\n\
1079
Convert a time tuple in local time to seconds since the Epoch.\n\
1080
Note that mktime(gmtime(0)) will not generally return zero for most\n\
1081
time zones; instead the returned value will either be equal to that\n\
1082
of the timezone or altzone attributes on the time module.");
1083
#endif /* HAVE_MKTIME */
1084
1085
#ifdef HAVE_WORKING_TZSET
1086
static int init_timezone(PyObject *module);
1087
1088
static PyObject *
1089
time_tzset(PyObject *self, PyObject *unused)
1090
{
1091
    PyObject* m;
1092
1093
    m = PyImport_ImportModule("time");
1094
    if (m == NULL) {
  Branch (1094:9): [True: 0, False: 125]
1095
        return NULL;
1096
    }
1097
1098
    tzset();
1099
1100
    /* Reset timezone, altzone, daylight and tzname */
1101
    if (init_timezone(m) < 0) {
  Branch (1101:9): [True: 0, False: 125]
1102
         return NULL;
1103
    }
1104
    Py_DECREF(m);
1105
    if (PyErr_Occurred())
  Branch (1105:9): [True: 0, False: 125]
1106
        return NULL;
1107
1108
    Py_RETURN_NONE;
1109
}
1110
1111
PyDoc_STRVAR(tzset_doc,
1112
"tzset()\n\
1113
\n\
1114
Initialize, or reinitialize, the local timezone to the value stored in\n\
1115
os.environ['TZ']. The TZ environment variable should be specified in\n\
1116
standard Unix timezone format as documented in the tzset man page\n\
1117
(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
1118
fall back to UTC. If the TZ environment variable is not set, the local\n\
1119
timezone is set to the systems best guess of wallclock time.\n\
1120
Changing the TZ environment variable without calling tzset *may* change\n\
1121
the local timezone used by methods such as localtime, but this behaviour\n\
1122
should not be relied on.");
1123
#endif /* HAVE_WORKING_TZSET */
1124
1125
1126
static int
1127
get_monotonic(_PyTime_t *t)
1128
{
1129
    // Avoid _PyTime_GetMonotonicClock() which silently ignores errors.
1130
    return _PyTime_GetMonotonicClockWithInfo(t, NULL);
1131
}
1132
1133
1134
static PyObject *
1135
time_monotonic(PyObject *self, PyObject *unused)
1136
{
1137
    _PyTime_t t;
1138
    if (get_monotonic(&t) < 0) {
  Branch (1138:9): [True: 0, False: 3.88M]
1139
        return NULL;
1140
    }
1141
    return _PyFloat_FromPyTime(t);
1142
}
1143
1144
PyDoc_STRVAR(monotonic_doc,
1145
"monotonic() -> float\n\
1146
\n\
1147
Monotonic clock, cannot go backward.");
1148
1149
static PyObject *
1150
time_monotonic_ns(PyObject *self, PyObject *unused)
1151
{
1152
    _PyTime_t t;
1153
    if (get_monotonic(&t) < 0) {
  Branch (1153:9): [True: 0, False: 1]
1154
        return NULL;
1155
    }
1156
    return _PyTime_AsNanosecondsObject(t);
1157
}
1158
1159
PyDoc_STRVAR(monotonic_ns_doc,
1160
"monotonic_ns() -> int\n\
1161
\n\
1162
Monotonic clock, cannot go backward, as nanoseconds.");
1163
1164
1165
static int
1166
get_perf_counter(_PyTime_t *t)
1167
{
1168
    // Avoid _PyTime_GetPerfCounter() which silently ignores errors.
1169
    return _PyTime_GetPerfCounterWithInfo(t, NULL);
1170
}
1171
1172
1173
static PyObject *
1174
time_perf_counter(PyObject *self, PyObject *unused)
1175
{
1176
    _PyTime_t t;
1177
    if (get_perf_counter(&t) < 0) {
  Branch (1177:9): [True: 0, False: 40.5k]
1178
        return NULL;
1179
    }
1180
    return _PyFloat_FromPyTime(t);
1181
}
1182
1183
PyDoc_STRVAR(perf_counter_doc,
1184
"perf_counter() -> float\n\
1185
\n\
1186
Performance counter for benchmarking.");
1187
1188
1189
static PyObject *
1190
time_perf_counter_ns(PyObject *self, PyObject *unused)
1191
{
1192
    _PyTime_t t;
1193
    if (get_perf_counter(&t) < 0) {
  Branch (1193:9): [True: 0, False: 1]
1194
        return NULL;
1195
    }
1196
    return _PyTime_AsNanosecondsObject(t);
1197
}
1198
1199
PyDoc_STRVAR(perf_counter_ns_doc,
1200
"perf_counter_ns() -> int\n\
1201
\n\
1202
Performance counter for benchmarking as nanoseconds.");
1203
1204
static int
1205
_PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1206
{
1207
#if defined(MS_WINDOWS)
1208
    HANDLE process;
1209
    FILETIME creation_time, exit_time, kernel_time, user_time;
1210
    ULARGE_INTEGER large;
1211
    _PyTime_t ktime, utime, t;
1212
    BOOL ok;
1213
1214
    process = GetCurrentProcess();
1215
    ok = GetProcessTimes(process, &creation_time, &exit_time,
1216
                         &kernel_time, &user_time);
1217
    if (!ok) {
1218
        PyErr_SetFromWindowsErr(0);
1219
        return -1;
1220
    }
1221
1222
    if (info) {
1223
        info->implementation = "GetProcessTimes()";
1224
        info->resolution = 1e-7;
1225
        info->monotonic = 1;
1226
        info->adjustable = 0;
1227
    }
1228
1229
    large.u.LowPart = kernel_time.dwLowDateTime;
1230
    large.u.HighPart = kernel_time.dwHighDateTime;
1231
    ktime = large.QuadPart;
1232
1233
    large.u.LowPart = user_time.dwLowDateTime;
1234
    large.u.HighPart = user_time.dwHighDateTime;
1235
    utime = large.QuadPart;
1236
1237
    /* ktime and utime have a resolution of 100 nanoseconds */
1238
    t = _PyTime_FromNanoseconds((ktime + utime) * 100);
1239
    *tp = t;
1240
    return 0;
1241
#else
1242
1243
    /* clock_gettime */
1244
#if defined(HAVE_CLOCK_GETTIME) \
1245
    && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF))
1246
    struct timespec ts;
1247
1248
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
1249
1250
#ifdef CLOCK_PROF
1251
        const clockid_t clk_id = CLOCK_PROF;
1252
        const char *function = "clock_gettime(CLOCK_PROF)";
1253
#else
1254
        const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
1255
        const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
1256
#endif
1257
1258
        if (clock_gettime(clk_id, &ts) == 0) {
  Branch (1258:13): [True: 1.96k, False: 0]
1259
            if (info) {
  Branch (1259:17): [True: 2, False: 1.96k]
1260
                struct timespec res;
1261
                info->implementation = function;
1262
                info->monotonic = 1;
1263
                info->adjustable = 0;
1264
                if (clock_getres(clk_id, &res)) {
  Branch (1264:21): [True: 0, False: 2]
1265
                    PyErr_SetFromErrno(PyExc_OSError);
1266
                    return -1;
1267
                }
1268
                info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1269
            }
1270
1271
            if (_PyTime_FromTimespec(tp, &ts) < 0) {
  Branch (1271:17): [True: 0, False: 1.96k]
1272
                return -1;
1273
            }
1274
            return 0;
1275
        }
1276
    }
1277
#endif
1278
1279
    /* getrusage(RUSAGE_SELF) */
1280
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRUSAGE)
1281
    struct rusage ru;
1282
1283
    if (getrusage(RUSAGE_SELF, &ru) == 0) {
  Branch (1283:9): [True: 0, False: 0]
1284
        _PyTime_t utime, stime;
1285
1286
        if (info) {
  Branch (1286:13): [True: 0, False: 0]
1287
            info->implementation = "getrusage(RUSAGE_SELF)";
1288
            info->monotonic = 1;
1289
            info->adjustable = 0;
1290
            info->resolution = 1e-6;
1291
        }
1292
1293
        if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) {
  Branch (1293:13): [True: 0, False: 0]
1294
            return -1;
1295
        }
1296
        if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) {
  Branch (1296:13): [True: 0, False: 0]
1297
            return -1;
1298
        }
1299
1300
        _PyTime_t total = utime + stime;
1301
        *tp = total;
1302
        return 0;
1303
    }
1304
#endif
1305
1306
    /* times() */
1307
#ifdef HAVE_TIMES
1308
    struct tms t;
1309
1310
    if (times(&t) != (clock_t)-1) {
  Branch (1310:9): [True: 0, False: 0]
1311
        static long ticks_per_second = -1;
1312
1313
        if (ticks_per_second == -1) {
  Branch (1313:13): [True: 0, False: 0]
1314
            long freq;
1315
#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
1316
            freq = sysconf(_SC_CLK_TCK);
1317
            if (freq < 1) {
  Branch (1317:17): [True: 0, False: 0]
1318
                freq = -1;
1319
            }
1320
#elif defined(HZ)
1321
            freq = HZ;
1322
#else
1323
            freq = 60; /* magic fallback value; may be bogus */
1324
#endif
1325
1326
            if (freq != -1) {
  Branch (1326:17): [True: 0, False: 0]
1327
                /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second)
1328
                   cannot overflow below */
1329
#if LONG_MAX > _PyTime_MAX / SEC_TO_NS
1330
                if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) {
  Branch (1330:21): [True: 0, False: 0]
1331
                    PyErr_SetString(PyExc_OverflowError,
1332
                                    "_SC_CLK_TCK is too large");
1333
                    return -1;
1334
                }
1335
#endif
1336
1337
                ticks_per_second = freq;
1338
            }
1339
        }
1340
1341
        if (ticks_per_second != -1) {
  Branch (1341:13): [True: 0, False: 0]
1342
            if (info) {
  Branch (1342:17): [True: 0, False: 0]
1343
                info->implementation = "times()";
1344
                info->monotonic = 1;
1345
                info->adjustable = 0;
1346
                info->resolution = 1.0 / (double)ticks_per_second;
1347
            }
1348
1349
            _PyTime_t ns;
1350
            ns = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second);
1351
            ns += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second);
1352
            *tp = _PyTime_FromNanoseconds(ns);
1353
            return 0;
1354
        }
1355
    }
1356
#endif
1357
1358
    /* clock */
1359
    /* Currently, Python 3 requires clock() to build: see issue #22624 */
1360
    return _PyTime_GetClockWithInfo(tp, info);
1361
#endif
1362
}
1363
1364
static PyObject *
1365
time_process_time(PyObject *self, PyObject *unused)
1366
{
1367
    _PyTime_t t;
1368
    if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
  Branch (1368:9): [True: 0, False: 1.96k]
1369
        return NULL;
1370
    }
1371
    return _PyFloat_FromPyTime(t);
1372
}
1373
1374
PyDoc_STRVAR(process_time_doc,
1375
"process_time() -> float\n\
1376
\n\
1377
Process time for profiling: sum of the kernel and user-space CPU time.");
1378
1379
static PyObject *
1380
time_process_time_ns(PyObject *self, PyObject *unused)
1381
{
1382
    _PyTime_t t;
1383
    if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
  Branch (1383:9): [True: 0, False: 1]
1384
        return NULL;
1385
    }
1386
    return _PyTime_AsNanosecondsObject(t);
1387
}
1388
1389
PyDoc_STRVAR(process_time_ns_doc,
1390
"process_time() -> int\n\
1391
\n\
1392
Process time for profiling as nanoseconds:\n\
1393
sum of the kernel and user-space CPU time.");
1394
1395
1396
#if defined(MS_WINDOWS)
1397
#define HAVE_THREAD_TIME
1398
static int
1399
_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1400
{
1401
    HANDLE thread;
1402
    FILETIME creation_time, exit_time, kernel_time, user_time;
1403
    ULARGE_INTEGER large;
1404
    _PyTime_t ktime, utime, t;
1405
    BOOL ok;
1406
1407
    thread =  GetCurrentThread();
1408
    ok = GetThreadTimes(thread, &creation_time, &exit_time,
1409
                        &kernel_time, &user_time);
1410
    if (!ok) {
1411
        PyErr_SetFromWindowsErr(0);
1412
        return -1;
1413
    }
1414
1415
    if (info) {
1416
        info->implementation = "GetThreadTimes()";
1417
        info->resolution = 1e-7;
1418
        info->monotonic = 1;
1419
        info->adjustable = 0;
1420
    }
1421
1422
    large.u.LowPart = kernel_time.dwLowDateTime;
1423
    large.u.HighPart = kernel_time.dwHighDateTime;
1424
    ktime = large.QuadPart;
1425
1426
    large.u.LowPart = user_time.dwLowDateTime;
1427
    large.u.HighPart = user_time.dwHighDateTime;
1428
    utime = large.QuadPart;
1429
1430
    /* ktime and utime have a resolution of 100 nanoseconds */
1431
    t = _PyTime_FromNanoseconds((ktime + utime) * 100);
1432
    *tp = t;
1433
    return 0;
1434
}
1435
1436
#elif defined(_AIX)
1437
#define HAVE_THREAD_TIME
1438
static int
1439
_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1440
{
1441
    /* bpo-40192: On AIX, thread_cputime() is preferred: it has nanosecond
1442
       resolution, whereas clock_gettime(CLOCK_THREAD_CPUTIME_ID)
1443
       has a resolution of 10 ms. */
1444
    thread_cputime_t tc;
1445
    if (thread_cputime(-1, &tc) != 0) {
1446
        PyErr_SetFromErrno(PyExc_OSError);
1447
        return -1;
1448
    }
1449
1450
    if (info) {
1451
        info->implementation = "thread_cputime()";
1452
        info->monotonic = 1;
1453
        info->adjustable = 0;
1454
        info->resolution = 1e-9;
1455
    }
1456
    *tp = _PyTime_FromNanoseconds(tc.stime + tc.utime);
1457
    return 0;
1458
}
1459
1460
#elif defined(__sun) && defined(__SVR4)
1461
#define HAVE_THREAD_TIME
1462
static int
1463
_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1464
{
1465
    /* bpo-35455: On Solaris, CLOCK_THREAD_CPUTIME_ID clock is not always
1466
       available; use gethrvtime() to substitute this functionality. */
1467
    if (info) {
1468
        info->implementation = "gethrvtime()";
1469
        info->resolution = 1e-9;
1470
        info->monotonic = 1;
1471
        info->adjustable = 0;
1472
    }
1473
    *tp = _PyTime_FromNanoseconds(gethrvtime());
1474
    return 0;
1475
}
1476
1477
#elif defined(HAVE_CLOCK_GETTIME) && \
1478
      defined(CLOCK_PROCESS_CPUTIME_ID) && \
1479
      !defined(__EMSCRIPTEN__) && !defined(__wasi__)
1480
#define HAVE_THREAD_TIME
1481
1482
#if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability)
1483
static int
1484
_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1485
     __attribute__((availability(macos, introduced=10.12)))
1486
     __attribute__((availability(ios, introduced=10.0)))
1487
     __attribute__((availability(tvos, introduced=10.0)))
1488
     __attribute__((availability(watchos, introduced=3.0)));
1489
#endif
1490
1491
static int
1492
_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
1493
{
1494
    struct timespec ts;
1495
    const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID;
1496
    const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)";
1497
1498
    if (clock_gettime(clk_id, &ts)) {
  Branch (1498:9): [True: 0, False: 6]
1499
        PyErr_SetFromErrno(PyExc_OSError);
1500
        return -1;
1501
    }
1502
    if (info) {
  Branch (1502:9): [True: 2, False: 4]
1503
        struct timespec res;
1504
        info->implementation = function;
1505
        info->monotonic = 1;
1506
        info->adjustable = 0;
1507
        if (clock_getres(clk_id, &res)) {
  Branch (1507:13): [True: 0, False: 2]
1508
            PyErr_SetFromErrno(PyExc_OSError);
1509
            return -1;
1510
        }
1511
        info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
1512
    }
1513
1514
    if (_PyTime_FromTimespec(tp, &ts) < 0) {
  Branch (1514:9): [True: 0, False: 6]
1515
        return -1;
1516
    }
1517
    return 0;
1518
}
1519
#endif
1520
1521
#ifdef HAVE_THREAD_TIME
1522
#ifdef __APPLE__
1523
/*
1524
 * The clock_* functions will be removed from the module
1525
 * dict entirely when the C API is not available.
1526
 */
1527
#pragma clang diagnostic push
1528
#pragma clang diagnostic ignored "-Wunguarded-availability"
1529
#endif
1530
1531
static PyObject *
1532
time_thread_time(PyObject *self, PyObject *unused)
1533
{
1534
    _PyTime_t t;
1535
    if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
  Branch (1535:9): [True: 0, False: 3]
1536
        return NULL;
1537
    }
1538
    return _PyFloat_FromPyTime(t);
1539
}
1540
1541
PyDoc_STRVAR(thread_time_doc,
1542
"thread_time() -> float\n\
1543
\n\
1544
Thread time for profiling: sum of the kernel and user-space CPU time.");
1545
1546
static PyObject *
1547
time_thread_time_ns(PyObject *self, PyObject *unused)
1548
{
1549
    _PyTime_t t;
1550
    if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
  Branch (1550:9): [True: 0, False: 1]
1551
        return NULL;
1552
    }
1553
    return _PyTime_AsNanosecondsObject(t);
1554
}
1555
1556
PyDoc_STRVAR(thread_time_ns_doc,
1557
"thread_time() -> int\n\
1558
\n\
1559
Thread time for profiling as nanoseconds:\n\
1560
sum of the kernel and user-space CPU time.");
1561
1562
#ifdef __APPLE__
1563
#pragma clang diagnostic pop
1564
#endif
1565
1566
#endif
1567
1568
1569
static PyObject *
1570
time_get_clock_info(PyObject *self, PyObject *args)
1571
{
1572
    char *name;
1573
    _Py_clock_info_t info;
1574
    PyObject *obj = NULL, *dict, *ns;
1575
    _PyTime_t t;
1576
1577
    if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) {
  Branch (1577:9): [True: 0, False: 3.00k]
1578
        return NULL;
1579
    }
1580
1581
#ifdef Py_DEBUG
1582
    info.implementation = NULL;
1583
    info.monotonic = -1;
1584
    info.adjustable = -1;
1585
    info.resolution = -1.0;
1586
#else
1587
    info.implementation = "";
1588
    info.monotonic = 0;
1589
    info.adjustable = 0;
1590
    info.resolution = 1.0;
1591
#endif
1592
1593
    if (strcmp(name, "time") == 0) {
  Branch (1593:9): [True: 2, False: 3.00k]
1594
        if (_PyTime_GetSystemClockWithInfo(&t, &info) < 0) {
  Branch (1594:13): [True: 0, False: 2]
1595
            return NULL;
1596
        }
1597
    }
1598
    else if (strcmp(name, "monotonic") == 0) {
  Branch (1598:14): [True: 2.99k, False: 6]
1599
        if (_PyTime_GetMonotonicClockWithInfo(&t, &info) < 0) {
  Branch (1599:13): [True: 0, False: 2.99k]
1600
            return NULL;
1601
        }
1602
    }
1603
    else if (strcmp(name, "perf_counter") == 0) {
  Branch (1603:14): [True: 1, False: 5]
1604
        if (_PyTime_GetPerfCounterWithInfo(&t, &info) < 0) {
  Branch (1604:13): [True: 0, False: 1]
1605
            return NULL;
1606
        }
1607
    }
1608
    else if (strcmp(name, "process_time") == 0) {
  Branch (1608:14): [True: 2, False: 3]
1609
        if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) {
  Branch (1609:13): [True: 0, False: 2]
1610
            return NULL;
1611
        }
1612
    }
1613
#ifdef HAVE_THREAD_TIME
1614
    else if (strcmp(name, "thread_time") == 0) {
  Branch (1614:14): [True: 2, False: 1]
1615
1616
#ifdef __APPLE__
1617
        if (HAVE_CLOCK_GETTIME_RUNTIME) {
1618
#endif
1619
            if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) {
  Branch (1619:17): [True: 0, False: 2]
1620
                return NULL;
1621
            }
1622
#ifdef __APPLE__
1623
        } else {
1624
            PyErr_SetString(PyExc_ValueError, "unknown clock");
1625
            return NULL;
1626
        }
1627
#endif
1628
    }
1629
#endif
1630
    else {
1631
        PyErr_SetString(PyExc_ValueError, "unknown clock");
1632
        return NULL;
1633
    }
1634
1635
    dict = PyDict_New();
1636
    if (dict == NULL) {
  Branch (1636:9): [True: 0, False: 3.00k]
1637
        return NULL;
1638
    }
1639
1640
    assert(info.implementation != NULL);
1641
    obj = PyUnicode_FromString(info.implementation);
1642
    if (obj == NULL) {
  Branch (1642:9): [True: 0, False: 3.00k]
1643
        goto error;
1644
    }
1645
    if (PyDict_SetItemString(dict, "implementation", obj) == -1) {
  Branch (1645:9): [True: 0, False: 3.00k]
1646
        goto error;
1647
    }
1648
    Py_CLEAR(obj);
1649
1650
    assert(info.monotonic != -1);
1651
    obj = PyBool_FromLong(info.monotonic);
1652
    if (obj == NULL) {
  Branch (1652:9): [True: 0, False: 3.00k]
1653
        goto error;
1654
    }
1655
    if (PyDict_SetItemString(dict, "monotonic", obj) == -1) {
  Branch (1655:9): [True: 0, False: 3.00k]
1656
        goto error;
1657
    }
1658
    Py_CLEAR(obj);
1659
1660
    assert(info.adjustable != -1);
1661
    obj = PyBool_FromLong(info.adjustable);
1662
    if (obj == NULL) {
  Branch (1662:9): [True: 0, False: 3.00k]
1663
        goto error;
1664
    }
1665
    if (PyDict_SetItemString(dict, "adjustable", obj) == -1) {
  Branch (1665:9): [True: 0, False: 3.00k]
1666
        goto error;
1667
    }
1668
    Py_CLEAR(obj);
1669
1670
    assert(info.resolution > 0.0);
1671
    assert(info.resolution <= 1.0);
1672
    obj = PyFloat_FromDouble(info.resolution);
1673
    if (obj == NULL) {
  Branch (1673:9): [True: 0, False: 3.00k]
1674
        goto error;
1675
    }
1676
    if (PyDict_SetItemString(dict, "resolution", obj) == -1) {
  Branch (1676:9): [True: 0, False: 3.00k]
1677
        goto error;
1678
    }
1679
    Py_CLEAR(obj);
1680
1681
    ns = _PyNamespace_New(dict);
1682
    Py_DECREF(dict);
1683
    return ns;
1684
1685
error:
1686
    Py_DECREF(dict);
1687
    Py_XDECREF(obj);
1688
    return NULL;
1689
}
1690
1691
PyDoc_STRVAR(get_clock_info_doc,
1692
"get_clock_info(name: str) -> dict\n\
1693
\n\
1694
Get information of the specified clock.");
1695
1696
#ifndef HAVE_DECL_TZNAME
1697
static void
1698
get_zone(char *zone, int n, struct tm *p)
1699
{
1700
#ifdef HAVE_STRUCT_TM_TM_ZONE
1701
    strncpy(zone, p->tm_zone ? p->tm_zone : 
" "0
, n);
  Branch (1701:19): [True: 816, False: 0]
1702
#else
1703
    tzset();
1704
    strftime(zone, n, "%Z", p);
1705
#endif
1706
}
1707
1708
static time_t
1709
get_gmtoff(time_t t, struct tm *p)
1710
{
1711
#ifdef HAVE_STRUCT_TM_TM_ZONE
1712
    return p->tm_gmtoff;
1713
#else
1714
    return timegm(p) - t;
1715
#endif
1716
}
1717
#endif // !HAVE_DECL_TZNAME
1718
1719
static int
1720
init_timezone(PyObject *m)
1721
{
1722
    assert(!PyErr_Occurred());
1723
1724
    /* This code moved from PyInit_time wholesale to allow calling it from
1725
    time_tzset. In the future, some parts of it can be moved back
1726
    (for platforms that don't HAVE_WORKING_TZSET, when we know what they
1727
    are), and the extraneous calls to tzset(3) should be removed.
1728
    I haven't done this yet, as I don't want to change this code as
1729
    little as possible when introducing the time.tzset and time.tzsetwall
1730
    methods. This should simply be a method of doing the following once,
1731
    at the top of this function and removing the call to tzset() from
1732
    time_tzset():
1733
1734
        #ifdef HAVE_TZSET
1735
        tzset()
1736
        #endif
1737
1738
    And I'm lazy and hate C so nyer.
1739
     */
1740
#ifdef HAVE_DECL_TZNAME
1741
    PyObject *otz0, *otz1;
1742
    tzset();
1743
    PyModule_AddIntConstant(m, "timezone", _Py_timezone);
1744
#ifdef HAVE_ALTZONE
1745
    PyModule_AddIntConstant(m, "altzone", altzone);
1746
#else
1747
    PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600);
1748
#endif
1749
    PyModule_AddIntConstant(m, "daylight", _Py_daylight);
1750
#ifdef MS_WINDOWS
1751
    TIME_ZONE_INFORMATION tzinfo = {0};
1752
    GetTimeZoneInformation(&tzinfo);
1753
    otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1);
1754
    if (otz0 == NULL) {
1755
        return -1;
1756
    }
1757
    otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1);
1758
    if (otz1 == NULL) {
1759
        Py_DECREF(otz0);
1760
        return -1;
1761
    }
1762
#else
1763
    otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape");
1764
    if (otz0 == NULL) {
1765
        return -1;
1766
    }
1767
    otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape");
1768
    if (otz1 == NULL) {
1769
        Py_DECREF(otz0);
1770
        return -1;
1771
    }
1772
#endif // MS_WINDOWS
1773
    PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1);
1774
    if (tzname_obj == NULL) {
1775
        return -1;
1776
    }
1777
    PyModule_AddObject(m, "tzname", tzname_obj);
1778
#else // !HAVE_DECL_TZNAME
1779
    static const time_t YEAR = (365 * 24 + 6) * 3600;
1780
    time_t t;
1781
    struct tm p;
1782
    time_t janzone_t, julyzone_t;
1783
    char janname[10], julyname[10];
1784
    t = (time((time_t *)0) / YEAR) * YEAR;
1785
    _PyTime_localtime(t, &p);
1786
    get_zone(janname, 9, &p);
1787
    janzone_t = -get_gmtoff(t, &p);
1788
    janname[9] = '\0';
1789
    t += YEAR/2;
1790
    _PyTime_localtime(t, &p);
1791
    get_zone(julyname, 9, &p);
1792
    julyzone_t = -get_gmtoff(t, &p);
1793
    julyname[9] = '\0';
1794
1795
    /* Sanity check, don't check for the validity of timezones.
1796
       In practice, it should be more in range -12 hours .. +14 hours. */
1797
#define MAX_TIMEZONE (48 * 3600)
1798
    if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE
  Branch (1798:9): [True: 0, False: 408]
  Branch (1798:38): [True: 0, False: 408]
1799
        || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE)
  Branch (1799:12): [True: 0, False: 408]
  Branch (1799:42): [True: 0, False: 408]
1800
    {
1801
        PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset");
1802
        return -1;
1803
    }
1804
    int janzone = (int)janzone_t;
1805
    int julyzone = (int)julyzone_t;
1806
1807
    PyObject *tzname_obj;
1808
    if (janzone < julyzone) {
  Branch (1808:9): [True: 5, False: 403]
1809
        /* DST is reversed in the southern hemisphere */
1810
        PyModule_AddIntConstant(m, "timezone", julyzone);
1811
        PyModule_AddIntConstant(m, "altzone", janzone);
1812
        PyModule_AddIntConstant(m, "daylight", janzone != julyzone);
1813
        tzname_obj = Py_BuildValue("(zz)", julyname, janname);
1814
    } else {
1815
        PyModule_AddIntConstant(m, "timezone", janzone);
1816
        PyModule_AddIntConstant(m, "altzone", julyzone);
1817
        PyModule_AddIntConstant(m, "daylight", janzone != julyzone);
1818
        tzname_obj = Py_BuildValue("(zz)", janname, julyname);
1819
    }
1820
    if (tzname_obj == NULL) {
  Branch (1820:9): [True: 0, False: 408]
1821
        return -1;
1822
    }
1823
    PyModule_AddObject(m, "tzname", tzname_obj);
1824
#endif // !HAVE_DECL_TZNAME
1825
1826
    if (PyErr_Occurred()) {
  Branch (1826:9): [True: 0, False: 408]
1827
        return -1;
1828
    }
1829
    return 0;
1830
}
1831
1832
1833
static PyMethodDef time_methods[] = {
1834
    {"time",            time_time, METH_NOARGS, time_doc},
1835
    {"time_ns",         time_time_ns, METH_NOARGS, time_ns_doc},
1836
#ifdef HAVE_CLOCK_GETTIME
1837
    {"clock_gettime",   time_clock_gettime, METH_VARARGS, clock_gettime_doc},
1838
    {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc},
1839
#endif
1840
#ifdef HAVE_CLOCK_SETTIME
1841
    {"clock_settime",   time_clock_settime, METH_VARARGS, clock_settime_doc},
1842
    {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc},
1843
#endif
1844
#ifdef HAVE_CLOCK_GETRES
1845
    {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
1846
#endif
1847
#ifdef HAVE_PTHREAD_GETCPUCLOCKID
1848
    {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc},
1849
#endif
1850
    {"sleep",           time_sleep, METH_O, sleep_doc},
1851
    {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
1852
    {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
1853
    {"asctime",         time_asctime, METH_VARARGS, asctime_doc},
1854
    {"ctime",           time_ctime, METH_VARARGS, ctime_doc},
1855
#ifdef HAVE_MKTIME
1856
    {"mktime",          time_mktime, METH_O, mktime_doc},
1857
#endif
1858
#ifdef HAVE_STRFTIME
1859
    {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
1860
#endif
1861
    {"strptime",        time_strptime, METH_VARARGS, strptime_doc},
1862
#ifdef HAVE_WORKING_TZSET
1863
    {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
1864
#endif
1865
    {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
1866
    {"monotonic_ns",    time_monotonic_ns, METH_NOARGS, monotonic_ns_doc},
1867
    {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
1868
    {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc},
1869
#ifdef HAVE_THREAD_TIME
1870
    {"thread_time",     time_thread_time, METH_NOARGS, thread_time_doc},
1871
    {"thread_time_ns",  time_thread_time_ns, METH_NOARGS, thread_time_ns_doc},
1872
#endif
1873
    {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
1874
    {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc},
1875
    {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},
1876
    {NULL,              NULL}           /* sentinel */
1877
};
1878
1879
1880
PyDoc_STRVAR(module_doc,
1881
"This module provides various functions to manipulate time values.\n\
1882
\n\
1883
There are two standard representations of time.  One is the number\n\
1884
of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\n\
1885
or a floating point number (to represent fractions of seconds).\n\
1886
The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
1887
The actual value can be retrieved by calling gmtime(0).\n\
1888
\n\
1889
The other representation is a tuple of 9 integers giving local time.\n\
1890
The tuple items are:\n\
1891
  year (including century, e.g. 1998)\n\
1892
  month (1-12)\n\
1893
  day (1-31)\n\
1894
  hours (0-23)\n\
1895
  minutes (0-59)\n\
1896
  seconds (0-59)\n\
1897
  weekday (0-6, Monday is 0)\n\
1898
  Julian day (day in the year, 1-366)\n\
1899
  DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
1900
If the DST flag is 0, the time is given in the regular time zone;\n\
1901
if it is 1, the time is given in the DST time zone;\n\
1902
if it is -1, mktime() should guess based on the date and time.\n");
1903
1904
1905
static int
1906
time_exec(PyObject *module)
1907
{
1908
    time_module_state *state = get_time_state(module);
1909
#if defined(__APPLE__) && defined(HAVE_CLOCK_GETTIME)
1910
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
1911
        /* pass: ^^^ cannot use '!' here */
1912
    } else {
1913
        PyObject* dct = PyModule_GetDict(module);
1914
        if (dct == NULL) {
1915
            return -1;
1916
        }
1917
1918
        if (PyDict_DelItemString(dct, "clock_gettime") == -1) {
1919
            PyErr_Clear();
1920
        }
1921
        if (PyDict_DelItemString(dct, "clock_gettime_ns") == -1) {
1922
            PyErr_Clear();
1923
        }
1924
        if (PyDict_DelItemString(dct, "clock_settime") == -1) {
1925
            PyErr_Clear();
1926
        }
1927
        if (PyDict_DelItemString(dct, "clock_settime_ns") == -1) {
1928
            PyErr_Clear();
1929
        }
1930
        if (PyDict_DelItemString(dct, "clock_getres") == -1) {
1931
            PyErr_Clear();
1932
        }
1933
    }
1934
#endif
1935
#if defined(__APPLE__) && defined(HAVE_THREAD_TIME)
1936
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
1937
        /* pass: ^^^ cannot use '!' here */
1938
    } else {
1939
        PyObject* dct = PyModule_GetDict(module);
1940
1941
        if (PyDict_DelItemString(dct, "thread_time") == -1) {
1942
            PyErr_Clear();
1943
        }
1944
        if (PyDict_DelItemString(dct, "thread_time_ns") == -1) {
1945
            PyErr_Clear();
1946
        }
1947
    }
1948
#endif
1949
    /* Set, or reset, module variables like time.timezone */
1950
    if (init_timezone(module) < 0) {
  Branch (1950:9): [True: 0, False: 283]
1951
        return -1;
1952
    }
1953
1954
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES)
1955
    if (HAVE_CLOCK_GETTIME_RUNTIME) {
1956
1957
#ifdef CLOCK_REALTIME
1958
        if (PyModule_AddIntMacro(module, CLOCK_REALTIME) < 0) {
  Branch (1958:13): [True: 0, False: 283]
1959
            return -1;
1960
        }
1961
#endif
1962
1963
#ifdef CLOCK_MONOTONIC
1964
1965
        if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC) < 0) {
  Branch (1965:13): [True: 0, False: 283]
1966
            return -1;
1967
        }
1968
1969
#endif
1970
#ifdef CLOCK_MONOTONIC_RAW
1971
        if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW) < 0) {
  Branch (1971:13): [True: 0, False: 283]
1972
            return -1;
1973
        }
1974
#endif
1975
1976
#ifdef CLOCK_HIGHRES
1977
        if (PyModule_AddIntMacro(module, CLOCK_HIGHRES) < 0) {
1978
            return -1;
1979
        }
1980
#endif
1981
#ifdef CLOCK_PROCESS_CPUTIME_ID
1982
        if (PyModule_AddIntMacro(module, CLOCK_PROCESS_CPUTIME_ID) < 0) {
  Branch (1982:13): [True: 0, False: 283]
1983
            return -1;
1984
        }
1985
#endif
1986
1987
#ifdef CLOCK_THREAD_CPUTIME_ID
1988
        if (PyModule_AddIntMacro(module, CLOCK_THREAD_CPUTIME_ID) < 0) {
  Branch (1988:13): [True: 0, False: 283]
1989
            return -1;
1990
        }
1991
#endif
1992
#ifdef CLOCK_PROF
1993
        if (PyModule_AddIntMacro(module, CLOCK_PROF) < 0) {
1994
            return -1;
1995
        }
1996
#endif
1997
#ifdef CLOCK_BOOTTIME
1998
        if (PyModule_AddIntMacro(module, CLOCK_BOOTTIME) < 0) {
  Branch (1998:13): [True: 0, False: 283]
1999
            return -1;
2000
        }
2001
#endif
2002
#ifdef CLOCK_TAI
2003
        if (PyModule_AddIntMacro(module, CLOCK_TAI) < 0) {
  Branch (2003:13): [True: 0, False: 283]
2004
            return -1;
2005
        }
2006
#endif
2007
#ifdef CLOCK_UPTIME
2008
        if (PyModule_AddIntMacro(module, CLOCK_UPTIME) < 0) {
2009
            return -1;
2010
        }
2011
#endif
2012
#ifdef CLOCK_UPTIME_RAW
2013
2014
        if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW) < 0) {
2015
            return -1;
2016
        }
2017
#endif
2018
    }
2019
2020
#endif  /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */
2021
2022
    if (PyModule_AddIntConstant(module, "_STRUCT_TM_ITEMS", 11)) {
  Branch (2022:9): [True: 0, False: 283]
2023
        return -1;
2024
    }
2025
2026
    // struct_time type
2027
    state->struct_time_type = PyStructSequence_NewType(&struct_time_type_desc);
2028
    if (state->struct_time_type == NULL) {
  Branch (2028:9): [True: 0, False: 283]
2029
        return -1;
2030
    }
2031
    if (PyModule_AddType(module, state->struct_time_type)) {
  Branch (2031:9): [True: 0, False: 283]
2032
        return -1;
2033
    }
2034
2035
#if defined(__linux__) && !defined(__GLIBC__)
2036
    struct tm tm;
2037
    const time_t zero = 0;
2038
    if (gmtime_r(&zero, &tm) != NULL)
2039
        utc_string = tm.tm_zone;
2040
#endif
2041
2042
#if defined(MS_WINDOWS)
2043
    if (timer_flags == (DWORD)-1) {
2044
        DWORD test_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
2045
        HANDLE timer = CreateWaitableTimerExW(NULL, NULL, test_flags,
2046
                                              TIMER_ALL_ACCESS);
2047
        if (timer == NULL) {
2048
            // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is not supported.
2049
            timer_flags = 0;
2050
        }
2051
        else {
2052
            // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is supported.
2053
            timer_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
2054
            CloseHandle(timer);
2055
        }
2056
    }
2057
#endif
2058
2059
    return 0;
2060
}
2061
2062
2063
static int
2064
time_module_traverse(PyObject *module, visitproc visit, void *arg)
2065
{
2066
    time_module_state *state = get_time_state(module);
2067
    Py_VISIT(state->struct_time_type);
2068
    return 0;
2069
}
2070
2071
2072
static int
2073
time_module_clear(PyObject *module)
2074
{
2075
    time_module_state *state = get_time_state(module);
2076
    Py_CLEAR(state->struct_time_type);
2077
    return 0;
2078
}
2079
2080
2081
static void
2082
time_module_free(void *module)
2083
{
2084
    time_module_clear((PyObject *)module);
2085
}
2086
2087
2088
static struct PyModuleDef_Slot time_slots[] = {
2089
    {Py_mod_exec, time_exec},
2090
    {0, NULL}
2091
};
2092
2093
static struct PyModuleDef timemodule = {
2094
    PyModuleDef_HEAD_INIT,
2095
    .m_name = "time",
2096
    .m_doc = module_doc,
2097
    .m_size = sizeof(time_module_state),
2098
    .m_methods = time_methods,
2099
    .m_slots = time_slots,
2100
    .m_traverse = time_module_traverse,
2101
    .m_clear = time_module_clear,
2102
    .m_free = time_module_free,
2103
};
2104
2105
PyMODINIT_FUNC
2106
PyInit_time(void)
2107
{
2108
    return PyModuleDef_Init(&timemodule);
2109
}
2110
2111
2112
// time.sleep() implementation.
2113
// On error, raise an exception and return -1.
2114
// On success, return 0.
2115
static int
2116
pysleep(_PyTime_t timeout)
2117
{
2118
    assert(timeout >= 0);
2119
2120
#ifndef MS_WINDOWS
2121
#ifdef HAVE_CLOCK_NANOSLEEP
2122
    struct timespec timeout_abs;
2123
#elif defined(HAVE_NANOSLEEP)
2124
    struct timespec timeout_ts;
2125
#else
2126
    struct timeval timeout_tv;
2127
#endif
2128
    _PyTime_t deadline, monotonic;
2129
    int err = 0;
2130
2131
    if (get_monotonic(&monotonic) < 0) {
  Branch (2131:9): [True: 0, False: 89.3k]
2132
        return -1;
2133
    }
2134
    deadline = monotonic + timeout;
2135
#ifdef HAVE_CLOCK_NANOSLEEP
2136
    if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) {
  Branch (2136:9): [True: 0, False: 89.3k]
2137
        return -1;
2138
    }
2139
#endif
2140
2141
    
do 89.3k
{
2142
#ifdef HAVE_CLOCK_NANOSLEEP
2143
        // use timeout_abs
2144
#elif defined(HAVE_NANOSLEEP)
2145
        if (_PyTime_AsTimespec(timeout, &timeout_ts) < 0) {
2146
            return -1;
2147
        }
2148
#else
2149
        if (_PyTime_AsTimeval(timeout, &timeout_tv, _PyTime_ROUND_CEILING) < 0) {
2150
            return -1;
2151
        }
2152
#endif
2153
2154
        int ret;
2155
        Py_BEGIN_ALLOW_THREADS
2156
#ifdef HAVE_CLOCK_NANOSLEEP
2157
        ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL);
2158
        err = ret;
2159
#elif defined(HAVE_NANOSLEEP)
2160
        ret = nanosleep(&timeout_ts, NULL);
2161
        err = errno;
2162
#else
2163
        ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout_tv);
2164
        err = errno;
2165
#endif
2166
        Py_END_ALLOW_THREADS
2167
2168
        if (ret == 0) {
  Branch (2168:13): [True: 89.3k, False: 3.75k]
2169
            break;
2170
        }
2171
2172
        if (err != EINTR) {
  Branch (2172:13): [True: 0, False: 3.75k]
2173
            errno = err;
2174
            PyErr_SetFromErrno(PyExc_OSError);
2175
            return -1;
2176
        }
2177
2178
        /* sleep was interrupted by SIGINT */
2179
        if (PyErr_CheckSignals()) {
  Branch (2179:13): [True: 0, False: 3.75k]
2180
            return -1;
2181
        }
2182
2183
#ifndef HAVE_CLOCK_NANOSLEEP
2184
        if (get_monotonic(&monotonic) < 0) {
2185
            return -1;
2186
        }
2187
        timeout = deadline - monotonic;
2188
        if (timeout < 0) {
2189
            break;
2190
        }
2191
        /* retry with the recomputed delay */
2192
#endif
2193
    } while (1);
  Branch (2193:14): [Folded - Ignored]
2194
2195
    return 0;
2196
#else  // MS_WINDOWS
2197
    _PyTime_t timeout_100ns = _PyTime_As100Nanoseconds(timeout,
2198
                                                       _PyTime_ROUND_CEILING);
2199
2200
    // Maintain Windows Sleep() semantics for time.sleep(0)
2201
    if (timeout_100ns == 0) {
2202
        Py_BEGIN_ALLOW_THREADS
2203
        // A value of zero causes the thread to relinquish the remainder of its
2204
        // time slice to any other thread that is ready to run. If there are no
2205
        // other threads ready to run, the function returns immediately, and
2206
        // the thread continues execution.
2207
        Sleep(0);
2208
        Py_END_ALLOW_THREADS
2209
        return 0;
2210
    }
2211
2212
    LARGE_INTEGER relative_timeout;
2213
    // No need to check for integer overflow, both types are signed
2214
    assert(sizeof(relative_timeout) == sizeof(timeout_100ns));
2215
    // SetWaitableTimer(): a negative due time indicates relative time
2216
    relative_timeout.QuadPart = -timeout_100ns;
2217
2218
    HANDLE timer = CreateWaitableTimerExW(NULL, NULL, timer_flags,
2219
                                          TIMER_ALL_ACCESS);
2220
    if (timer == NULL) {
2221
        PyErr_SetFromWindowsErr(0);
2222
        return -1;
2223
    }
2224
2225
    if (!SetWaitableTimerEx(timer, &relative_timeout,
2226
                            0, // no period; the timer is signaled once
2227
                            NULL, NULL, // no completion routine
2228
                            NULL,  // no wake context; do not resume from suspend
2229
                            0)) // no tolerable delay for timer coalescing
2230
    {
2231
        PyErr_SetFromWindowsErr(0);
2232
        goto error;
2233
    }
2234
2235
    // Only the main thread can be interrupted by SIGINT.
2236
    // Signal handlers are only executed in the main thread.
2237
    if (_PyOS_IsMainThread()) {
2238
        HANDLE sigint_event = _PyOS_SigintEvent();
2239
2240
        while (1) {
2241
            // Check for pending SIGINT signal before resetting the event
2242
            if (PyErr_CheckSignals()) {
2243
                goto error;
2244
            }
2245
            ResetEvent(sigint_event);
2246
2247
            HANDLE events[] = {timer, sigint_event};
2248
            DWORD rc;
2249
2250
            Py_BEGIN_ALLOW_THREADS
2251
            rc = WaitForMultipleObjects(Py_ARRAY_LENGTH(events), events,
2252
                                        // bWaitAll
2253
                                        FALSE,
2254
                                        // No wait timeout
2255
                                        INFINITE);
2256
            Py_END_ALLOW_THREADS
2257
2258
            if (rc == WAIT_FAILED) {
2259
                PyErr_SetFromWindowsErr(0);
2260
                goto error;
2261
            }
2262
2263
            if (rc == WAIT_OBJECT_0) {
2264
                // Timer signaled: we are done
2265
                break;
2266
            }
2267
2268
            assert(rc == (WAIT_OBJECT_0 + 1));
2269
            // The sleep was interrupted by SIGINT: restart sleeping
2270
        }
2271
    }
2272
    else {
2273
        DWORD rc;
2274
2275
        Py_BEGIN_ALLOW_THREADS
2276
        rc = WaitForSingleObject(timer, INFINITE);
2277
        Py_END_ALLOW_THREADS
2278
2279
        if (rc == WAIT_FAILED) {
2280
            PyErr_SetFromWindowsErr(0);
2281
            goto error;
2282
        }
2283
2284
        assert(rc == WAIT_OBJECT_0);
2285
        // Timer signaled: we are done
2286
    }
2287
2288
    CloseHandle(timer);
2289
    return 0;
2290
2291
error:
2292
    CloseHandle(timer);
2293
    return -1;
2294
#endif
2295
}