#include "Python.h"
#include "pycore_fileutils.h"
#include "pycore_moduleobject.h"
#include "pycore_namespace.h"
#include "pycore_runtime.h"
#include "pycore_time.h"
#include <time.h>
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if defined(HAVE_SYS_RESOURCE_H)
# include <sys/resource.h>
#endif
#ifdef QUICKWIN
# include <io.h>
#endif
#if defined(HAVE_PTHREAD_H)
# include <pthread.h>
#endif
#if defined(_AIX)
# include <sys/thread.h>
#endif
#if defined(__WATCOMC__) && !defined(__QNX__)
# include <i86.h>
#else
# ifdef MS_WINDOWS
# ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# endif
#endif
#ifdef _Py_MEMORY_SANITIZER
# include <sanitizer/msan_interface.h>
#endif
#ifdef _MSC_VER
#define _Py_timezone …
#define _Py_daylight …
#define _Py_tzname …
#else
#define _Py_timezone …
#define _Py_daylight …
#define _Py_tzname …
#endif
#if defined(__APPLE__ ) && defined(__has_builtin)
# if __has_builtin(__builtin_available)
#define HAVE_CLOCK_GETTIME_RUNTIME …
# endif
#endif
#ifndef HAVE_CLOCK_GETTIME_RUNTIME
#define HAVE_CLOCK_GETTIME_RUNTIME …
#endif
#define SEC_TO_NS …
static int pysleep(PyTime_t timeout);
time_module_state;
static inline time_module_state*
get_time_state(PyObject *module)
{ … }
static PyObject*
_PyFloat_FromPyTime(PyTime_t t)
{ … }
static PyObject *
time_time(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(time_doc,
"time() -> floating-point number\n\
\n\
Return the current time in seconds since the Epoch.\n\
Fractions of a second may be present if the system clock provides them.");
static PyObject *
time_time_ns(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(time_ns_doc,
"time_ns() -> int\n\
\n\
Return the current time in nanoseconds since the Epoch.");
#ifdef HAVE_CLOCK
#ifndef CLOCKS_PER_SEC
# ifdef CLK_TCK
#define CLOCKS_PER_SEC …
# else
#define CLOCKS_PER_SEC …
# endif
#endif
static int
py_clock(time_module_state *state, PyTime_t *tp, _Py_clock_info_t *info)
{ … }
#endif
#ifdef HAVE_CLOCK_GETTIME
#ifdef __APPLE__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
#endif
static int
time_clockid_converter(PyObject *obj, clockid_t *p)
{ … }
static PyObject *
time_clock_gettime_impl(PyObject *module, clockid_t clk_id)
{ … }
static PyObject *
time_clock_gettime_ns_impl(PyObject *module, clockid_t clk_id)
{ … }
#endif
#ifdef HAVE_CLOCK_SETTIME
static PyObject *
time_clock_settime(PyObject *self, PyObject *args)
{ … }
PyDoc_STRVAR(clock_settime_doc,
"clock_settime(clk_id, time)\n\
\n\
Set the time of the specified clock clk_id.");
static PyObject *
time_clock_settime_ns(PyObject *self, PyObject *args)
{ … }
PyDoc_STRVAR(clock_settime_ns_doc,
"clock_settime_ns(clk_id, time)\n\
\n\
Set the time of the specified clock clk_id with nanoseconds.");
#endif
#ifdef HAVE_CLOCK_GETRES
static PyObject *
time_clock_getres(PyObject *self, PyObject *args)
{ … }
PyDoc_STRVAR(clock_getres_doc,
"clock_getres(clk_id) -> floating-point number\n\
\n\
Return the resolution (precision) of the specified clock clk_id.");
#ifdef __APPLE__
#pragma clang diagnostic pop
#endif
#endif
#ifdef HAVE_PTHREAD_GETCPUCLOCKID
static PyObject *
time_pthread_getcpuclockid(PyObject *self, PyObject *args)
{ … }
PyDoc_STRVAR(pthread_getcpuclockid_doc,
"pthread_getcpuclockid(thread_id) -> int\n\
\n\
Return the clk_id of a thread's CPU time clock.");
#endif
static PyObject *
time_sleep(PyObject *self, PyObject *timeout_obj)
{ … }
PyDoc_STRVAR(sleep_doc,
"sleep(seconds)\n\
\n\
Delay execution for a given number of seconds. The argument may be\n\
a floating-point number for subsecond precision.");
static PyStructSequence_Field struct_time_type_fields[] = …;
static PyStructSequence_Desc struct_time_type_desc = …;
#if defined(MS_WINDOWS)
#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION …
#endif
static DWORD timer_flags = (DWORD)-1;
#endif
static PyObject *
tmtotuple(time_module_state *state, struct tm *p
#ifndef HAVE_STRUCT_TM_TM_ZONE
, const char *zone, time_t gmtoff
#endif
)
{ … }
static int
parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
{ … }
static PyObject *
time_gmtime(PyObject *module, PyObject *args)
{ … }
#ifndef HAVE_TIMEGM
static time_t
timegm(struct tm *p)
{
return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 +
(p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 -
((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400;
}
#endif
PyDoc_STRVAR(gmtime_doc,
"gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\
tm_sec, tm_wday, tm_yday, tm_isdst)\n\
\n\
Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
GMT). When 'seconds' is not passed in, convert the current time instead.\n\
\n\
If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
attributes only.");
static PyObject *
time_localtime(PyObject *module, PyObject *args)
{ … }
#if defined(__linux__) && !defined(__GLIBC__)
static const char *utc_string = NULL;
#endif
PyDoc_STRVAR(localtime_doc,
"localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
tm_sec,tm_wday,tm_yday,tm_isdst)\n\
\n\
Convert seconds since the Epoch to a time tuple expressing local time.\n\
When 'seconds' is not passed in, convert the current time instead.");
static int
gettmarg(time_module_state *state, PyObject *args,
struct tm *p, const char *format)
{ … }
static int
checktm(struct tm* buf)
{ … }
#define STRFTIME_FORMAT_CODES …
#ifdef HAVE_STRFTIME
#ifdef HAVE_WCSFTIME
#define time_char …
#define format_time …
#define time_strlen …
#else
#define time_char …
#define format_time …
#define time_strlen …
#endif
static PyObject *
time_strftime1(time_char **outbuf, size_t *bufsize,
time_char *format, size_t fmtlen,
struct tm *tm)
{ … }
static PyObject *
time_strftime(PyObject *module, PyObject *args)
{ … }
#undef time_char
#undef format_time
PyDoc_STRVAR(strftime_doc,
"strftime(format[, tuple]) -> string\n\
\n\
Convert a time tuple to a string according to a format specification.\n\
See the library reference manual for formatting codes. When the time tuple\n\
is not present, current time as returned by localtime() is used.\n\
\n" STRFTIME_FORMAT_CODES);
#endif
static PyObject *
time_strptime(PyObject *self, PyObject *args)
{ … }
PyDoc_STRVAR(strptime_doc,
"strptime(string, format) -> struct_time\n\
\n\
Parse a string to a time tuple according to a format specification.\n\
See the library reference manual for formatting codes (same as\n\
strftime()).\n\
\n" STRFTIME_FORMAT_CODES);
static PyObject *
_asctime(struct tm *timeptr)
{ … }
static PyObject *
time_asctime(PyObject *module, PyObject *args)
{ … }
PyDoc_STRVAR(asctime_doc,
"asctime([tuple]) -> string\n\
\n\
Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
When the time tuple is not present, current time as returned by localtime()\n\
is used.");
static PyObject *
time_ctime(PyObject *self, PyObject *args)
{ … }
PyDoc_STRVAR(ctime_doc,
"ctime(seconds) -> string\n\
\n\
Convert a time in seconds since the Epoch to a string in local time.\n\
This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
not present, current time as returned by localtime() is used.");
#ifdef HAVE_MKTIME
static PyObject *
time_mktime(PyObject *module, PyObject *tm_tuple)
{ … }
PyDoc_STRVAR(mktime_doc,
"mktime(tuple) -> floating-point number\n\
\n\
Convert a time tuple in local time to seconds since the Epoch.\n\
Note that mktime(gmtime(0)) will not generally return zero for most\n\
time zones; instead the returned value will either be equal to that\n\
of the timezone or altzone attributes on the time module.");
#endif
#ifdef HAVE_WORKING_TZSET
static int init_timezone(PyObject *module);
static PyObject *
time_tzset(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(tzset_doc,
"tzset()\n\
\n\
Initialize, or reinitialize, the local timezone to the value stored in\n\
os.environ['TZ']. The TZ environment variable should be specified in\n\
standard Unix timezone format as documented in the tzset man page\n\
(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
fall back to UTC. If the TZ environment variable is not set, the local\n\
timezone is set to the systems best guess of wallclock time.\n\
Changing the TZ environment variable without calling tzset *may* change\n\
the local timezone used by methods such as localtime, but this behaviour\n\
should not be relied on.");
#endif
static PyObject *
time_monotonic(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(monotonic_doc,
"monotonic() -> float\n\
\n\
Monotonic clock, cannot go backward.");
static PyObject *
time_monotonic_ns(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(monotonic_ns_doc,
"monotonic_ns() -> int\n\
\n\
Monotonic clock, cannot go backward, as nanoseconds.");
static PyObject *
time_perf_counter(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(perf_counter_doc,
"perf_counter() -> float\n\
\n\
Performance counter for benchmarking.");
static PyObject *
time_perf_counter_ns(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(perf_counter_ns_doc,
"perf_counter_ns() -> int\n\
\n\
Performance counter for benchmarking as nanoseconds.");
#if defined(HAVE_TIMES) && !defined(__wasi__)
static int
process_time_times(time_module_state *state, PyTime_t *tp,
_Py_clock_info_t *info)
{ … }
#endif
static int
py_process_time(time_module_state *state, PyTime_t *tp,
_Py_clock_info_t *info)
{ … }
static PyObject *
time_process_time(PyObject *module, PyObject *unused)
{ … }
PyDoc_STRVAR(process_time_doc,
"process_time() -> float\n\
\n\
Process time for profiling: sum of the kernel and user-space CPU time.");
static PyObject *
time_process_time_ns(PyObject *module, PyObject *unused)
{ … }
PyDoc_STRVAR(process_time_ns_doc,
"process_time() -> int\n\
\n\
Process time for profiling as nanoseconds:\n\
sum of the kernel and user-space CPU time.");
#if defined(MS_WINDOWS)
#define HAVE_THREAD_TIME
static int
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
{
HANDLE thread;
FILETIME creation_time, exit_time, kernel_time, user_time;
ULARGE_INTEGER large;
PyTime_t ktime, utime;
BOOL ok;
thread = GetCurrentThread();
ok = GetThreadTimes(thread, &creation_time, &exit_time,
&kernel_time, &user_time);
if (!ok) {
PyErr_SetFromWindowsErr(0);
return -1;
}
if (info) {
info->implementation = "GetThreadTimes()";
info->resolution = 1e-7;
info->monotonic = 1;
info->adjustable = 0;
}
large.u.LowPart = kernel_time.dwLowDateTime;
large.u.HighPart = kernel_time.dwHighDateTime;
ktime = large.QuadPart;
large.u.LowPart = user_time.dwLowDateTime;
large.u.HighPart = user_time.dwHighDateTime;
utime = large.QuadPart;
*tp = (ktime + utime) * 100;
return 0;
}
#elif defined(_AIX)
#define HAVE_THREAD_TIME
static int
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
{
thread_cputime_t tc;
if (thread_cputime(-1, &tc) != 0) {
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
if (info) {
info->implementation = "thread_cputime()";
info->monotonic = 1;
info->adjustable = 0;
info->resolution = 1e-9;
}
*tp = (tc.stime + tc.utime);
return 0;
}
#elif defined(__sun) && defined(__SVR4)
#define HAVE_THREAD_TIME
static int
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
{
if (info) {
info->implementation = "gethrvtime()";
info->resolution = 1e-9;
info->monotonic = 1;
info->adjustable = 0;
}
*tp = gethrvtime();
return 0;
}
#elif defined(HAVE_CLOCK_GETTIME) && \
defined(CLOCK_THREAD_CPUTIME_ID) && \
!defined(__EMSCRIPTEN__) && !defined(__wasi__) && \
!defined(__NetBSD__)
#define HAVE_THREAD_TIME
#if defined(__APPLE__) && _Py__has_attribute(availability)
static int
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
__attribute__((availability(macos, introduced=10.12)))
__attribute__((availability(ios, introduced=10.0)))
__attribute__((availability(tvos, introduced=10.0)))
__attribute__((availability(watchos, introduced=3.0)));
#endif
static int
_PyTime_GetThreadTimeWithInfo(PyTime_t *tp, _Py_clock_info_t *info)
{ … }
#endif
#ifdef HAVE_THREAD_TIME
#ifdef __APPLE__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
#endif
static PyObject *
time_thread_time(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(thread_time_doc,
"thread_time() -> float\n\
\n\
Thread time for profiling: sum of the kernel and user-space CPU time.");
static PyObject *
time_thread_time_ns(PyObject *self, PyObject *unused)
{ … }
PyDoc_STRVAR(thread_time_ns_doc,
"thread_time() -> int\n\
\n\
Thread time for profiling as nanoseconds:\n\
sum of the kernel and user-space CPU time.");
#ifdef __APPLE__
#pragma clang diagnostic pop
#endif
#endif
static PyObject *
time_get_clock_info(PyObject *module, PyObject *args)
{ … }
PyDoc_STRVAR(get_clock_info_doc,
"get_clock_info(name: str) -> dict\n\
\n\
Get information of the specified clock.");
#ifndef HAVE_DECL_TZNAME
static void
get_zone(char *zone, int n, struct tm *p)
{ … }
static time_t
get_gmtoff(time_t t, struct tm *p)
{ … }
#endif
static int
init_timezone(PyObject *m)
{ … }
#include "clinic/timemodule.c.h"
static PyMethodDef time_methods[] = …;
PyDoc_STRVAR(module_doc,
"This module provides various functions to manipulate time values.\n\
\n\
There are two standard representations of time. One is the number\n\
of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\
or a floating-point number (to represent fractions of seconds).\n\
The epoch is the point where the time starts, the return value of time.gmtime(0).\n\
It is January 1, 1970, 00:00:00 (UTC) on all platforms.\n\
\n\
The other representation is a tuple of 9 integers giving local time.\n\
The tuple items are:\n\
year (including century, e.g. 1998)\n\
month (1-12)\n\
day (1-31)\n\
hours (0-23)\n\
minutes (0-59)\n\
seconds (0-59)\n\
weekday (0-6, Monday is 0)\n\
Julian day (day in the year, 1-366)\n\
DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
If the DST flag is 0, the time is given in the regular time zone;\n\
if it is 1, the time is given in the DST time zone;\n\
if it is -1, mktime() should guess based on the date and time.\n");
static int
time_exec(PyObject *module)
{ … }
static int
time_module_traverse(PyObject *module, visitproc visit, void *arg)
{ … }
static int
time_module_clear(PyObject *module)
{ … }
static void
time_module_free(void *module)
{ … }
static struct PyModuleDef_Slot time_slots[] = …;
static struct PyModuleDef timemodule = …;
PyMODINIT_FUNC
PyInit_time(void)
{ … }
static int
pysleep(PyTime_t timeout)
{ … }