17db96d56Sopenharmony_ci/* Time module */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci#include "Python.h" 47db96d56Sopenharmony_ci#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH 57db96d56Sopenharmony_ci#include "pycore_moduleobject.h" // _PyModule_GetState() 67db96d56Sopenharmony_ci#include "pycore_namespace.h" // _PyNamespace_New() 77db96d56Sopenharmony_ci#include "pycore_runtime.h" // _Py_ID() 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci#include <ctype.h> 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci#ifdef HAVE_SYS_TIMES_H 127db96d56Sopenharmony_ci# include <sys/times.h> 137db96d56Sopenharmony_ci#endif 147db96d56Sopenharmony_ci#ifdef HAVE_SYS_TYPES_H 157db96d56Sopenharmony_ci# include <sys/types.h> 167db96d56Sopenharmony_ci#endif 177db96d56Sopenharmony_ci#if defined(HAVE_SYS_RESOURCE_H) 187db96d56Sopenharmony_ci# include <sys/resource.h> 197db96d56Sopenharmony_ci#endif 207db96d56Sopenharmony_ci#ifdef QUICKWIN 217db96d56Sopenharmony_ci# include <io.h> 227db96d56Sopenharmony_ci#endif 237db96d56Sopenharmony_ci#if defined(HAVE_PTHREAD_H) 247db96d56Sopenharmony_ci# include <pthread.h> 257db96d56Sopenharmony_ci#endif 267db96d56Sopenharmony_ci#if defined(_AIX) 277db96d56Sopenharmony_ci# include <sys/thread.h> 287db96d56Sopenharmony_ci#endif 297db96d56Sopenharmony_ci#if defined(__WATCOMC__) && !defined(__QNX__) 307db96d56Sopenharmony_ci# include <i86.h> 317db96d56Sopenharmony_ci#else 327db96d56Sopenharmony_ci# ifdef MS_WINDOWS 337db96d56Sopenharmony_ci# define WIN32_LEAN_AND_MEAN 347db96d56Sopenharmony_ci# include <windows.h> 357db96d56Sopenharmony_ci# endif /* MS_WINDOWS */ 367db96d56Sopenharmony_ci#endif /* !__WATCOMC__ || __QNX__ */ 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ci#ifdef _Py_MEMORY_SANITIZER 397db96d56Sopenharmony_ci# include <sanitizer/msan_interface.h> 407db96d56Sopenharmony_ci#endif 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci#ifdef _MSC_VER 437db96d56Sopenharmony_ci# define _Py_timezone _timezone 447db96d56Sopenharmony_ci# define _Py_daylight _daylight 457db96d56Sopenharmony_ci# define _Py_tzname _tzname 467db96d56Sopenharmony_ci#else 477db96d56Sopenharmony_ci# define _Py_timezone timezone 487db96d56Sopenharmony_ci# define _Py_daylight daylight 497db96d56Sopenharmony_ci# define _Py_tzname tzname 507db96d56Sopenharmony_ci#endif 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci#if defined(__APPLE__ ) && defined(__has_builtin) 537db96d56Sopenharmony_ci# if __has_builtin(__builtin_available) 547db96d56Sopenharmony_ci# define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) 557db96d56Sopenharmony_ci# endif 567db96d56Sopenharmony_ci#endif 577db96d56Sopenharmony_ci#ifndef HAVE_CLOCK_GETTIME_RUNTIME 587db96d56Sopenharmony_ci# define HAVE_CLOCK_GETTIME_RUNTIME 1 597db96d56Sopenharmony_ci#endif 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci#define SEC_TO_NS (1000 * 1000 * 1000) 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci/* Forward declarations */ 667db96d56Sopenharmony_cistatic int pysleep(_PyTime_t timeout); 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_citypedef struct { 707db96d56Sopenharmony_ci PyTypeObject *struct_time_type; 717db96d56Sopenharmony_ci} time_module_state; 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_cistatic inline time_module_state* 747db96d56Sopenharmony_ciget_time_state(PyObject *module) 757db96d56Sopenharmony_ci{ 767db96d56Sopenharmony_ci void *state = _PyModule_GetState(module); 777db96d56Sopenharmony_ci assert(state != NULL); 787db96d56Sopenharmony_ci return (time_module_state *)state; 797db96d56Sopenharmony_ci} 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_cistatic PyObject* 837db96d56Sopenharmony_ci_PyFloat_FromPyTime(_PyTime_t t) 847db96d56Sopenharmony_ci{ 857db96d56Sopenharmony_ci double d = _PyTime_AsSecondsDouble(t); 867db96d56Sopenharmony_ci return PyFloat_FromDouble(d); 877db96d56Sopenharmony_ci} 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_cistatic int 917db96d56Sopenharmony_ciget_system_time(_PyTime_t *t) 927db96d56Sopenharmony_ci{ 937db96d56Sopenharmony_ci // Avoid _PyTime_GetSystemClock() which silently ignores errors. 947db96d56Sopenharmony_ci return _PyTime_GetSystemClockWithInfo(t, NULL); 957db96d56Sopenharmony_ci} 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_cistatic PyObject * 997db96d56Sopenharmony_citime_time(PyObject *self, PyObject *unused) 1007db96d56Sopenharmony_ci{ 1017db96d56Sopenharmony_ci _PyTime_t t; 1027db96d56Sopenharmony_ci if (get_system_time(&t) < 0) { 1037db96d56Sopenharmony_ci return NULL; 1047db96d56Sopenharmony_ci } 1057db96d56Sopenharmony_ci return _PyFloat_FromPyTime(t); 1067db96d56Sopenharmony_ci} 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ciPyDoc_STRVAR(time_doc, 1107db96d56Sopenharmony_ci"time() -> floating point number\n\ 1117db96d56Sopenharmony_ci\n\ 1127db96d56Sopenharmony_ciReturn the current time in seconds since the Epoch.\n\ 1137db96d56Sopenharmony_ciFractions of a second may be present if the system clock provides them."); 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_cistatic PyObject * 1167db96d56Sopenharmony_citime_time_ns(PyObject *self, PyObject *unused) 1177db96d56Sopenharmony_ci{ 1187db96d56Sopenharmony_ci _PyTime_t t; 1197db96d56Sopenharmony_ci if (get_system_time(&t) < 0) { 1207db96d56Sopenharmony_ci return NULL; 1217db96d56Sopenharmony_ci } 1227db96d56Sopenharmony_ci return _PyTime_AsNanosecondsObject(t); 1237db96d56Sopenharmony_ci} 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ciPyDoc_STRVAR(time_ns_doc, 1267db96d56Sopenharmony_ci"time_ns() -> int\n\ 1277db96d56Sopenharmony_ci\n\ 1287db96d56Sopenharmony_ciReturn the current time in nanoseconds since the Epoch."); 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci#if defined(HAVE_CLOCK) 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_ci#ifndef CLOCKS_PER_SEC 1337db96d56Sopenharmony_ci# ifdef CLK_TCK 1347db96d56Sopenharmony_ci# define CLOCKS_PER_SEC CLK_TCK 1357db96d56Sopenharmony_ci# else 1367db96d56Sopenharmony_ci# define CLOCKS_PER_SEC 1000000 1377db96d56Sopenharmony_ci# endif 1387db96d56Sopenharmony_ci#endif 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_cistatic int 1417db96d56Sopenharmony_ci_PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) 1427db96d56Sopenharmony_ci{ 1437db96d56Sopenharmony_ci static int initialized = 0; 1447db96d56Sopenharmony_ci 1457db96d56Sopenharmony_ci if (!initialized) { 1467db96d56Sopenharmony_ci initialized = 1; 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci /* Make sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC) 1497db96d56Sopenharmony_ci above cannot overflow */ 1507db96d56Sopenharmony_ci if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) { 1517db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 1527db96d56Sopenharmony_ci "CLOCKS_PER_SEC is too large"); 1537db96d56Sopenharmony_ci return -1; 1547db96d56Sopenharmony_ci } 1557db96d56Sopenharmony_ci } 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci if (info) { 1587db96d56Sopenharmony_ci info->implementation = "clock()"; 1597db96d56Sopenharmony_ci info->resolution = 1.0 / (double)CLOCKS_PER_SEC; 1607db96d56Sopenharmony_ci info->monotonic = 1; 1617db96d56Sopenharmony_ci info->adjustable = 0; 1627db96d56Sopenharmony_ci } 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci clock_t ticks = clock(); 1657db96d56Sopenharmony_ci if (ticks == (clock_t)-1) { 1667db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, 1677db96d56Sopenharmony_ci "the processor time used is not available " 1687db96d56Sopenharmony_ci "or its value cannot be represented"); 1697db96d56Sopenharmony_ci return -1; 1707db96d56Sopenharmony_ci } 1717db96d56Sopenharmony_ci _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC); 1727db96d56Sopenharmony_ci *tp = _PyTime_FromNanoseconds(ns); 1737db96d56Sopenharmony_ci return 0; 1747db96d56Sopenharmony_ci} 1757db96d56Sopenharmony_ci#endif /* HAVE_CLOCK */ 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_GETTIME 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci#ifdef __APPLE__ 1817db96d56Sopenharmony_ci/* 1827db96d56Sopenharmony_ci * The clock_* functions will be removed from the module 1837db96d56Sopenharmony_ci * dict entirely when the C API is not available. 1847db96d56Sopenharmony_ci */ 1857db96d56Sopenharmony_ci#pragma clang diagnostic push 1867db96d56Sopenharmony_ci#pragma clang diagnostic ignored "-Wunguarded-availability" 1877db96d56Sopenharmony_ci#endif 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_cistatic PyObject * 1907db96d56Sopenharmony_citime_clock_gettime(PyObject *self, PyObject *args) 1917db96d56Sopenharmony_ci{ 1927db96d56Sopenharmony_ci int ret; 1937db96d56Sopenharmony_ci struct timespec tp; 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ci#if defined(_AIX) && (SIZEOF_LONG == 8) 1967db96d56Sopenharmony_ci long clk_id; 1977db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) { 1987db96d56Sopenharmony_ci#else 1997db96d56Sopenharmony_ci int clk_id; 2007db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { 2017db96d56Sopenharmony_ci#endif 2027db96d56Sopenharmony_ci return NULL; 2037db96d56Sopenharmony_ci } 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci ret = clock_gettime((clockid_t)clk_id, &tp); 2067db96d56Sopenharmony_ci if (ret != 0) { 2077db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 2087db96d56Sopenharmony_ci return NULL; 2097db96d56Sopenharmony_ci } 2107db96d56Sopenharmony_ci return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); 2117db96d56Sopenharmony_ci} 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ciPyDoc_STRVAR(clock_gettime_doc, 2147db96d56Sopenharmony_ci"clock_gettime(clk_id) -> float\n\ 2157db96d56Sopenharmony_ci\n\ 2167db96d56Sopenharmony_ciReturn the time of the specified clock clk_id."); 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_cistatic PyObject * 2197db96d56Sopenharmony_citime_clock_gettime_ns(PyObject *self, PyObject *args) 2207db96d56Sopenharmony_ci{ 2217db96d56Sopenharmony_ci int ret; 2227db96d56Sopenharmony_ci int clk_id; 2237db96d56Sopenharmony_ci struct timespec ts; 2247db96d56Sopenharmony_ci _PyTime_t t; 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { 2277db96d56Sopenharmony_ci return NULL; 2287db96d56Sopenharmony_ci } 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci ret = clock_gettime((clockid_t)clk_id, &ts); 2317db96d56Sopenharmony_ci if (ret != 0) { 2327db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 2337db96d56Sopenharmony_ci return NULL; 2347db96d56Sopenharmony_ci } 2357db96d56Sopenharmony_ci if (_PyTime_FromTimespec(&t, &ts) < 0) { 2367db96d56Sopenharmony_ci return NULL; 2377db96d56Sopenharmony_ci } 2387db96d56Sopenharmony_ci return _PyTime_AsNanosecondsObject(t); 2397db96d56Sopenharmony_ci} 2407db96d56Sopenharmony_ci 2417db96d56Sopenharmony_ciPyDoc_STRVAR(clock_gettime_ns_doc, 2427db96d56Sopenharmony_ci"clock_gettime_ns(clk_id) -> int\n\ 2437db96d56Sopenharmony_ci\n\ 2447db96d56Sopenharmony_ciReturn the time of the specified clock clk_id as nanoseconds."); 2457db96d56Sopenharmony_ci#endif /* HAVE_CLOCK_GETTIME */ 2467db96d56Sopenharmony_ci 2477db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_SETTIME 2487db96d56Sopenharmony_cistatic PyObject * 2497db96d56Sopenharmony_citime_clock_settime(PyObject *self, PyObject *args) 2507db96d56Sopenharmony_ci{ 2517db96d56Sopenharmony_ci int clk_id; 2527db96d56Sopenharmony_ci PyObject *obj; 2537db96d56Sopenharmony_ci _PyTime_t t; 2547db96d56Sopenharmony_ci struct timespec tp; 2557db96d56Sopenharmony_ci int ret; 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) 2587db96d56Sopenharmony_ci return NULL; 2597db96d56Sopenharmony_ci 2607db96d56Sopenharmony_ci if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0) 2617db96d56Sopenharmony_ci return NULL; 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci if (_PyTime_AsTimespec(t, &tp) == -1) 2647db96d56Sopenharmony_ci return NULL; 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci ret = clock_settime((clockid_t)clk_id, &tp); 2677db96d56Sopenharmony_ci if (ret != 0) { 2687db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 2697db96d56Sopenharmony_ci return NULL; 2707db96d56Sopenharmony_ci } 2717db96d56Sopenharmony_ci Py_RETURN_NONE; 2727db96d56Sopenharmony_ci} 2737db96d56Sopenharmony_ci 2747db96d56Sopenharmony_ciPyDoc_STRVAR(clock_settime_doc, 2757db96d56Sopenharmony_ci"clock_settime(clk_id, time)\n\ 2767db96d56Sopenharmony_ci\n\ 2777db96d56Sopenharmony_ciSet the time of the specified clock clk_id."); 2787db96d56Sopenharmony_ci 2797db96d56Sopenharmony_cistatic PyObject * 2807db96d56Sopenharmony_citime_clock_settime_ns(PyObject *self, PyObject *args) 2817db96d56Sopenharmony_ci{ 2827db96d56Sopenharmony_ci int clk_id; 2837db96d56Sopenharmony_ci PyObject *obj; 2847db96d56Sopenharmony_ci _PyTime_t t; 2857db96d56Sopenharmony_ci struct timespec ts; 2867db96d56Sopenharmony_ci int ret; 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) { 2897db96d56Sopenharmony_ci return NULL; 2907db96d56Sopenharmony_ci } 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { 2937db96d56Sopenharmony_ci return NULL; 2947db96d56Sopenharmony_ci } 2957db96d56Sopenharmony_ci if (_PyTime_AsTimespec(t, &ts) == -1) { 2967db96d56Sopenharmony_ci return NULL; 2977db96d56Sopenharmony_ci } 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci ret = clock_settime((clockid_t)clk_id, &ts); 3007db96d56Sopenharmony_ci if (ret != 0) { 3017db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 3027db96d56Sopenharmony_ci return NULL; 3037db96d56Sopenharmony_ci } 3047db96d56Sopenharmony_ci Py_RETURN_NONE; 3057db96d56Sopenharmony_ci} 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ciPyDoc_STRVAR(clock_settime_ns_doc, 3087db96d56Sopenharmony_ci"clock_settime_ns(clk_id, time)\n\ 3097db96d56Sopenharmony_ci\n\ 3107db96d56Sopenharmony_ciSet the time of the specified clock clk_id with nanoseconds."); 3117db96d56Sopenharmony_ci#endif /* HAVE_CLOCK_SETTIME */ 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_GETRES 3147db96d56Sopenharmony_cistatic PyObject * 3157db96d56Sopenharmony_citime_clock_getres(PyObject *self, PyObject *args) 3167db96d56Sopenharmony_ci{ 3177db96d56Sopenharmony_ci int ret; 3187db96d56Sopenharmony_ci int clk_id; 3197db96d56Sopenharmony_ci struct timespec tp; 3207db96d56Sopenharmony_ci 3217db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id)) 3227db96d56Sopenharmony_ci return NULL; 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_ci ret = clock_getres((clockid_t)clk_id, &tp); 3257db96d56Sopenharmony_ci if (ret != 0) { 3267db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 3277db96d56Sopenharmony_ci return NULL; 3287db96d56Sopenharmony_ci } 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); 3317db96d56Sopenharmony_ci} 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ciPyDoc_STRVAR(clock_getres_doc, 3347db96d56Sopenharmony_ci"clock_getres(clk_id) -> floating point number\n\ 3357db96d56Sopenharmony_ci\n\ 3367db96d56Sopenharmony_ciReturn the resolution (precision) of the specified clock clk_id."); 3377db96d56Sopenharmony_ci 3387db96d56Sopenharmony_ci#ifdef __APPLE__ 3397db96d56Sopenharmony_ci#pragma clang diagnostic pop 3407db96d56Sopenharmony_ci#endif 3417db96d56Sopenharmony_ci 3427db96d56Sopenharmony_ci#endif /* HAVE_CLOCK_GETRES */ 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci#ifdef HAVE_PTHREAD_GETCPUCLOCKID 3457db96d56Sopenharmony_cistatic PyObject * 3467db96d56Sopenharmony_citime_pthread_getcpuclockid(PyObject *self, PyObject *args) 3477db96d56Sopenharmony_ci{ 3487db96d56Sopenharmony_ci unsigned long thread_id; 3497db96d56Sopenharmony_ci int err; 3507db96d56Sopenharmony_ci clockid_t clk_id; 3517db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) { 3527db96d56Sopenharmony_ci return NULL; 3537db96d56Sopenharmony_ci } 3547db96d56Sopenharmony_ci err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id); 3557db96d56Sopenharmony_ci if (err) { 3567db96d56Sopenharmony_ci errno = err; 3577db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 3587db96d56Sopenharmony_ci return NULL; 3597db96d56Sopenharmony_ci } 3607db96d56Sopenharmony_ci#ifdef _Py_MEMORY_SANITIZER 3617db96d56Sopenharmony_ci __msan_unpoison(&clk_id, sizeof(clk_id)); 3627db96d56Sopenharmony_ci#endif 3637db96d56Sopenharmony_ci return PyLong_FromLong(clk_id); 3647db96d56Sopenharmony_ci} 3657db96d56Sopenharmony_ci 3667db96d56Sopenharmony_ciPyDoc_STRVAR(pthread_getcpuclockid_doc, 3677db96d56Sopenharmony_ci"pthread_getcpuclockid(thread_id) -> int\n\ 3687db96d56Sopenharmony_ci\n\ 3697db96d56Sopenharmony_ciReturn the clk_id of a thread's CPU time clock."); 3707db96d56Sopenharmony_ci#endif /* HAVE_PTHREAD_GETCPUCLOCKID */ 3717db96d56Sopenharmony_ci 3727db96d56Sopenharmony_cistatic PyObject * 3737db96d56Sopenharmony_citime_sleep(PyObject *self, PyObject *timeout_obj) 3747db96d56Sopenharmony_ci{ 3757db96d56Sopenharmony_ci _PyTime_t timeout; 3767db96d56Sopenharmony_ci if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) 3777db96d56Sopenharmony_ci return NULL; 3787db96d56Sopenharmony_ci if (timeout < 0) { 3797db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 3807db96d56Sopenharmony_ci "sleep length must be non-negative"); 3817db96d56Sopenharmony_ci return NULL; 3827db96d56Sopenharmony_ci } 3837db96d56Sopenharmony_ci if (pysleep(timeout) != 0) { 3847db96d56Sopenharmony_ci return NULL; 3857db96d56Sopenharmony_ci } 3867db96d56Sopenharmony_ci Py_RETURN_NONE; 3877db96d56Sopenharmony_ci} 3887db96d56Sopenharmony_ci 3897db96d56Sopenharmony_ciPyDoc_STRVAR(sleep_doc, 3907db96d56Sopenharmony_ci"sleep(seconds)\n\ 3917db96d56Sopenharmony_ci\n\ 3927db96d56Sopenharmony_ciDelay execution for a given number of seconds. The argument may be\n\ 3937db96d56Sopenharmony_cia floating point number for subsecond precision."); 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_cistatic PyStructSequence_Field struct_time_type_fields[] = { 3967db96d56Sopenharmony_ci {"tm_year", "year, for example, 1993"}, 3977db96d56Sopenharmony_ci {"tm_mon", "month of year, range [1, 12]"}, 3987db96d56Sopenharmony_ci {"tm_mday", "day of month, range [1, 31]"}, 3997db96d56Sopenharmony_ci {"tm_hour", "hours, range [0, 23]"}, 4007db96d56Sopenharmony_ci {"tm_min", "minutes, range [0, 59]"}, 4017db96d56Sopenharmony_ci {"tm_sec", "seconds, range [0, 61])"}, 4027db96d56Sopenharmony_ci {"tm_wday", "day of week, range [0, 6], Monday is 0"}, 4037db96d56Sopenharmony_ci {"tm_yday", "day of year, range [1, 366]"}, 4047db96d56Sopenharmony_ci {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, 4057db96d56Sopenharmony_ci {"tm_zone", "abbreviation of timezone name"}, 4067db96d56Sopenharmony_ci {"tm_gmtoff", "offset from UTC in seconds"}, 4077db96d56Sopenharmony_ci {0} 4087db96d56Sopenharmony_ci}; 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_cistatic PyStructSequence_Desc struct_time_type_desc = { 4117db96d56Sopenharmony_ci "time.struct_time", 4127db96d56Sopenharmony_ci "The time value as returned by gmtime(), localtime(), and strptime(), and\n" 4137db96d56Sopenharmony_ci " accepted by asctime(), mktime() and strftime(). May be considered as a\n" 4147db96d56Sopenharmony_ci " sequence of 9 integers.\n\n" 4157db96d56Sopenharmony_ci " Note that several fields' values are not the same as those defined by\n" 4167db96d56Sopenharmony_ci " the C language standard for struct tm. For example, the value of the\n" 4177db96d56Sopenharmony_ci " field tm_year is the actual year, not year - 1900. See individual\n" 4187db96d56Sopenharmony_ci " fields' descriptions for details.", 4197db96d56Sopenharmony_ci struct_time_type_fields, 4207db96d56Sopenharmony_ci 9, 4217db96d56Sopenharmony_ci}; 4227db96d56Sopenharmony_ci 4237db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 4247db96d56Sopenharmony_ci#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 4257db96d56Sopenharmony_ci #define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 4267db96d56Sopenharmony_ci#endif 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_cistatic DWORD timer_flags = (DWORD)-1; 4297db96d56Sopenharmony_ci#endif 4307db96d56Sopenharmony_ci 4317db96d56Sopenharmony_cistatic PyObject * 4327db96d56Sopenharmony_citmtotuple(time_module_state *state, struct tm *p 4337db96d56Sopenharmony_ci#ifndef HAVE_STRUCT_TM_TM_ZONE 4347db96d56Sopenharmony_ci , const char *zone, time_t gmtoff 4357db96d56Sopenharmony_ci#endif 4367db96d56Sopenharmony_ci) 4377db96d56Sopenharmony_ci{ 4387db96d56Sopenharmony_ci PyObject *v = PyStructSequence_New(state->struct_time_type); 4397db96d56Sopenharmony_ci if (v == NULL) 4407db96d56Sopenharmony_ci return NULL; 4417db96d56Sopenharmony_ci 4427db96d56Sopenharmony_ci#define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) 4437db96d56Sopenharmony_ci 4447db96d56Sopenharmony_ci SET(0, p->tm_year + 1900); 4457db96d56Sopenharmony_ci SET(1, p->tm_mon + 1); /* Want January == 1 */ 4467db96d56Sopenharmony_ci SET(2, p->tm_mday); 4477db96d56Sopenharmony_ci SET(3, p->tm_hour); 4487db96d56Sopenharmony_ci SET(4, p->tm_min); 4497db96d56Sopenharmony_ci SET(5, p->tm_sec); 4507db96d56Sopenharmony_ci SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */ 4517db96d56Sopenharmony_ci SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */ 4527db96d56Sopenharmony_ci SET(8, p->tm_isdst); 4537db96d56Sopenharmony_ci#ifdef HAVE_STRUCT_TM_TM_ZONE 4547db96d56Sopenharmony_ci PyStructSequence_SET_ITEM(v, 9, 4557db96d56Sopenharmony_ci PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape")); 4567db96d56Sopenharmony_ci SET(10, p->tm_gmtoff); 4577db96d56Sopenharmony_ci#else 4587db96d56Sopenharmony_ci PyStructSequence_SET_ITEM(v, 9, 4597db96d56Sopenharmony_ci PyUnicode_DecodeLocale(zone, "surrogateescape")); 4607db96d56Sopenharmony_ci PyStructSequence_SET_ITEM(v, 10, _PyLong_FromTime_t(gmtoff)); 4617db96d56Sopenharmony_ci#endif /* HAVE_STRUCT_TM_TM_ZONE */ 4627db96d56Sopenharmony_ci#undef SET 4637db96d56Sopenharmony_ci if (PyErr_Occurred()) { 4647db96d56Sopenharmony_ci Py_XDECREF(v); 4657db96d56Sopenharmony_ci return NULL; 4667db96d56Sopenharmony_ci } 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci return v; 4697db96d56Sopenharmony_ci} 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci/* Parse arg tuple that can contain an optional float-or-None value; 4727db96d56Sopenharmony_ci format needs to be "|O:name". 4737db96d56Sopenharmony_ci Returns non-zero on success (parallels PyArg_ParseTuple). 4747db96d56Sopenharmony_ci*/ 4757db96d56Sopenharmony_cistatic int 4767db96d56Sopenharmony_ciparse_time_t_args(PyObject *args, const char *format, time_t *pwhen) 4777db96d56Sopenharmony_ci{ 4787db96d56Sopenharmony_ci PyObject *ot = NULL; 4797db96d56Sopenharmony_ci time_t whent; 4807db96d56Sopenharmony_ci 4817db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, format, &ot)) 4827db96d56Sopenharmony_ci return 0; 4837db96d56Sopenharmony_ci if (ot == NULL || ot == Py_None) { 4847db96d56Sopenharmony_ci whent = time(NULL); 4857db96d56Sopenharmony_ci } 4867db96d56Sopenharmony_ci else { 4877db96d56Sopenharmony_ci if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1) 4887db96d56Sopenharmony_ci return 0; 4897db96d56Sopenharmony_ci } 4907db96d56Sopenharmony_ci *pwhen = whent; 4917db96d56Sopenharmony_ci return 1; 4927db96d56Sopenharmony_ci} 4937db96d56Sopenharmony_ci 4947db96d56Sopenharmony_cistatic PyObject * 4957db96d56Sopenharmony_citime_gmtime(PyObject *module, PyObject *args) 4967db96d56Sopenharmony_ci{ 4977db96d56Sopenharmony_ci time_t when; 4987db96d56Sopenharmony_ci struct tm buf; 4997db96d56Sopenharmony_ci 5007db96d56Sopenharmony_ci if (!parse_time_t_args(args, "|O:gmtime", &when)) 5017db96d56Sopenharmony_ci return NULL; 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_ci errno = 0; 5047db96d56Sopenharmony_ci if (_PyTime_gmtime(when, &buf) != 0) 5057db96d56Sopenharmony_ci return NULL; 5067db96d56Sopenharmony_ci 5077db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 5087db96d56Sopenharmony_ci#ifdef HAVE_STRUCT_TM_TM_ZONE 5097db96d56Sopenharmony_ci return tmtotuple(state, &buf); 5107db96d56Sopenharmony_ci#else 5117db96d56Sopenharmony_ci return tmtotuple(state, &buf, "UTC", 0); 5127db96d56Sopenharmony_ci#endif 5137db96d56Sopenharmony_ci} 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci#ifndef HAVE_TIMEGM 5167db96d56Sopenharmony_cistatic time_t 5177db96d56Sopenharmony_citimegm(struct tm *p) 5187db96d56Sopenharmony_ci{ 5197db96d56Sopenharmony_ci /* XXX: the following implementation will not work for tm_year < 1970. 5207db96d56Sopenharmony_ci but it is likely that platforms that don't have timegm do not support 5217db96d56Sopenharmony_ci negative timestamps anyways. */ 5227db96d56Sopenharmony_ci return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 + 5237db96d56Sopenharmony_ci (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 - 5247db96d56Sopenharmony_ci ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400; 5257db96d56Sopenharmony_ci} 5267db96d56Sopenharmony_ci#endif 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_ciPyDoc_STRVAR(gmtime_doc, 5297db96d56Sopenharmony_ci"gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\ 5307db96d56Sopenharmony_ci tm_sec, tm_wday, tm_yday, tm_isdst)\n\ 5317db96d56Sopenharmony_ci\n\ 5327db96d56Sopenharmony_ciConvert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\ 5337db96d56Sopenharmony_ciGMT). When 'seconds' is not passed in, convert the current time instead.\n\ 5347db96d56Sopenharmony_ci\n\ 5357db96d56Sopenharmony_ciIf the platform supports the tm_gmtoff and tm_zone, they are available as\n\ 5367db96d56Sopenharmony_ciattributes only."); 5377db96d56Sopenharmony_ci 5387db96d56Sopenharmony_cistatic PyObject * 5397db96d56Sopenharmony_citime_localtime(PyObject *module, PyObject *args) 5407db96d56Sopenharmony_ci{ 5417db96d56Sopenharmony_ci time_t when; 5427db96d56Sopenharmony_ci struct tm buf; 5437db96d56Sopenharmony_ci 5447db96d56Sopenharmony_ci if (!parse_time_t_args(args, "|O:localtime", &when)) 5457db96d56Sopenharmony_ci return NULL; 5467db96d56Sopenharmony_ci if (_PyTime_localtime(when, &buf) != 0) 5477db96d56Sopenharmony_ci return NULL; 5487db96d56Sopenharmony_ci 5497db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 5507db96d56Sopenharmony_ci#ifdef HAVE_STRUCT_TM_TM_ZONE 5517db96d56Sopenharmony_ci return tmtotuple(state, &buf); 5527db96d56Sopenharmony_ci#else 5537db96d56Sopenharmony_ci { 5547db96d56Sopenharmony_ci struct tm local = buf; 5557db96d56Sopenharmony_ci char zone[100]; 5567db96d56Sopenharmony_ci time_t gmtoff; 5577db96d56Sopenharmony_ci strftime(zone, sizeof(zone), "%Z", &buf); 5587db96d56Sopenharmony_ci gmtoff = timegm(&buf) - when; 5597db96d56Sopenharmony_ci return tmtotuple(state, &local, zone, gmtoff); 5607db96d56Sopenharmony_ci } 5617db96d56Sopenharmony_ci#endif 5627db96d56Sopenharmony_ci} 5637db96d56Sopenharmony_ci 5647db96d56Sopenharmony_ci#if defined(__linux__) && !defined(__GLIBC__) 5657db96d56Sopenharmony_cistatic const char *utc_string = NULL; 5667db96d56Sopenharmony_ci#endif 5677db96d56Sopenharmony_ci 5687db96d56Sopenharmony_ciPyDoc_STRVAR(localtime_doc, 5697db96d56Sopenharmony_ci"localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\ 5707db96d56Sopenharmony_ci tm_sec,tm_wday,tm_yday,tm_isdst)\n\ 5717db96d56Sopenharmony_ci\n\ 5727db96d56Sopenharmony_ciConvert seconds since the Epoch to a time tuple expressing local time.\n\ 5737db96d56Sopenharmony_ciWhen 'seconds' is not passed in, convert the current time instead."); 5747db96d56Sopenharmony_ci 5757db96d56Sopenharmony_ci/* Convert 9-item tuple to tm structure. Return 1 on success, set 5767db96d56Sopenharmony_ci * an exception and return 0 on error. 5777db96d56Sopenharmony_ci */ 5787db96d56Sopenharmony_cistatic int 5797db96d56Sopenharmony_cigettmarg(time_module_state *state, PyObject *args, 5807db96d56Sopenharmony_ci struct tm *p, const char *format) 5817db96d56Sopenharmony_ci{ 5827db96d56Sopenharmony_ci int y; 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_ci memset((void *) p, '\0', sizeof(struct tm)); 5857db96d56Sopenharmony_ci 5867db96d56Sopenharmony_ci if (!PyTuple_Check(args)) { 5877db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 5887db96d56Sopenharmony_ci "Tuple or struct_time argument required"); 5897db96d56Sopenharmony_ci return 0; 5907db96d56Sopenharmony_ci } 5917db96d56Sopenharmony_ci 5927db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, format, 5937db96d56Sopenharmony_ci &y, &p->tm_mon, &p->tm_mday, 5947db96d56Sopenharmony_ci &p->tm_hour, &p->tm_min, &p->tm_sec, 5957db96d56Sopenharmony_ci &p->tm_wday, &p->tm_yday, &p->tm_isdst)) 5967db96d56Sopenharmony_ci return 0; 5977db96d56Sopenharmony_ci 5987db96d56Sopenharmony_ci if (y < INT_MIN + 1900) { 5997db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "year out of range"); 6007db96d56Sopenharmony_ci return 0; 6017db96d56Sopenharmony_ci } 6027db96d56Sopenharmony_ci 6037db96d56Sopenharmony_ci p->tm_year = y - 1900; 6047db96d56Sopenharmony_ci p->tm_mon--; 6057db96d56Sopenharmony_ci p->tm_wday = (p->tm_wday + 1) % 7; 6067db96d56Sopenharmony_ci p->tm_yday--; 6077db96d56Sopenharmony_ci#ifdef HAVE_STRUCT_TM_TM_ZONE 6087db96d56Sopenharmony_ci if (Py_IS_TYPE(args, state->struct_time_type)) { 6097db96d56Sopenharmony_ci PyObject *item; 6107db96d56Sopenharmony_ci item = PyStructSequence_GET_ITEM(args, 9); 6117db96d56Sopenharmony_ci if (item != Py_None) { 6127db96d56Sopenharmony_ci p->tm_zone = (char *)PyUnicode_AsUTF8(item); 6137db96d56Sopenharmony_ci if (p->tm_zone == NULL) { 6147db96d56Sopenharmony_ci return 0; 6157db96d56Sopenharmony_ci } 6167db96d56Sopenharmony_ci#if defined(__linux__) && !defined(__GLIBC__) 6177db96d56Sopenharmony_ci // Make an attempt to return the C library's own timezone strings to 6187db96d56Sopenharmony_ci // it. musl refuses to process a tm_zone field unless it produced 6197db96d56Sopenharmony_ci // it. See issue #34672. 6207db96d56Sopenharmony_ci if (utc_string && strcmp(p->tm_zone, utc_string) == 0) { 6217db96d56Sopenharmony_ci p->tm_zone = utc_string; 6227db96d56Sopenharmony_ci } 6237db96d56Sopenharmony_ci else if (tzname[0] && strcmp(p->tm_zone, tzname[0]) == 0) { 6247db96d56Sopenharmony_ci p->tm_zone = tzname[0]; 6257db96d56Sopenharmony_ci } 6267db96d56Sopenharmony_ci else if (tzname[1] && strcmp(p->tm_zone, tzname[1]) == 0) { 6277db96d56Sopenharmony_ci p->tm_zone = tzname[1]; 6287db96d56Sopenharmony_ci } 6297db96d56Sopenharmony_ci#endif 6307db96d56Sopenharmony_ci } 6317db96d56Sopenharmony_ci item = PyStructSequence_GET_ITEM(args, 10); 6327db96d56Sopenharmony_ci if (item != Py_None) { 6337db96d56Sopenharmony_ci p->tm_gmtoff = PyLong_AsLong(item); 6347db96d56Sopenharmony_ci if (PyErr_Occurred()) 6357db96d56Sopenharmony_ci return 0; 6367db96d56Sopenharmony_ci } 6377db96d56Sopenharmony_ci } 6387db96d56Sopenharmony_ci#endif /* HAVE_STRUCT_TM_TM_ZONE */ 6397db96d56Sopenharmony_ci return 1; 6407db96d56Sopenharmony_ci} 6417db96d56Sopenharmony_ci 6427db96d56Sopenharmony_ci/* Check values of the struct tm fields before it is passed to strftime() and 6437db96d56Sopenharmony_ci * asctime(). Return 1 if all values are valid, otherwise set an exception 6447db96d56Sopenharmony_ci * and returns 0. 6457db96d56Sopenharmony_ci */ 6467db96d56Sopenharmony_cistatic int 6477db96d56Sopenharmony_cichecktm(struct tm* buf) 6487db96d56Sopenharmony_ci{ 6497db96d56Sopenharmony_ci /* Checks added to make sure strftime() and asctime() does not crash Python by 6507db96d56Sopenharmony_ci indexing blindly into some array for a textual representation 6517db96d56Sopenharmony_ci by some bad index (fixes bug #897625 and #6608). 6527db96d56Sopenharmony_ci 6537db96d56Sopenharmony_ci Also support values of zero from Python code for arguments in which 6547db96d56Sopenharmony_ci that is out of range by forcing that value to the lowest value that 6557db96d56Sopenharmony_ci is valid (fixed bug #1520914). 6567db96d56Sopenharmony_ci 6577db96d56Sopenharmony_ci Valid ranges based on what is allowed in struct tm: 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_ci - tm_year: [0, max(int)] (1) 6607db96d56Sopenharmony_ci - tm_mon: [0, 11] (2) 6617db96d56Sopenharmony_ci - tm_mday: [1, 31] 6627db96d56Sopenharmony_ci - tm_hour: [0, 23] 6637db96d56Sopenharmony_ci - tm_min: [0, 59] 6647db96d56Sopenharmony_ci - tm_sec: [0, 60] 6657db96d56Sopenharmony_ci - tm_wday: [0, 6] (1) 6667db96d56Sopenharmony_ci - tm_yday: [0, 365] (2) 6677db96d56Sopenharmony_ci - tm_isdst: [-max(int), max(int)] 6687db96d56Sopenharmony_ci 6697db96d56Sopenharmony_ci (1) gettmarg() handles bounds-checking. 6707db96d56Sopenharmony_ci (2) Python's acceptable range is one greater than the range in C, 6717db96d56Sopenharmony_ci thus need to check against automatic decrement by gettmarg(). 6727db96d56Sopenharmony_ci */ 6737db96d56Sopenharmony_ci if (buf->tm_mon == -1) 6747db96d56Sopenharmony_ci buf->tm_mon = 0; 6757db96d56Sopenharmony_ci else if (buf->tm_mon < 0 || buf->tm_mon > 11) { 6767db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "month out of range"); 6777db96d56Sopenharmony_ci return 0; 6787db96d56Sopenharmony_ci } 6797db96d56Sopenharmony_ci if (buf->tm_mday == 0) 6807db96d56Sopenharmony_ci buf->tm_mday = 1; 6817db96d56Sopenharmony_ci else if (buf->tm_mday < 0 || buf->tm_mday > 31) { 6827db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "day of month out of range"); 6837db96d56Sopenharmony_ci return 0; 6847db96d56Sopenharmony_ci } 6857db96d56Sopenharmony_ci if (buf->tm_hour < 0 || buf->tm_hour > 23) { 6867db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "hour out of range"); 6877db96d56Sopenharmony_ci return 0; 6887db96d56Sopenharmony_ci } 6897db96d56Sopenharmony_ci if (buf->tm_min < 0 || buf->tm_min > 59) { 6907db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "minute out of range"); 6917db96d56Sopenharmony_ci return 0; 6927db96d56Sopenharmony_ci } 6937db96d56Sopenharmony_ci if (buf->tm_sec < 0 || buf->tm_sec > 61) { 6947db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "seconds out of range"); 6957db96d56Sopenharmony_ci return 0; 6967db96d56Sopenharmony_ci } 6977db96d56Sopenharmony_ci /* tm_wday does not need checking of its upper-bound since taking 6987db96d56Sopenharmony_ci ``% 7`` in gettmarg() automatically restricts the range. */ 6997db96d56Sopenharmony_ci if (buf->tm_wday < 0) { 7007db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "day of week out of range"); 7017db96d56Sopenharmony_ci return 0; 7027db96d56Sopenharmony_ci } 7037db96d56Sopenharmony_ci if (buf->tm_yday == -1) 7047db96d56Sopenharmony_ci buf->tm_yday = 0; 7057db96d56Sopenharmony_ci else if (buf->tm_yday < 0 || buf->tm_yday > 365) { 7067db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "day of year out of range"); 7077db96d56Sopenharmony_ci return 0; 7087db96d56Sopenharmony_ci } 7097db96d56Sopenharmony_ci return 1; 7107db96d56Sopenharmony_ci} 7117db96d56Sopenharmony_ci 7127db96d56Sopenharmony_ci#ifdef MS_WINDOWS 7137db96d56Sopenharmony_ci /* wcsftime() doesn't format correctly time zones, see issue #10653 */ 7147db96d56Sopenharmony_ci# undef HAVE_WCSFTIME 7157db96d56Sopenharmony_ci#endif 7167db96d56Sopenharmony_ci#define STRFTIME_FORMAT_CODES \ 7177db96d56Sopenharmony_ci"Commonly used format codes:\n\ 7187db96d56Sopenharmony_ci\n\ 7197db96d56Sopenharmony_ci%Y Year with century as a decimal number.\n\ 7207db96d56Sopenharmony_ci%m Month as a decimal number [01,12].\n\ 7217db96d56Sopenharmony_ci%d Day of the month as a decimal number [01,31].\n\ 7227db96d56Sopenharmony_ci%H Hour (24-hour clock) as a decimal number [00,23].\n\ 7237db96d56Sopenharmony_ci%M Minute as a decimal number [00,59].\n\ 7247db96d56Sopenharmony_ci%S Second as a decimal number [00,61].\n\ 7257db96d56Sopenharmony_ci%z Time zone offset from UTC.\n\ 7267db96d56Sopenharmony_ci%a Locale's abbreviated weekday name.\n\ 7277db96d56Sopenharmony_ci%A Locale's full weekday name.\n\ 7287db96d56Sopenharmony_ci%b Locale's abbreviated month name.\n\ 7297db96d56Sopenharmony_ci%B Locale's full month name.\n\ 7307db96d56Sopenharmony_ci%c Locale's appropriate date and time representation.\n\ 7317db96d56Sopenharmony_ci%I Hour (12-hour clock) as a decimal number [01,12].\n\ 7327db96d56Sopenharmony_ci%p Locale's equivalent of either AM or PM.\n\ 7337db96d56Sopenharmony_ci\n\ 7347db96d56Sopenharmony_ciOther codes may be available on your platform. See documentation for\n\ 7357db96d56Sopenharmony_cithe C library strftime function.\n" 7367db96d56Sopenharmony_ci 7377db96d56Sopenharmony_ci#ifdef HAVE_STRFTIME 7387db96d56Sopenharmony_ci#ifdef HAVE_WCSFTIME 7397db96d56Sopenharmony_ci#define time_char wchar_t 7407db96d56Sopenharmony_ci#define format_time wcsftime 7417db96d56Sopenharmony_ci#define time_strlen wcslen 7427db96d56Sopenharmony_ci#else 7437db96d56Sopenharmony_ci#define time_char char 7447db96d56Sopenharmony_ci#define format_time strftime 7457db96d56Sopenharmony_ci#define time_strlen strlen 7467db96d56Sopenharmony_ci#endif 7477db96d56Sopenharmony_ci 7487db96d56Sopenharmony_cistatic PyObject * 7497db96d56Sopenharmony_citime_strftime(PyObject *module, PyObject *args) 7507db96d56Sopenharmony_ci{ 7517db96d56Sopenharmony_ci PyObject *tup = NULL; 7527db96d56Sopenharmony_ci struct tm buf; 7537db96d56Sopenharmony_ci const time_char *fmt; 7547db96d56Sopenharmony_ci#ifdef HAVE_WCSFTIME 7557db96d56Sopenharmony_ci wchar_t *format; 7567db96d56Sopenharmony_ci#else 7577db96d56Sopenharmony_ci PyObject *format; 7587db96d56Sopenharmony_ci#endif 7597db96d56Sopenharmony_ci PyObject *format_arg; 7607db96d56Sopenharmony_ci size_t fmtlen, buflen; 7617db96d56Sopenharmony_ci time_char *outbuf = NULL; 7627db96d56Sopenharmony_ci size_t i; 7637db96d56Sopenharmony_ci PyObject *ret = NULL; 7647db96d56Sopenharmony_ci 7657db96d56Sopenharmony_ci memset((void *) &buf, '\0', sizeof(buf)); 7667db96d56Sopenharmony_ci 7677db96d56Sopenharmony_ci /* Will always expect a unicode string to be passed as format. 7687db96d56Sopenharmony_ci Given that there's no str type anymore in py3k this seems safe. 7697db96d56Sopenharmony_ci */ 7707db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup)) 7717db96d56Sopenharmony_ci return NULL; 7727db96d56Sopenharmony_ci 7737db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 7747db96d56Sopenharmony_ci if (tup == NULL) { 7757db96d56Sopenharmony_ci time_t tt = time(NULL); 7767db96d56Sopenharmony_ci if (_PyTime_localtime(tt, &buf) != 0) 7777db96d56Sopenharmony_ci return NULL; 7787db96d56Sopenharmony_ci } 7797db96d56Sopenharmony_ci else if (!gettmarg(state, tup, &buf, 7807db96d56Sopenharmony_ci "iiiiiiiii;strftime(): illegal time tuple argument") || 7817db96d56Sopenharmony_ci !checktm(&buf)) 7827db96d56Sopenharmony_ci { 7837db96d56Sopenharmony_ci return NULL; 7847db96d56Sopenharmony_ci } 7857db96d56Sopenharmony_ci 7867db96d56Sopenharmony_ci#if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__) 7877db96d56Sopenharmony_ci if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) { 7887db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 7897db96d56Sopenharmony_ci "strftime() requires year in [1; 9999]"); 7907db96d56Sopenharmony_ci return NULL; 7917db96d56Sopenharmony_ci } 7927db96d56Sopenharmony_ci#endif 7937db96d56Sopenharmony_ci 7947db96d56Sopenharmony_ci /* Normalize tm_isdst just in case someone foolishly implements %Z 7957db96d56Sopenharmony_ci based on the assumption that tm_isdst falls within the range of 7967db96d56Sopenharmony_ci [-1, 1] */ 7977db96d56Sopenharmony_ci if (buf.tm_isdst < -1) 7987db96d56Sopenharmony_ci buf.tm_isdst = -1; 7997db96d56Sopenharmony_ci else if (buf.tm_isdst > 1) 8007db96d56Sopenharmony_ci buf.tm_isdst = 1; 8017db96d56Sopenharmony_ci 8027db96d56Sopenharmony_ci#ifdef HAVE_WCSFTIME 8037db96d56Sopenharmony_ci format = PyUnicode_AsWideCharString(format_arg, NULL); 8047db96d56Sopenharmony_ci if (format == NULL) 8057db96d56Sopenharmony_ci return NULL; 8067db96d56Sopenharmony_ci fmt = format; 8077db96d56Sopenharmony_ci#else 8087db96d56Sopenharmony_ci /* Convert the unicode string to an ascii one */ 8097db96d56Sopenharmony_ci format = PyUnicode_EncodeLocale(format_arg, "surrogateescape"); 8107db96d56Sopenharmony_ci if (format == NULL) 8117db96d56Sopenharmony_ci return NULL; 8127db96d56Sopenharmony_ci fmt = PyBytes_AS_STRING(format); 8137db96d56Sopenharmony_ci#endif 8147db96d56Sopenharmony_ci 8157db96d56Sopenharmony_ci#if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) 8167db96d56Sopenharmony_ci /* check that the format string contains only valid directives */ 8177db96d56Sopenharmony_ci for (outbuf = strchr(fmt, '%'); 8187db96d56Sopenharmony_ci outbuf != NULL; 8197db96d56Sopenharmony_ci outbuf = strchr(outbuf+2, '%')) 8207db96d56Sopenharmony_ci { 8217db96d56Sopenharmony_ci if (outbuf[1] == '#') 8227db96d56Sopenharmony_ci ++outbuf; /* not documented by python, */ 8237db96d56Sopenharmony_ci if (outbuf[1] == '\0') 8247db96d56Sopenharmony_ci break; 8257db96d56Sopenharmony_ci if ((outbuf[1] == 'y') && buf.tm_year < 0) { 8267db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 8277db96d56Sopenharmony_ci "format %y requires year >= 1900 on Windows"); 8287db96d56Sopenharmony_ci Py_DECREF(format); 8297db96d56Sopenharmony_ci return NULL; 8307db96d56Sopenharmony_ci } 8317db96d56Sopenharmony_ci } 8327db96d56Sopenharmony_ci#elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME) 8337db96d56Sopenharmony_ci for (outbuf = wcschr(fmt, '%'); 8347db96d56Sopenharmony_ci outbuf != NULL; 8357db96d56Sopenharmony_ci outbuf = wcschr(outbuf+2, '%')) 8367db96d56Sopenharmony_ci { 8377db96d56Sopenharmony_ci if (outbuf[1] == L'\0') 8387db96d56Sopenharmony_ci break; 8397db96d56Sopenharmony_ci /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) 8407db96d56Sopenharmony_ci returns "0/" instead of "99" */ 8417db96d56Sopenharmony_ci if (outbuf[1] == L'y' && buf.tm_year < 0) { 8427db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 8437db96d56Sopenharmony_ci "format %y requires year >= 1900 on AIX"); 8447db96d56Sopenharmony_ci PyMem_Free(format); 8457db96d56Sopenharmony_ci return NULL; 8467db96d56Sopenharmony_ci } 8477db96d56Sopenharmony_ci } 8487db96d56Sopenharmony_ci#endif 8497db96d56Sopenharmony_ci 8507db96d56Sopenharmony_ci fmtlen = time_strlen(fmt); 8517db96d56Sopenharmony_ci 8527db96d56Sopenharmony_ci /* I hate these functions that presume you know how big the output 8537db96d56Sopenharmony_ci * will be ahead of time... 8547db96d56Sopenharmony_ci */ 8557db96d56Sopenharmony_ci for (i = 1024; ; i += i) { 8567db96d56Sopenharmony_ci outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char)); 8577db96d56Sopenharmony_ci if (outbuf == NULL) { 8587db96d56Sopenharmony_ci PyErr_NoMemory(); 8597db96d56Sopenharmony_ci break; 8607db96d56Sopenharmony_ci } 8617db96d56Sopenharmony_ci#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) 8627db96d56Sopenharmony_ci errno = 0; 8637db96d56Sopenharmony_ci#endif 8647db96d56Sopenharmony_ci _Py_BEGIN_SUPPRESS_IPH 8657db96d56Sopenharmony_ci buflen = format_time(outbuf, i, fmt, &buf); 8667db96d56Sopenharmony_ci _Py_END_SUPPRESS_IPH 8677db96d56Sopenharmony_ci#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) 8687db96d56Sopenharmony_ci /* VisualStudio .NET 2005 does this properly */ 8697db96d56Sopenharmony_ci if (buflen == 0 && errno == EINVAL) { 8707db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Invalid format string"); 8717db96d56Sopenharmony_ci PyMem_Free(outbuf); 8727db96d56Sopenharmony_ci break; 8737db96d56Sopenharmony_ci } 8747db96d56Sopenharmony_ci#endif 8757db96d56Sopenharmony_ci if (buflen > 0 || i >= 256 * fmtlen) { 8767db96d56Sopenharmony_ci /* If the buffer is 256 times as long as the format, 8777db96d56Sopenharmony_ci it's probably not failing for lack of room! 8787db96d56Sopenharmony_ci More likely, the format yields an empty result, 8797db96d56Sopenharmony_ci e.g. an empty format, or %Z when the timezone 8807db96d56Sopenharmony_ci is unknown. */ 8817db96d56Sopenharmony_ci#ifdef HAVE_WCSFTIME 8827db96d56Sopenharmony_ci ret = PyUnicode_FromWideChar(outbuf, buflen); 8837db96d56Sopenharmony_ci#else 8847db96d56Sopenharmony_ci ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape"); 8857db96d56Sopenharmony_ci#endif 8867db96d56Sopenharmony_ci PyMem_Free(outbuf); 8877db96d56Sopenharmony_ci break; 8887db96d56Sopenharmony_ci } 8897db96d56Sopenharmony_ci PyMem_Free(outbuf); 8907db96d56Sopenharmony_ci } 8917db96d56Sopenharmony_ci#ifdef HAVE_WCSFTIME 8927db96d56Sopenharmony_ci PyMem_Free(format); 8937db96d56Sopenharmony_ci#else 8947db96d56Sopenharmony_ci Py_DECREF(format); 8957db96d56Sopenharmony_ci#endif 8967db96d56Sopenharmony_ci return ret; 8977db96d56Sopenharmony_ci} 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci#undef time_char 9007db96d56Sopenharmony_ci#undef format_time 9017db96d56Sopenharmony_ciPyDoc_STRVAR(strftime_doc, 9027db96d56Sopenharmony_ci"strftime(format[, tuple]) -> string\n\ 9037db96d56Sopenharmony_ci\n\ 9047db96d56Sopenharmony_ciConvert a time tuple to a string according to a format specification.\n\ 9057db96d56Sopenharmony_ciSee the library reference manual for formatting codes. When the time tuple\n\ 9067db96d56Sopenharmony_ciis not present, current time as returned by localtime() is used.\n\ 9077db96d56Sopenharmony_ci\n" STRFTIME_FORMAT_CODES); 9087db96d56Sopenharmony_ci#endif /* HAVE_STRFTIME */ 9097db96d56Sopenharmony_ci 9107db96d56Sopenharmony_cistatic PyObject * 9117db96d56Sopenharmony_citime_strptime(PyObject *self, PyObject *args) 9127db96d56Sopenharmony_ci{ 9137db96d56Sopenharmony_ci PyObject *module, *func, *result; 9147db96d56Sopenharmony_ci 9157db96d56Sopenharmony_ci module = PyImport_ImportModule("_strptime"); 9167db96d56Sopenharmony_ci if (!module) 9177db96d56Sopenharmony_ci return NULL; 9187db96d56Sopenharmony_ci 9197db96d56Sopenharmony_ci func = PyObject_GetAttr(module, &_Py_ID(_strptime_time)); 9207db96d56Sopenharmony_ci Py_DECREF(module); 9217db96d56Sopenharmony_ci if (!func) { 9227db96d56Sopenharmony_ci return NULL; 9237db96d56Sopenharmony_ci } 9247db96d56Sopenharmony_ci 9257db96d56Sopenharmony_ci result = PyObject_Call(func, args, NULL); 9267db96d56Sopenharmony_ci Py_DECREF(func); 9277db96d56Sopenharmony_ci return result; 9287db96d56Sopenharmony_ci} 9297db96d56Sopenharmony_ci 9307db96d56Sopenharmony_ci 9317db96d56Sopenharmony_ciPyDoc_STRVAR(strptime_doc, 9327db96d56Sopenharmony_ci"strptime(string, format) -> struct_time\n\ 9337db96d56Sopenharmony_ci\n\ 9347db96d56Sopenharmony_ciParse a string to a time tuple according to a format specification.\n\ 9357db96d56Sopenharmony_ciSee the library reference manual for formatting codes (same as\n\ 9367db96d56Sopenharmony_cistrftime()).\n\ 9377db96d56Sopenharmony_ci\n" STRFTIME_FORMAT_CODES); 9387db96d56Sopenharmony_ci 9397db96d56Sopenharmony_cistatic PyObject * 9407db96d56Sopenharmony_ci_asctime(struct tm *timeptr) 9417db96d56Sopenharmony_ci{ 9427db96d56Sopenharmony_ci /* Inspired by Open Group reference implementation available at 9437db96d56Sopenharmony_ci * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */ 9447db96d56Sopenharmony_ci static const char wday_name[7][4] = { 9457db96d56Sopenharmony_ci "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 9467db96d56Sopenharmony_ci }; 9477db96d56Sopenharmony_ci static const char mon_name[12][4] = { 9487db96d56Sopenharmony_ci "Jan", "Feb", "Mar", "Apr", "May", "Jun", 9497db96d56Sopenharmony_ci "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 9507db96d56Sopenharmony_ci }; 9517db96d56Sopenharmony_ci return PyUnicode_FromFormat( 9527db96d56Sopenharmony_ci "%s %s%3d %.2d:%.2d:%.2d %d", 9537db96d56Sopenharmony_ci wday_name[timeptr->tm_wday], 9547db96d56Sopenharmony_ci mon_name[timeptr->tm_mon], 9557db96d56Sopenharmony_ci timeptr->tm_mday, timeptr->tm_hour, 9567db96d56Sopenharmony_ci timeptr->tm_min, timeptr->tm_sec, 9577db96d56Sopenharmony_ci 1900 + timeptr->tm_year); 9587db96d56Sopenharmony_ci} 9597db96d56Sopenharmony_ci 9607db96d56Sopenharmony_cistatic PyObject * 9617db96d56Sopenharmony_citime_asctime(PyObject *module, PyObject *args) 9627db96d56Sopenharmony_ci{ 9637db96d56Sopenharmony_ci PyObject *tup = NULL; 9647db96d56Sopenharmony_ci struct tm buf; 9657db96d56Sopenharmony_ci 9667db96d56Sopenharmony_ci if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) 9677db96d56Sopenharmony_ci return NULL; 9687db96d56Sopenharmony_ci 9697db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 9707db96d56Sopenharmony_ci if (tup == NULL) { 9717db96d56Sopenharmony_ci time_t tt = time(NULL); 9727db96d56Sopenharmony_ci if (_PyTime_localtime(tt, &buf) != 0) 9737db96d56Sopenharmony_ci return NULL; 9747db96d56Sopenharmony_ci } 9757db96d56Sopenharmony_ci else if (!gettmarg(state, tup, &buf, 9767db96d56Sopenharmony_ci "iiiiiiiii;asctime(): illegal time tuple argument") || 9777db96d56Sopenharmony_ci !checktm(&buf)) 9787db96d56Sopenharmony_ci { 9797db96d56Sopenharmony_ci return NULL; 9807db96d56Sopenharmony_ci } 9817db96d56Sopenharmony_ci return _asctime(&buf); 9827db96d56Sopenharmony_ci} 9837db96d56Sopenharmony_ci 9847db96d56Sopenharmony_ciPyDoc_STRVAR(asctime_doc, 9857db96d56Sopenharmony_ci"asctime([tuple]) -> string\n\ 9867db96d56Sopenharmony_ci\n\ 9877db96d56Sopenharmony_ciConvert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\ 9887db96d56Sopenharmony_ciWhen the time tuple is not present, current time as returned by localtime()\n\ 9897db96d56Sopenharmony_ciis used."); 9907db96d56Sopenharmony_ci 9917db96d56Sopenharmony_cistatic PyObject * 9927db96d56Sopenharmony_citime_ctime(PyObject *self, PyObject *args) 9937db96d56Sopenharmony_ci{ 9947db96d56Sopenharmony_ci time_t tt; 9957db96d56Sopenharmony_ci struct tm buf; 9967db96d56Sopenharmony_ci if (!parse_time_t_args(args, "|O:ctime", &tt)) 9977db96d56Sopenharmony_ci return NULL; 9987db96d56Sopenharmony_ci if (_PyTime_localtime(tt, &buf) != 0) 9997db96d56Sopenharmony_ci return NULL; 10007db96d56Sopenharmony_ci return _asctime(&buf); 10017db96d56Sopenharmony_ci} 10027db96d56Sopenharmony_ci 10037db96d56Sopenharmony_ciPyDoc_STRVAR(ctime_doc, 10047db96d56Sopenharmony_ci"ctime(seconds) -> string\n\ 10057db96d56Sopenharmony_ci\n\ 10067db96d56Sopenharmony_ciConvert a time in seconds since the Epoch to a string in local time.\n\ 10077db96d56Sopenharmony_ciThis is equivalent to asctime(localtime(seconds)). When the time tuple is\n\ 10087db96d56Sopenharmony_cinot present, current time as returned by localtime() is used."); 10097db96d56Sopenharmony_ci 10107db96d56Sopenharmony_ci#ifdef HAVE_MKTIME 10117db96d56Sopenharmony_cistatic PyObject * 10127db96d56Sopenharmony_citime_mktime(PyObject *module, PyObject *tm_tuple) 10137db96d56Sopenharmony_ci{ 10147db96d56Sopenharmony_ci struct tm tm; 10157db96d56Sopenharmony_ci time_t tt; 10167db96d56Sopenharmony_ci 10177db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 10187db96d56Sopenharmony_ci if (!gettmarg(state, tm_tuple, &tm, 10197db96d56Sopenharmony_ci "iiiiiiiii;mktime(): illegal time tuple argument")) 10207db96d56Sopenharmony_ci { 10217db96d56Sopenharmony_ci return NULL; 10227db96d56Sopenharmony_ci } 10237db96d56Sopenharmony_ci 10247db96d56Sopenharmony_ci#if defined(_AIX) || (defined(__VXWORKS__) && !defined(_WRS_CONFIG_LP64)) 10257db96d56Sopenharmony_ci /* bpo-19748: AIX mktime() valid range is 00:00:00 UTC, January 1, 1970 10267db96d56Sopenharmony_ci to 03:14:07 UTC, January 19, 2038. Thanks to the workaround below, 10277db96d56Sopenharmony_ci it is possible to support years in range [1902; 2037] */ 10287db96d56Sopenharmony_ci if (tm.tm_year < 2 || tm.tm_year > 137) { 10297db96d56Sopenharmony_ci /* bpo-19748: On AIX, mktime() does not report overflow error 10307db96d56Sopenharmony_ci for timestamp < -2^31 or timestamp > 2**31-1. VxWorks has the 10317db96d56Sopenharmony_ci same issue when working in 32 bit mode. */ 10327db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 10337db96d56Sopenharmony_ci "mktime argument out of range"); 10347db96d56Sopenharmony_ci return NULL; 10357db96d56Sopenharmony_ci } 10367db96d56Sopenharmony_ci#endif 10377db96d56Sopenharmony_ci 10387db96d56Sopenharmony_ci#ifdef _AIX 10397db96d56Sopenharmony_ci /* bpo-34373: AIX mktime() has an integer overflow for years in range 10407db96d56Sopenharmony_ci [1902; 1969]. Workaround the issue by using a year greater or equal than 10417db96d56Sopenharmony_ci 1970 (tm_year >= 70): mktime() behaves correctly in that case 10427db96d56Sopenharmony_ci (ex: properly report errors). tm_year and tm_wday are adjusted after 10437db96d56Sopenharmony_ci mktime() call. */ 10447db96d56Sopenharmony_ci int orig_tm_year = tm.tm_year; 10457db96d56Sopenharmony_ci int delta_days = 0; 10467db96d56Sopenharmony_ci while (tm.tm_year < 70) { 10477db96d56Sopenharmony_ci /* Use 4 years to account properly leap years */ 10487db96d56Sopenharmony_ci tm.tm_year += 4; 10497db96d56Sopenharmony_ci delta_days -= (366 + (365 * 3)); 10507db96d56Sopenharmony_ci } 10517db96d56Sopenharmony_ci#endif 10527db96d56Sopenharmony_ci 10537db96d56Sopenharmony_ci tm.tm_wday = -1; /* sentinel; original value ignored */ 10547db96d56Sopenharmony_ci tt = mktime(&tm); 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_ci /* Return value of -1 does not necessarily mean an error, but tm_wday 10577db96d56Sopenharmony_ci * cannot remain set to -1 if mktime succeeded. */ 10587db96d56Sopenharmony_ci if (tt == (time_t)(-1) 10597db96d56Sopenharmony_ci /* Return value of -1 does not necessarily mean an error, but 10607db96d56Sopenharmony_ci * tm_wday cannot remain set to -1 if mktime succeeded. */ 10617db96d56Sopenharmony_ci && tm.tm_wday == -1) 10627db96d56Sopenharmony_ci { 10637db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 10647db96d56Sopenharmony_ci "mktime argument out of range"); 10657db96d56Sopenharmony_ci return NULL; 10667db96d56Sopenharmony_ci } 10677db96d56Sopenharmony_ci 10687db96d56Sopenharmony_ci#ifdef _AIX 10697db96d56Sopenharmony_ci if (delta_days != 0) { 10707db96d56Sopenharmony_ci tm.tm_year = orig_tm_year; 10717db96d56Sopenharmony_ci if (tm.tm_wday != -1) { 10727db96d56Sopenharmony_ci tm.tm_wday = (tm.tm_wday + delta_days) % 7; 10737db96d56Sopenharmony_ci } 10747db96d56Sopenharmony_ci tt += delta_days * (24 * 3600); 10757db96d56Sopenharmony_ci } 10767db96d56Sopenharmony_ci#endif 10777db96d56Sopenharmony_ci 10787db96d56Sopenharmony_ci return PyFloat_FromDouble((double)tt); 10797db96d56Sopenharmony_ci} 10807db96d56Sopenharmony_ci 10817db96d56Sopenharmony_ciPyDoc_STRVAR(mktime_doc, 10827db96d56Sopenharmony_ci"mktime(tuple) -> floating point number\n\ 10837db96d56Sopenharmony_ci\n\ 10847db96d56Sopenharmony_ciConvert a time tuple in local time to seconds since the Epoch.\n\ 10857db96d56Sopenharmony_ciNote that mktime(gmtime(0)) will not generally return zero for most\n\ 10867db96d56Sopenharmony_citime zones; instead the returned value will either be equal to that\n\ 10877db96d56Sopenharmony_ciof the timezone or altzone attributes on the time module."); 10887db96d56Sopenharmony_ci#endif /* HAVE_MKTIME */ 10897db96d56Sopenharmony_ci 10907db96d56Sopenharmony_ci#ifdef HAVE_WORKING_TZSET 10917db96d56Sopenharmony_cistatic int init_timezone(PyObject *module); 10927db96d56Sopenharmony_ci 10937db96d56Sopenharmony_cistatic PyObject * 10947db96d56Sopenharmony_citime_tzset(PyObject *self, PyObject *unused) 10957db96d56Sopenharmony_ci{ 10967db96d56Sopenharmony_ci PyObject* m; 10977db96d56Sopenharmony_ci 10987db96d56Sopenharmony_ci m = PyImport_ImportModule("time"); 10997db96d56Sopenharmony_ci if (m == NULL) { 11007db96d56Sopenharmony_ci return NULL; 11017db96d56Sopenharmony_ci } 11027db96d56Sopenharmony_ci 11037db96d56Sopenharmony_ci tzset(); 11047db96d56Sopenharmony_ci 11057db96d56Sopenharmony_ci /* Reset timezone, altzone, daylight and tzname */ 11067db96d56Sopenharmony_ci if (init_timezone(m) < 0) { 11077db96d56Sopenharmony_ci return NULL; 11087db96d56Sopenharmony_ci } 11097db96d56Sopenharmony_ci Py_DECREF(m); 11107db96d56Sopenharmony_ci if (PyErr_Occurred()) 11117db96d56Sopenharmony_ci return NULL; 11127db96d56Sopenharmony_ci 11137db96d56Sopenharmony_ci Py_RETURN_NONE; 11147db96d56Sopenharmony_ci} 11157db96d56Sopenharmony_ci 11167db96d56Sopenharmony_ciPyDoc_STRVAR(tzset_doc, 11177db96d56Sopenharmony_ci"tzset()\n\ 11187db96d56Sopenharmony_ci\n\ 11197db96d56Sopenharmony_ciInitialize, or reinitialize, the local timezone to the value stored in\n\ 11207db96d56Sopenharmony_cios.environ['TZ']. The TZ environment variable should be specified in\n\ 11217db96d56Sopenharmony_cistandard Unix timezone format as documented in the tzset man page\n\ 11227db96d56Sopenharmony_ci(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\ 11237db96d56Sopenharmony_cifall back to UTC. If the TZ environment variable is not set, the local\n\ 11247db96d56Sopenharmony_citimezone is set to the systems best guess of wallclock time.\n\ 11257db96d56Sopenharmony_ciChanging the TZ environment variable without calling tzset *may* change\n\ 11267db96d56Sopenharmony_cithe local timezone used by methods such as localtime, but this behaviour\n\ 11277db96d56Sopenharmony_cishould not be relied on."); 11287db96d56Sopenharmony_ci#endif /* HAVE_WORKING_TZSET */ 11297db96d56Sopenharmony_ci 11307db96d56Sopenharmony_ci 11317db96d56Sopenharmony_cistatic int 11327db96d56Sopenharmony_ciget_monotonic(_PyTime_t *t) 11337db96d56Sopenharmony_ci{ 11347db96d56Sopenharmony_ci // Avoid _PyTime_GetMonotonicClock() which silently ignores errors. 11357db96d56Sopenharmony_ci return _PyTime_GetMonotonicClockWithInfo(t, NULL); 11367db96d56Sopenharmony_ci} 11377db96d56Sopenharmony_ci 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_cistatic PyObject * 11407db96d56Sopenharmony_citime_monotonic(PyObject *self, PyObject *unused) 11417db96d56Sopenharmony_ci{ 11427db96d56Sopenharmony_ci _PyTime_t t; 11437db96d56Sopenharmony_ci if (get_monotonic(&t) < 0) { 11447db96d56Sopenharmony_ci return NULL; 11457db96d56Sopenharmony_ci } 11467db96d56Sopenharmony_ci return _PyFloat_FromPyTime(t); 11477db96d56Sopenharmony_ci} 11487db96d56Sopenharmony_ci 11497db96d56Sopenharmony_ciPyDoc_STRVAR(monotonic_doc, 11507db96d56Sopenharmony_ci"monotonic() -> float\n\ 11517db96d56Sopenharmony_ci\n\ 11527db96d56Sopenharmony_ciMonotonic clock, cannot go backward."); 11537db96d56Sopenharmony_ci 11547db96d56Sopenharmony_cistatic PyObject * 11557db96d56Sopenharmony_citime_monotonic_ns(PyObject *self, PyObject *unused) 11567db96d56Sopenharmony_ci{ 11577db96d56Sopenharmony_ci _PyTime_t t; 11587db96d56Sopenharmony_ci if (get_monotonic(&t) < 0) { 11597db96d56Sopenharmony_ci return NULL; 11607db96d56Sopenharmony_ci } 11617db96d56Sopenharmony_ci return _PyTime_AsNanosecondsObject(t); 11627db96d56Sopenharmony_ci} 11637db96d56Sopenharmony_ci 11647db96d56Sopenharmony_ciPyDoc_STRVAR(monotonic_ns_doc, 11657db96d56Sopenharmony_ci"monotonic_ns() -> int\n\ 11667db96d56Sopenharmony_ci\n\ 11677db96d56Sopenharmony_ciMonotonic clock, cannot go backward, as nanoseconds."); 11687db96d56Sopenharmony_ci 11697db96d56Sopenharmony_ci 11707db96d56Sopenharmony_cistatic int 11717db96d56Sopenharmony_ciget_perf_counter(_PyTime_t *t) 11727db96d56Sopenharmony_ci{ 11737db96d56Sopenharmony_ci // Avoid _PyTime_GetPerfCounter() which silently ignores errors. 11747db96d56Sopenharmony_ci return _PyTime_GetPerfCounterWithInfo(t, NULL); 11757db96d56Sopenharmony_ci} 11767db96d56Sopenharmony_ci 11777db96d56Sopenharmony_ci 11787db96d56Sopenharmony_cistatic PyObject * 11797db96d56Sopenharmony_citime_perf_counter(PyObject *self, PyObject *unused) 11807db96d56Sopenharmony_ci{ 11817db96d56Sopenharmony_ci _PyTime_t t; 11827db96d56Sopenharmony_ci if (get_perf_counter(&t) < 0) { 11837db96d56Sopenharmony_ci return NULL; 11847db96d56Sopenharmony_ci } 11857db96d56Sopenharmony_ci return _PyFloat_FromPyTime(t); 11867db96d56Sopenharmony_ci} 11877db96d56Sopenharmony_ci 11887db96d56Sopenharmony_ciPyDoc_STRVAR(perf_counter_doc, 11897db96d56Sopenharmony_ci"perf_counter() -> float\n\ 11907db96d56Sopenharmony_ci\n\ 11917db96d56Sopenharmony_ciPerformance counter for benchmarking."); 11927db96d56Sopenharmony_ci 11937db96d56Sopenharmony_ci 11947db96d56Sopenharmony_cistatic PyObject * 11957db96d56Sopenharmony_citime_perf_counter_ns(PyObject *self, PyObject *unused) 11967db96d56Sopenharmony_ci{ 11977db96d56Sopenharmony_ci _PyTime_t t; 11987db96d56Sopenharmony_ci if (get_perf_counter(&t) < 0) { 11997db96d56Sopenharmony_ci return NULL; 12007db96d56Sopenharmony_ci } 12017db96d56Sopenharmony_ci return _PyTime_AsNanosecondsObject(t); 12027db96d56Sopenharmony_ci} 12037db96d56Sopenharmony_ci 12047db96d56Sopenharmony_ciPyDoc_STRVAR(perf_counter_ns_doc, 12057db96d56Sopenharmony_ci"perf_counter_ns() -> int\n\ 12067db96d56Sopenharmony_ci\n\ 12077db96d56Sopenharmony_ciPerformance counter for benchmarking as nanoseconds."); 12087db96d56Sopenharmony_ci 12097db96d56Sopenharmony_cistatic int 12107db96d56Sopenharmony_ci_PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) 12117db96d56Sopenharmony_ci{ 12127db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 12137db96d56Sopenharmony_ci HANDLE process; 12147db96d56Sopenharmony_ci FILETIME creation_time, exit_time, kernel_time, user_time; 12157db96d56Sopenharmony_ci ULARGE_INTEGER large; 12167db96d56Sopenharmony_ci _PyTime_t ktime, utime, t; 12177db96d56Sopenharmony_ci BOOL ok; 12187db96d56Sopenharmony_ci 12197db96d56Sopenharmony_ci process = GetCurrentProcess(); 12207db96d56Sopenharmony_ci ok = GetProcessTimes(process, &creation_time, &exit_time, 12217db96d56Sopenharmony_ci &kernel_time, &user_time); 12227db96d56Sopenharmony_ci if (!ok) { 12237db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 12247db96d56Sopenharmony_ci return -1; 12257db96d56Sopenharmony_ci } 12267db96d56Sopenharmony_ci 12277db96d56Sopenharmony_ci if (info) { 12287db96d56Sopenharmony_ci info->implementation = "GetProcessTimes()"; 12297db96d56Sopenharmony_ci info->resolution = 1e-7; 12307db96d56Sopenharmony_ci info->monotonic = 1; 12317db96d56Sopenharmony_ci info->adjustable = 0; 12327db96d56Sopenharmony_ci } 12337db96d56Sopenharmony_ci 12347db96d56Sopenharmony_ci large.u.LowPart = kernel_time.dwLowDateTime; 12357db96d56Sopenharmony_ci large.u.HighPart = kernel_time.dwHighDateTime; 12367db96d56Sopenharmony_ci ktime = large.QuadPart; 12377db96d56Sopenharmony_ci 12387db96d56Sopenharmony_ci large.u.LowPart = user_time.dwLowDateTime; 12397db96d56Sopenharmony_ci large.u.HighPart = user_time.dwHighDateTime; 12407db96d56Sopenharmony_ci utime = large.QuadPart; 12417db96d56Sopenharmony_ci 12427db96d56Sopenharmony_ci /* ktime and utime have a resolution of 100 nanoseconds */ 12437db96d56Sopenharmony_ci t = _PyTime_FromNanoseconds((ktime + utime) * 100); 12447db96d56Sopenharmony_ci *tp = t; 12457db96d56Sopenharmony_ci return 0; 12467db96d56Sopenharmony_ci#else 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_ci /* clock_gettime */ 12497db96d56Sopenharmony_ci#if defined(HAVE_CLOCK_GETTIME) \ 12507db96d56Sopenharmony_ci && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF)) 12517db96d56Sopenharmony_ci struct timespec ts; 12527db96d56Sopenharmony_ci 12537db96d56Sopenharmony_ci if (HAVE_CLOCK_GETTIME_RUNTIME) { 12547db96d56Sopenharmony_ci 12557db96d56Sopenharmony_ci#ifdef CLOCK_PROF 12567db96d56Sopenharmony_ci const clockid_t clk_id = CLOCK_PROF; 12577db96d56Sopenharmony_ci const char *function = "clock_gettime(CLOCK_PROF)"; 12587db96d56Sopenharmony_ci#else 12597db96d56Sopenharmony_ci const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID; 12607db96d56Sopenharmony_ci const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)"; 12617db96d56Sopenharmony_ci#endif 12627db96d56Sopenharmony_ci 12637db96d56Sopenharmony_ci if (clock_gettime(clk_id, &ts) == 0) { 12647db96d56Sopenharmony_ci if (info) { 12657db96d56Sopenharmony_ci struct timespec res; 12667db96d56Sopenharmony_ci info->implementation = function; 12677db96d56Sopenharmony_ci info->monotonic = 1; 12687db96d56Sopenharmony_ci info->adjustable = 0; 12697db96d56Sopenharmony_ci if (clock_getres(clk_id, &res)) { 12707db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 12717db96d56Sopenharmony_ci return -1; 12727db96d56Sopenharmony_ci } 12737db96d56Sopenharmony_ci info->resolution = res.tv_sec + res.tv_nsec * 1e-9; 12747db96d56Sopenharmony_ci } 12757db96d56Sopenharmony_ci 12767db96d56Sopenharmony_ci if (_PyTime_FromTimespec(tp, &ts) < 0) { 12777db96d56Sopenharmony_ci return -1; 12787db96d56Sopenharmony_ci } 12797db96d56Sopenharmony_ci return 0; 12807db96d56Sopenharmony_ci } 12817db96d56Sopenharmony_ci } 12827db96d56Sopenharmony_ci#endif 12837db96d56Sopenharmony_ci 12847db96d56Sopenharmony_ci /* getrusage(RUSAGE_SELF) */ 12857db96d56Sopenharmony_ci#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRUSAGE) 12867db96d56Sopenharmony_ci struct rusage ru; 12877db96d56Sopenharmony_ci 12887db96d56Sopenharmony_ci if (getrusage(RUSAGE_SELF, &ru) == 0) { 12897db96d56Sopenharmony_ci _PyTime_t utime, stime; 12907db96d56Sopenharmony_ci 12917db96d56Sopenharmony_ci if (info) { 12927db96d56Sopenharmony_ci info->implementation = "getrusage(RUSAGE_SELF)"; 12937db96d56Sopenharmony_ci info->monotonic = 1; 12947db96d56Sopenharmony_ci info->adjustable = 0; 12957db96d56Sopenharmony_ci info->resolution = 1e-6; 12967db96d56Sopenharmony_ci } 12977db96d56Sopenharmony_ci 12987db96d56Sopenharmony_ci if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) { 12997db96d56Sopenharmony_ci return -1; 13007db96d56Sopenharmony_ci } 13017db96d56Sopenharmony_ci if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) { 13027db96d56Sopenharmony_ci return -1; 13037db96d56Sopenharmony_ci } 13047db96d56Sopenharmony_ci 13057db96d56Sopenharmony_ci _PyTime_t total = utime + stime; 13067db96d56Sopenharmony_ci *tp = total; 13077db96d56Sopenharmony_ci return 0; 13087db96d56Sopenharmony_ci } 13097db96d56Sopenharmony_ci#endif 13107db96d56Sopenharmony_ci 13117db96d56Sopenharmony_ci /* times() */ 13127db96d56Sopenharmony_ci#ifdef HAVE_TIMES 13137db96d56Sopenharmony_ci struct tms t; 13147db96d56Sopenharmony_ci 13157db96d56Sopenharmony_ci if (times(&t) != (clock_t)-1) { 13167db96d56Sopenharmony_ci static long ticks_per_second = -1; 13177db96d56Sopenharmony_ci 13187db96d56Sopenharmony_ci if (ticks_per_second == -1) { 13197db96d56Sopenharmony_ci long freq; 13207db96d56Sopenharmony_ci#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) 13217db96d56Sopenharmony_ci freq = sysconf(_SC_CLK_TCK); 13227db96d56Sopenharmony_ci if (freq < 1) { 13237db96d56Sopenharmony_ci freq = -1; 13247db96d56Sopenharmony_ci } 13257db96d56Sopenharmony_ci#elif defined(HZ) 13267db96d56Sopenharmony_ci freq = HZ; 13277db96d56Sopenharmony_ci#else 13287db96d56Sopenharmony_ci freq = 60; /* magic fallback value; may be bogus */ 13297db96d56Sopenharmony_ci#endif 13307db96d56Sopenharmony_ci 13317db96d56Sopenharmony_ci if (freq != -1) { 13327db96d56Sopenharmony_ci /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) 13337db96d56Sopenharmony_ci cannot overflow below */ 13347db96d56Sopenharmony_ci#if LONG_MAX > _PyTime_MAX / SEC_TO_NS 13357db96d56Sopenharmony_ci if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) { 13367db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 13377db96d56Sopenharmony_ci "_SC_CLK_TCK is too large"); 13387db96d56Sopenharmony_ci return -1; 13397db96d56Sopenharmony_ci } 13407db96d56Sopenharmony_ci#endif 13417db96d56Sopenharmony_ci 13427db96d56Sopenharmony_ci ticks_per_second = freq; 13437db96d56Sopenharmony_ci } 13447db96d56Sopenharmony_ci } 13457db96d56Sopenharmony_ci 13467db96d56Sopenharmony_ci if (ticks_per_second != -1) { 13477db96d56Sopenharmony_ci if (info) { 13487db96d56Sopenharmony_ci info->implementation = "times()"; 13497db96d56Sopenharmony_ci info->monotonic = 1; 13507db96d56Sopenharmony_ci info->adjustable = 0; 13517db96d56Sopenharmony_ci info->resolution = 1.0 / (double)ticks_per_second; 13527db96d56Sopenharmony_ci } 13537db96d56Sopenharmony_ci 13547db96d56Sopenharmony_ci _PyTime_t ns; 13557db96d56Sopenharmony_ci ns = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second); 13567db96d56Sopenharmony_ci ns += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second); 13577db96d56Sopenharmony_ci *tp = _PyTime_FromNanoseconds(ns); 13587db96d56Sopenharmony_ci return 0; 13597db96d56Sopenharmony_ci } 13607db96d56Sopenharmony_ci } 13617db96d56Sopenharmony_ci#endif 13627db96d56Sopenharmony_ci 13637db96d56Sopenharmony_ci /* clock */ 13647db96d56Sopenharmony_ci /* Currently, Python 3 requires clock() to build: see issue #22624 */ 13657db96d56Sopenharmony_ci return _PyTime_GetClockWithInfo(tp, info); 13667db96d56Sopenharmony_ci#endif 13677db96d56Sopenharmony_ci} 13687db96d56Sopenharmony_ci 13697db96d56Sopenharmony_cistatic PyObject * 13707db96d56Sopenharmony_citime_process_time(PyObject *self, PyObject *unused) 13717db96d56Sopenharmony_ci{ 13727db96d56Sopenharmony_ci _PyTime_t t; 13737db96d56Sopenharmony_ci if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { 13747db96d56Sopenharmony_ci return NULL; 13757db96d56Sopenharmony_ci } 13767db96d56Sopenharmony_ci return _PyFloat_FromPyTime(t); 13777db96d56Sopenharmony_ci} 13787db96d56Sopenharmony_ci 13797db96d56Sopenharmony_ciPyDoc_STRVAR(process_time_doc, 13807db96d56Sopenharmony_ci"process_time() -> float\n\ 13817db96d56Sopenharmony_ci\n\ 13827db96d56Sopenharmony_ciProcess time for profiling: sum of the kernel and user-space CPU time."); 13837db96d56Sopenharmony_ci 13847db96d56Sopenharmony_cistatic PyObject * 13857db96d56Sopenharmony_citime_process_time_ns(PyObject *self, PyObject *unused) 13867db96d56Sopenharmony_ci{ 13877db96d56Sopenharmony_ci _PyTime_t t; 13887db96d56Sopenharmony_ci if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { 13897db96d56Sopenharmony_ci return NULL; 13907db96d56Sopenharmony_ci } 13917db96d56Sopenharmony_ci return _PyTime_AsNanosecondsObject(t); 13927db96d56Sopenharmony_ci} 13937db96d56Sopenharmony_ci 13947db96d56Sopenharmony_ciPyDoc_STRVAR(process_time_ns_doc, 13957db96d56Sopenharmony_ci"process_time() -> int\n\ 13967db96d56Sopenharmony_ci\n\ 13977db96d56Sopenharmony_ciProcess time for profiling as nanoseconds:\n\ 13987db96d56Sopenharmony_cisum of the kernel and user-space CPU time."); 13997db96d56Sopenharmony_ci 14007db96d56Sopenharmony_ci 14017db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 14027db96d56Sopenharmony_ci#define HAVE_THREAD_TIME 14037db96d56Sopenharmony_cistatic int 14047db96d56Sopenharmony_ci_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) 14057db96d56Sopenharmony_ci{ 14067db96d56Sopenharmony_ci HANDLE thread; 14077db96d56Sopenharmony_ci FILETIME creation_time, exit_time, kernel_time, user_time; 14087db96d56Sopenharmony_ci ULARGE_INTEGER large; 14097db96d56Sopenharmony_ci _PyTime_t ktime, utime, t; 14107db96d56Sopenharmony_ci BOOL ok; 14117db96d56Sopenharmony_ci 14127db96d56Sopenharmony_ci thread = GetCurrentThread(); 14137db96d56Sopenharmony_ci ok = GetThreadTimes(thread, &creation_time, &exit_time, 14147db96d56Sopenharmony_ci &kernel_time, &user_time); 14157db96d56Sopenharmony_ci if (!ok) { 14167db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 14177db96d56Sopenharmony_ci return -1; 14187db96d56Sopenharmony_ci } 14197db96d56Sopenharmony_ci 14207db96d56Sopenharmony_ci if (info) { 14217db96d56Sopenharmony_ci info->implementation = "GetThreadTimes()"; 14227db96d56Sopenharmony_ci info->resolution = 1e-7; 14237db96d56Sopenharmony_ci info->monotonic = 1; 14247db96d56Sopenharmony_ci info->adjustable = 0; 14257db96d56Sopenharmony_ci } 14267db96d56Sopenharmony_ci 14277db96d56Sopenharmony_ci large.u.LowPart = kernel_time.dwLowDateTime; 14287db96d56Sopenharmony_ci large.u.HighPart = kernel_time.dwHighDateTime; 14297db96d56Sopenharmony_ci ktime = large.QuadPart; 14307db96d56Sopenharmony_ci 14317db96d56Sopenharmony_ci large.u.LowPart = user_time.dwLowDateTime; 14327db96d56Sopenharmony_ci large.u.HighPart = user_time.dwHighDateTime; 14337db96d56Sopenharmony_ci utime = large.QuadPart; 14347db96d56Sopenharmony_ci 14357db96d56Sopenharmony_ci /* ktime and utime have a resolution of 100 nanoseconds */ 14367db96d56Sopenharmony_ci t = _PyTime_FromNanoseconds((ktime + utime) * 100); 14377db96d56Sopenharmony_ci *tp = t; 14387db96d56Sopenharmony_ci return 0; 14397db96d56Sopenharmony_ci} 14407db96d56Sopenharmony_ci 14417db96d56Sopenharmony_ci#elif defined(_AIX) 14427db96d56Sopenharmony_ci#define HAVE_THREAD_TIME 14437db96d56Sopenharmony_cistatic int 14447db96d56Sopenharmony_ci_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) 14457db96d56Sopenharmony_ci{ 14467db96d56Sopenharmony_ci /* bpo-40192: On AIX, thread_cputime() is preferred: it has nanosecond 14477db96d56Sopenharmony_ci resolution, whereas clock_gettime(CLOCK_THREAD_CPUTIME_ID) 14487db96d56Sopenharmony_ci has a resolution of 10 ms. */ 14497db96d56Sopenharmony_ci thread_cputime_t tc; 14507db96d56Sopenharmony_ci if (thread_cputime(-1, &tc) != 0) { 14517db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 14527db96d56Sopenharmony_ci return -1; 14537db96d56Sopenharmony_ci } 14547db96d56Sopenharmony_ci 14557db96d56Sopenharmony_ci if (info) { 14567db96d56Sopenharmony_ci info->implementation = "thread_cputime()"; 14577db96d56Sopenharmony_ci info->monotonic = 1; 14587db96d56Sopenharmony_ci info->adjustable = 0; 14597db96d56Sopenharmony_ci info->resolution = 1e-9; 14607db96d56Sopenharmony_ci } 14617db96d56Sopenharmony_ci *tp = _PyTime_FromNanoseconds(tc.stime + tc.utime); 14627db96d56Sopenharmony_ci return 0; 14637db96d56Sopenharmony_ci} 14647db96d56Sopenharmony_ci 14657db96d56Sopenharmony_ci#elif defined(__sun) && defined(__SVR4) 14667db96d56Sopenharmony_ci#define HAVE_THREAD_TIME 14677db96d56Sopenharmony_cistatic int 14687db96d56Sopenharmony_ci_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) 14697db96d56Sopenharmony_ci{ 14707db96d56Sopenharmony_ci /* bpo-35455: On Solaris, CLOCK_THREAD_CPUTIME_ID clock is not always 14717db96d56Sopenharmony_ci available; use gethrvtime() to substitute this functionality. */ 14727db96d56Sopenharmony_ci if (info) { 14737db96d56Sopenharmony_ci info->implementation = "gethrvtime()"; 14747db96d56Sopenharmony_ci info->resolution = 1e-9; 14757db96d56Sopenharmony_ci info->monotonic = 1; 14767db96d56Sopenharmony_ci info->adjustable = 0; 14777db96d56Sopenharmony_ci } 14787db96d56Sopenharmony_ci *tp = _PyTime_FromNanoseconds(gethrvtime()); 14797db96d56Sopenharmony_ci return 0; 14807db96d56Sopenharmony_ci} 14817db96d56Sopenharmony_ci 14827db96d56Sopenharmony_ci#elif defined(HAVE_CLOCK_GETTIME) && \ 14837db96d56Sopenharmony_ci defined(CLOCK_PROCESS_CPUTIME_ID) && \ 14847db96d56Sopenharmony_ci !defined(__EMSCRIPTEN__) && !defined(__wasi__) 14857db96d56Sopenharmony_ci#define HAVE_THREAD_TIME 14867db96d56Sopenharmony_ci 14877db96d56Sopenharmony_ci#if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability) 14887db96d56Sopenharmony_cistatic int 14897db96d56Sopenharmony_ci_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) 14907db96d56Sopenharmony_ci __attribute__((availability(macos, introduced=10.12))) 14917db96d56Sopenharmony_ci __attribute__((availability(ios, introduced=10.0))) 14927db96d56Sopenharmony_ci __attribute__((availability(tvos, introduced=10.0))) 14937db96d56Sopenharmony_ci __attribute__((availability(watchos, introduced=3.0))); 14947db96d56Sopenharmony_ci#endif 14957db96d56Sopenharmony_ci 14967db96d56Sopenharmony_cistatic int 14977db96d56Sopenharmony_ci_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) 14987db96d56Sopenharmony_ci{ 14997db96d56Sopenharmony_ci struct timespec ts; 15007db96d56Sopenharmony_ci const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID; 15017db96d56Sopenharmony_ci const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)"; 15027db96d56Sopenharmony_ci 15037db96d56Sopenharmony_ci if (clock_gettime(clk_id, &ts)) { 15047db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 15057db96d56Sopenharmony_ci return -1; 15067db96d56Sopenharmony_ci } 15077db96d56Sopenharmony_ci if (info) { 15087db96d56Sopenharmony_ci struct timespec res; 15097db96d56Sopenharmony_ci info->implementation = function; 15107db96d56Sopenharmony_ci info->monotonic = 1; 15117db96d56Sopenharmony_ci info->adjustable = 0; 15127db96d56Sopenharmony_ci if (clock_getres(clk_id, &res)) { 15137db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 15147db96d56Sopenharmony_ci return -1; 15157db96d56Sopenharmony_ci } 15167db96d56Sopenharmony_ci info->resolution = res.tv_sec + res.tv_nsec * 1e-9; 15177db96d56Sopenharmony_ci } 15187db96d56Sopenharmony_ci 15197db96d56Sopenharmony_ci if (_PyTime_FromTimespec(tp, &ts) < 0) { 15207db96d56Sopenharmony_ci return -1; 15217db96d56Sopenharmony_ci } 15227db96d56Sopenharmony_ci return 0; 15237db96d56Sopenharmony_ci} 15247db96d56Sopenharmony_ci#endif 15257db96d56Sopenharmony_ci 15267db96d56Sopenharmony_ci#ifdef HAVE_THREAD_TIME 15277db96d56Sopenharmony_ci#ifdef __APPLE__ 15287db96d56Sopenharmony_ci/* 15297db96d56Sopenharmony_ci * The clock_* functions will be removed from the module 15307db96d56Sopenharmony_ci * dict entirely when the C API is not available. 15317db96d56Sopenharmony_ci */ 15327db96d56Sopenharmony_ci#pragma clang diagnostic push 15337db96d56Sopenharmony_ci#pragma clang diagnostic ignored "-Wunguarded-availability" 15347db96d56Sopenharmony_ci#endif 15357db96d56Sopenharmony_ci 15367db96d56Sopenharmony_cistatic PyObject * 15377db96d56Sopenharmony_citime_thread_time(PyObject *self, PyObject *unused) 15387db96d56Sopenharmony_ci{ 15397db96d56Sopenharmony_ci _PyTime_t t; 15407db96d56Sopenharmony_ci if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) { 15417db96d56Sopenharmony_ci return NULL; 15427db96d56Sopenharmony_ci } 15437db96d56Sopenharmony_ci return _PyFloat_FromPyTime(t); 15447db96d56Sopenharmony_ci} 15457db96d56Sopenharmony_ci 15467db96d56Sopenharmony_ciPyDoc_STRVAR(thread_time_doc, 15477db96d56Sopenharmony_ci"thread_time() -> float\n\ 15487db96d56Sopenharmony_ci\n\ 15497db96d56Sopenharmony_ciThread time for profiling: sum of the kernel and user-space CPU time."); 15507db96d56Sopenharmony_ci 15517db96d56Sopenharmony_cistatic PyObject * 15527db96d56Sopenharmony_citime_thread_time_ns(PyObject *self, PyObject *unused) 15537db96d56Sopenharmony_ci{ 15547db96d56Sopenharmony_ci _PyTime_t t; 15557db96d56Sopenharmony_ci if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) { 15567db96d56Sopenharmony_ci return NULL; 15577db96d56Sopenharmony_ci } 15587db96d56Sopenharmony_ci return _PyTime_AsNanosecondsObject(t); 15597db96d56Sopenharmony_ci} 15607db96d56Sopenharmony_ci 15617db96d56Sopenharmony_ciPyDoc_STRVAR(thread_time_ns_doc, 15627db96d56Sopenharmony_ci"thread_time() -> int\n\ 15637db96d56Sopenharmony_ci\n\ 15647db96d56Sopenharmony_ciThread time for profiling as nanoseconds:\n\ 15657db96d56Sopenharmony_cisum of the kernel and user-space CPU time."); 15667db96d56Sopenharmony_ci 15677db96d56Sopenharmony_ci#ifdef __APPLE__ 15687db96d56Sopenharmony_ci#pragma clang diagnostic pop 15697db96d56Sopenharmony_ci#endif 15707db96d56Sopenharmony_ci 15717db96d56Sopenharmony_ci#endif 15727db96d56Sopenharmony_ci 15737db96d56Sopenharmony_ci 15747db96d56Sopenharmony_cistatic PyObject * 15757db96d56Sopenharmony_citime_get_clock_info(PyObject *self, PyObject *args) 15767db96d56Sopenharmony_ci{ 15777db96d56Sopenharmony_ci char *name; 15787db96d56Sopenharmony_ci _Py_clock_info_t info; 15797db96d56Sopenharmony_ci PyObject *obj = NULL, *dict, *ns; 15807db96d56Sopenharmony_ci _PyTime_t t; 15817db96d56Sopenharmony_ci 15827db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) { 15837db96d56Sopenharmony_ci return NULL; 15847db96d56Sopenharmony_ci } 15857db96d56Sopenharmony_ci 15867db96d56Sopenharmony_ci#ifdef Py_DEBUG 15877db96d56Sopenharmony_ci info.implementation = NULL; 15887db96d56Sopenharmony_ci info.monotonic = -1; 15897db96d56Sopenharmony_ci info.adjustable = -1; 15907db96d56Sopenharmony_ci info.resolution = -1.0; 15917db96d56Sopenharmony_ci#else 15927db96d56Sopenharmony_ci info.implementation = ""; 15937db96d56Sopenharmony_ci info.monotonic = 0; 15947db96d56Sopenharmony_ci info.adjustable = 0; 15957db96d56Sopenharmony_ci info.resolution = 1.0; 15967db96d56Sopenharmony_ci#endif 15977db96d56Sopenharmony_ci 15987db96d56Sopenharmony_ci if (strcmp(name, "time") == 0) { 15997db96d56Sopenharmony_ci if (_PyTime_GetSystemClockWithInfo(&t, &info) < 0) { 16007db96d56Sopenharmony_ci return NULL; 16017db96d56Sopenharmony_ci } 16027db96d56Sopenharmony_ci } 16037db96d56Sopenharmony_ci else if (strcmp(name, "monotonic") == 0) { 16047db96d56Sopenharmony_ci if (_PyTime_GetMonotonicClockWithInfo(&t, &info) < 0) { 16057db96d56Sopenharmony_ci return NULL; 16067db96d56Sopenharmony_ci } 16077db96d56Sopenharmony_ci } 16087db96d56Sopenharmony_ci else if (strcmp(name, "perf_counter") == 0) { 16097db96d56Sopenharmony_ci if (_PyTime_GetPerfCounterWithInfo(&t, &info) < 0) { 16107db96d56Sopenharmony_ci return NULL; 16117db96d56Sopenharmony_ci } 16127db96d56Sopenharmony_ci } 16137db96d56Sopenharmony_ci else if (strcmp(name, "process_time") == 0) { 16147db96d56Sopenharmony_ci if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) { 16157db96d56Sopenharmony_ci return NULL; 16167db96d56Sopenharmony_ci } 16177db96d56Sopenharmony_ci } 16187db96d56Sopenharmony_ci#ifdef HAVE_THREAD_TIME 16197db96d56Sopenharmony_ci else if (strcmp(name, "thread_time") == 0) { 16207db96d56Sopenharmony_ci 16217db96d56Sopenharmony_ci#ifdef __APPLE__ 16227db96d56Sopenharmony_ci if (HAVE_CLOCK_GETTIME_RUNTIME) { 16237db96d56Sopenharmony_ci#endif 16247db96d56Sopenharmony_ci if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) { 16257db96d56Sopenharmony_ci return NULL; 16267db96d56Sopenharmony_ci } 16277db96d56Sopenharmony_ci#ifdef __APPLE__ 16287db96d56Sopenharmony_ci } else { 16297db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "unknown clock"); 16307db96d56Sopenharmony_ci return NULL; 16317db96d56Sopenharmony_ci } 16327db96d56Sopenharmony_ci#endif 16337db96d56Sopenharmony_ci } 16347db96d56Sopenharmony_ci#endif 16357db96d56Sopenharmony_ci else { 16367db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "unknown clock"); 16377db96d56Sopenharmony_ci return NULL; 16387db96d56Sopenharmony_ci } 16397db96d56Sopenharmony_ci 16407db96d56Sopenharmony_ci dict = PyDict_New(); 16417db96d56Sopenharmony_ci if (dict == NULL) { 16427db96d56Sopenharmony_ci return NULL; 16437db96d56Sopenharmony_ci } 16447db96d56Sopenharmony_ci 16457db96d56Sopenharmony_ci assert(info.implementation != NULL); 16467db96d56Sopenharmony_ci obj = PyUnicode_FromString(info.implementation); 16477db96d56Sopenharmony_ci if (obj == NULL) { 16487db96d56Sopenharmony_ci goto error; 16497db96d56Sopenharmony_ci } 16507db96d56Sopenharmony_ci if (PyDict_SetItemString(dict, "implementation", obj) == -1) { 16517db96d56Sopenharmony_ci goto error; 16527db96d56Sopenharmony_ci } 16537db96d56Sopenharmony_ci Py_CLEAR(obj); 16547db96d56Sopenharmony_ci 16557db96d56Sopenharmony_ci assert(info.monotonic != -1); 16567db96d56Sopenharmony_ci obj = PyBool_FromLong(info.monotonic); 16577db96d56Sopenharmony_ci if (obj == NULL) { 16587db96d56Sopenharmony_ci goto error; 16597db96d56Sopenharmony_ci } 16607db96d56Sopenharmony_ci if (PyDict_SetItemString(dict, "monotonic", obj) == -1) { 16617db96d56Sopenharmony_ci goto error; 16627db96d56Sopenharmony_ci } 16637db96d56Sopenharmony_ci Py_CLEAR(obj); 16647db96d56Sopenharmony_ci 16657db96d56Sopenharmony_ci assert(info.adjustable != -1); 16667db96d56Sopenharmony_ci obj = PyBool_FromLong(info.adjustable); 16677db96d56Sopenharmony_ci if (obj == NULL) { 16687db96d56Sopenharmony_ci goto error; 16697db96d56Sopenharmony_ci } 16707db96d56Sopenharmony_ci if (PyDict_SetItemString(dict, "adjustable", obj) == -1) { 16717db96d56Sopenharmony_ci goto error; 16727db96d56Sopenharmony_ci } 16737db96d56Sopenharmony_ci Py_CLEAR(obj); 16747db96d56Sopenharmony_ci 16757db96d56Sopenharmony_ci assert(info.resolution > 0.0); 16767db96d56Sopenharmony_ci assert(info.resolution <= 1.0); 16777db96d56Sopenharmony_ci obj = PyFloat_FromDouble(info.resolution); 16787db96d56Sopenharmony_ci if (obj == NULL) { 16797db96d56Sopenharmony_ci goto error; 16807db96d56Sopenharmony_ci } 16817db96d56Sopenharmony_ci if (PyDict_SetItemString(dict, "resolution", obj) == -1) { 16827db96d56Sopenharmony_ci goto error; 16837db96d56Sopenharmony_ci } 16847db96d56Sopenharmony_ci Py_CLEAR(obj); 16857db96d56Sopenharmony_ci 16867db96d56Sopenharmony_ci ns = _PyNamespace_New(dict); 16877db96d56Sopenharmony_ci Py_DECREF(dict); 16887db96d56Sopenharmony_ci return ns; 16897db96d56Sopenharmony_ci 16907db96d56Sopenharmony_cierror: 16917db96d56Sopenharmony_ci Py_DECREF(dict); 16927db96d56Sopenharmony_ci Py_XDECREF(obj); 16937db96d56Sopenharmony_ci return NULL; 16947db96d56Sopenharmony_ci} 16957db96d56Sopenharmony_ci 16967db96d56Sopenharmony_ciPyDoc_STRVAR(get_clock_info_doc, 16977db96d56Sopenharmony_ci"get_clock_info(name: str) -> dict\n\ 16987db96d56Sopenharmony_ci\n\ 16997db96d56Sopenharmony_ciGet information of the specified clock."); 17007db96d56Sopenharmony_ci 17017db96d56Sopenharmony_ci#ifndef HAVE_DECL_TZNAME 17027db96d56Sopenharmony_cistatic void 17037db96d56Sopenharmony_ciget_zone(char *zone, int n, struct tm *p) 17047db96d56Sopenharmony_ci{ 17057db96d56Sopenharmony_ci#ifdef HAVE_STRUCT_TM_TM_ZONE 17067db96d56Sopenharmony_ci strncpy(zone, p->tm_zone ? p->tm_zone : " ", n); 17077db96d56Sopenharmony_ci#else 17087db96d56Sopenharmony_ci tzset(); 17097db96d56Sopenharmony_ci strftime(zone, n, "%Z", p); 17107db96d56Sopenharmony_ci#endif 17117db96d56Sopenharmony_ci} 17127db96d56Sopenharmony_ci 17137db96d56Sopenharmony_cistatic time_t 17147db96d56Sopenharmony_ciget_gmtoff(time_t t, struct tm *p) 17157db96d56Sopenharmony_ci{ 17167db96d56Sopenharmony_ci#ifdef HAVE_STRUCT_TM_TM_ZONE 17177db96d56Sopenharmony_ci return p->tm_gmtoff; 17187db96d56Sopenharmony_ci#else 17197db96d56Sopenharmony_ci return timegm(p) - t; 17207db96d56Sopenharmony_ci#endif 17217db96d56Sopenharmony_ci} 17227db96d56Sopenharmony_ci#endif // !HAVE_DECL_TZNAME 17237db96d56Sopenharmony_ci 17247db96d56Sopenharmony_cistatic int 17257db96d56Sopenharmony_ciinit_timezone(PyObject *m) 17267db96d56Sopenharmony_ci{ 17277db96d56Sopenharmony_ci assert(!PyErr_Occurred()); 17287db96d56Sopenharmony_ci 17297db96d56Sopenharmony_ci /* This code moved from PyInit_time wholesale to allow calling it from 17307db96d56Sopenharmony_ci time_tzset. In the future, some parts of it can be moved back 17317db96d56Sopenharmony_ci (for platforms that don't HAVE_WORKING_TZSET, when we know what they 17327db96d56Sopenharmony_ci are), and the extraneous calls to tzset(3) should be removed. 17337db96d56Sopenharmony_ci I haven't done this yet, as I don't want to change this code as 17347db96d56Sopenharmony_ci little as possible when introducing the time.tzset and time.tzsetwall 17357db96d56Sopenharmony_ci methods. This should simply be a method of doing the following once, 17367db96d56Sopenharmony_ci at the top of this function and removing the call to tzset() from 17377db96d56Sopenharmony_ci time_tzset(): 17387db96d56Sopenharmony_ci 17397db96d56Sopenharmony_ci #ifdef HAVE_TZSET 17407db96d56Sopenharmony_ci tzset() 17417db96d56Sopenharmony_ci #endif 17427db96d56Sopenharmony_ci 17437db96d56Sopenharmony_ci And I'm lazy and hate C so nyer. 17447db96d56Sopenharmony_ci */ 17457db96d56Sopenharmony_ci#ifdef HAVE_DECL_TZNAME 17467db96d56Sopenharmony_ci PyObject *otz0, *otz1; 17477db96d56Sopenharmony_ci tzset(); 17487db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "timezone", _Py_timezone); 17497db96d56Sopenharmony_ci#ifdef HAVE_ALTZONE 17507db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "altzone", altzone); 17517db96d56Sopenharmony_ci#else 17527db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600); 17537db96d56Sopenharmony_ci#endif 17547db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "daylight", _Py_daylight); 17557db96d56Sopenharmony_ci#ifdef MS_WINDOWS 17567db96d56Sopenharmony_ci TIME_ZONE_INFORMATION tzinfo = {0}; 17577db96d56Sopenharmony_ci GetTimeZoneInformation(&tzinfo); 17587db96d56Sopenharmony_ci otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1); 17597db96d56Sopenharmony_ci if (otz0 == NULL) { 17607db96d56Sopenharmony_ci return -1; 17617db96d56Sopenharmony_ci } 17627db96d56Sopenharmony_ci otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1); 17637db96d56Sopenharmony_ci if (otz1 == NULL) { 17647db96d56Sopenharmony_ci Py_DECREF(otz0); 17657db96d56Sopenharmony_ci return -1; 17667db96d56Sopenharmony_ci } 17677db96d56Sopenharmony_ci#else 17687db96d56Sopenharmony_ci otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape"); 17697db96d56Sopenharmony_ci if (otz0 == NULL) { 17707db96d56Sopenharmony_ci return -1; 17717db96d56Sopenharmony_ci } 17727db96d56Sopenharmony_ci otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape"); 17737db96d56Sopenharmony_ci if (otz1 == NULL) { 17747db96d56Sopenharmony_ci Py_DECREF(otz0); 17757db96d56Sopenharmony_ci return -1; 17767db96d56Sopenharmony_ci } 17777db96d56Sopenharmony_ci#endif // MS_WINDOWS 17787db96d56Sopenharmony_ci PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1); 17797db96d56Sopenharmony_ci if (tzname_obj == NULL) { 17807db96d56Sopenharmony_ci return -1; 17817db96d56Sopenharmony_ci } 17827db96d56Sopenharmony_ci PyModule_AddObject(m, "tzname", tzname_obj); 17837db96d56Sopenharmony_ci#else // !HAVE_DECL_TZNAME 17847db96d56Sopenharmony_ci static const time_t YEAR = (365 * 24 + 6) * 3600; 17857db96d56Sopenharmony_ci time_t t; 17867db96d56Sopenharmony_ci struct tm p; 17877db96d56Sopenharmony_ci time_t janzone_t, julyzone_t; 17887db96d56Sopenharmony_ci char janname[10], julyname[10]; 17897db96d56Sopenharmony_ci t = (time((time_t *)0) / YEAR) * YEAR; 17907db96d56Sopenharmony_ci _PyTime_localtime(t, &p); 17917db96d56Sopenharmony_ci get_zone(janname, 9, &p); 17927db96d56Sopenharmony_ci janzone_t = -get_gmtoff(t, &p); 17937db96d56Sopenharmony_ci janname[9] = '\0'; 17947db96d56Sopenharmony_ci t += YEAR/2; 17957db96d56Sopenharmony_ci _PyTime_localtime(t, &p); 17967db96d56Sopenharmony_ci get_zone(julyname, 9, &p); 17977db96d56Sopenharmony_ci julyzone_t = -get_gmtoff(t, &p); 17987db96d56Sopenharmony_ci julyname[9] = '\0'; 17997db96d56Sopenharmony_ci 18007db96d56Sopenharmony_ci /* Sanity check, don't check for the validity of timezones. 18017db96d56Sopenharmony_ci In practice, it should be more in range -12 hours .. +14 hours. */ 18027db96d56Sopenharmony_ci#define MAX_TIMEZONE (48 * 3600) 18037db96d56Sopenharmony_ci if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE 18047db96d56Sopenharmony_ci || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE) 18057db96d56Sopenharmony_ci { 18067db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset"); 18077db96d56Sopenharmony_ci return -1; 18087db96d56Sopenharmony_ci } 18097db96d56Sopenharmony_ci int janzone = (int)janzone_t; 18107db96d56Sopenharmony_ci int julyzone = (int)julyzone_t; 18117db96d56Sopenharmony_ci 18127db96d56Sopenharmony_ci PyObject *tzname_obj; 18137db96d56Sopenharmony_ci if (janzone < julyzone) { 18147db96d56Sopenharmony_ci /* DST is reversed in the southern hemisphere */ 18157db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "timezone", julyzone); 18167db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "altzone", janzone); 18177db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "daylight", janzone != julyzone); 18187db96d56Sopenharmony_ci tzname_obj = Py_BuildValue("(zz)", julyname, janname); 18197db96d56Sopenharmony_ci } else { 18207db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "timezone", janzone); 18217db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "altzone", julyzone); 18227db96d56Sopenharmony_ci PyModule_AddIntConstant(m, "daylight", janzone != julyzone); 18237db96d56Sopenharmony_ci tzname_obj = Py_BuildValue("(zz)", janname, julyname); 18247db96d56Sopenharmony_ci } 18257db96d56Sopenharmony_ci if (tzname_obj == NULL) { 18267db96d56Sopenharmony_ci return -1; 18277db96d56Sopenharmony_ci } 18287db96d56Sopenharmony_ci PyModule_AddObject(m, "tzname", tzname_obj); 18297db96d56Sopenharmony_ci#endif // !HAVE_DECL_TZNAME 18307db96d56Sopenharmony_ci 18317db96d56Sopenharmony_ci if (PyErr_Occurred()) { 18327db96d56Sopenharmony_ci return -1; 18337db96d56Sopenharmony_ci } 18347db96d56Sopenharmony_ci return 0; 18357db96d56Sopenharmony_ci} 18367db96d56Sopenharmony_ci 18377db96d56Sopenharmony_ci 18387db96d56Sopenharmony_cistatic PyMethodDef time_methods[] = { 18397db96d56Sopenharmony_ci {"time", time_time, METH_NOARGS, time_doc}, 18407db96d56Sopenharmony_ci {"time_ns", time_time_ns, METH_NOARGS, time_ns_doc}, 18417db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_GETTIME 18427db96d56Sopenharmony_ci {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, 18437db96d56Sopenharmony_ci {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc}, 18447db96d56Sopenharmony_ci#endif 18457db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_SETTIME 18467db96d56Sopenharmony_ci {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, 18477db96d56Sopenharmony_ci {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc}, 18487db96d56Sopenharmony_ci#endif 18497db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_GETRES 18507db96d56Sopenharmony_ci {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc}, 18517db96d56Sopenharmony_ci#endif 18527db96d56Sopenharmony_ci#ifdef HAVE_PTHREAD_GETCPUCLOCKID 18537db96d56Sopenharmony_ci {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc}, 18547db96d56Sopenharmony_ci#endif 18557db96d56Sopenharmony_ci {"sleep", time_sleep, METH_O, sleep_doc}, 18567db96d56Sopenharmony_ci {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, 18577db96d56Sopenharmony_ci {"localtime", time_localtime, METH_VARARGS, localtime_doc}, 18587db96d56Sopenharmony_ci {"asctime", time_asctime, METH_VARARGS, asctime_doc}, 18597db96d56Sopenharmony_ci {"ctime", time_ctime, METH_VARARGS, ctime_doc}, 18607db96d56Sopenharmony_ci#ifdef HAVE_MKTIME 18617db96d56Sopenharmony_ci {"mktime", time_mktime, METH_O, mktime_doc}, 18627db96d56Sopenharmony_ci#endif 18637db96d56Sopenharmony_ci#ifdef HAVE_STRFTIME 18647db96d56Sopenharmony_ci {"strftime", time_strftime, METH_VARARGS, strftime_doc}, 18657db96d56Sopenharmony_ci#endif 18667db96d56Sopenharmony_ci {"strptime", time_strptime, METH_VARARGS, strptime_doc}, 18677db96d56Sopenharmony_ci#ifdef HAVE_WORKING_TZSET 18687db96d56Sopenharmony_ci {"tzset", time_tzset, METH_NOARGS, tzset_doc}, 18697db96d56Sopenharmony_ci#endif 18707db96d56Sopenharmony_ci {"monotonic", time_monotonic, METH_NOARGS, monotonic_doc}, 18717db96d56Sopenharmony_ci {"monotonic_ns", time_monotonic_ns, METH_NOARGS, monotonic_ns_doc}, 18727db96d56Sopenharmony_ci {"process_time", time_process_time, METH_NOARGS, process_time_doc}, 18737db96d56Sopenharmony_ci {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc}, 18747db96d56Sopenharmony_ci#ifdef HAVE_THREAD_TIME 18757db96d56Sopenharmony_ci {"thread_time", time_thread_time, METH_NOARGS, thread_time_doc}, 18767db96d56Sopenharmony_ci {"thread_time_ns", time_thread_time_ns, METH_NOARGS, thread_time_ns_doc}, 18777db96d56Sopenharmony_ci#endif 18787db96d56Sopenharmony_ci {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, 18797db96d56Sopenharmony_ci {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc}, 18807db96d56Sopenharmony_ci {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, 18817db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 18827db96d56Sopenharmony_ci}; 18837db96d56Sopenharmony_ci 18847db96d56Sopenharmony_ci 18857db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc, 18867db96d56Sopenharmony_ci"This module provides various functions to manipulate time values.\n\ 18877db96d56Sopenharmony_ci\n\ 18887db96d56Sopenharmony_ciThere are two standard representations of time. One is the number\n\ 18897db96d56Sopenharmony_ciof seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\ 18907db96d56Sopenharmony_cior a floating point number (to represent fractions of seconds).\n\ 18917db96d56Sopenharmony_ciThe Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\ 18927db96d56Sopenharmony_ciThe actual value can be retrieved by calling gmtime(0).\n\ 18937db96d56Sopenharmony_ci\n\ 18947db96d56Sopenharmony_ciThe other representation is a tuple of 9 integers giving local time.\n\ 18957db96d56Sopenharmony_ciThe tuple items are:\n\ 18967db96d56Sopenharmony_ci year (including century, e.g. 1998)\n\ 18977db96d56Sopenharmony_ci month (1-12)\n\ 18987db96d56Sopenharmony_ci day (1-31)\n\ 18997db96d56Sopenharmony_ci hours (0-23)\n\ 19007db96d56Sopenharmony_ci minutes (0-59)\n\ 19017db96d56Sopenharmony_ci seconds (0-59)\n\ 19027db96d56Sopenharmony_ci weekday (0-6, Monday is 0)\n\ 19037db96d56Sopenharmony_ci Julian day (day in the year, 1-366)\n\ 19047db96d56Sopenharmony_ci DST (Daylight Savings Time) flag (-1, 0 or 1)\n\ 19057db96d56Sopenharmony_ciIf the DST flag is 0, the time is given in the regular time zone;\n\ 19067db96d56Sopenharmony_ciif it is 1, the time is given in the DST time zone;\n\ 19077db96d56Sopenharmony_ciif it is -1, mktime() should guess based on the date and time.\n"); 19087db96d56Sopenharmony_ci 19097db96d56Sopenharmony_ci 19107db96d56Sopenharmony_cistatic int 19117db96d56Sopenharmony_citime_exec(PyObject *module) 19127db96d56Sopenharmony_ci{ 19137db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 19147db96d56Sopenharmony_ci#if defined(__APPLE__) && defined(HAVE_CLOCK_GETTIME) 19157db96d56Sopenharmony_ci if (HAVE_CLOCK_GETTIME_RUNTIME) { 19167db96d56Sopenharmony_ci /* pass: ^^^ cannot use '!' here */ 19177db96d56Sopenharmony_ci } else { 19187db96d56Sopenharmony_ci PyObject* dct = PyModule_GetDict(module); 19197db96d56Sopenharmony_ci if (dct == NULL) { 19207db96d56Sopenharmony_ci return -1; 19217db96d56Sopenharmony_ci } 19227db96d56Sopenharmony_ci 19237db96d56Sopenharmony_ci if (PyDict_DelItemString(dct, "clock_gettime") == -1) { 19247db96d56Sopenharmony_ci PyErr_Clear(); 19257db96d56Sopenharmony_ci } 19267db96d56Sopenharmony_ci if (PyDict_DelItemString(dct, "clock_gettime_ns") == -1) { 19277db96d56Sopenharmony_ci PyErr_Clear(); 19287db96d56Sopenharmony_ci } 19297db96d56Sopenharmony_ci if (PyDict_DelItemString(dct, "clock_settime") == -1) { 19307db96d56Sopenharmony_ci PyErr_Clear(); 19317db96d56Sopenharmony_ci } 19327db96d56Sopenharmony_ci if (PyDict_DelItemString(dct, "clock_settime_ns") == -1) { 19337db96d56Sopenharmony_ci PyErr_Clear(); 19347db96d56Sopenharmony_ci } 19357db96d56Sopenharmony_ci if (PyDict_DelItemString(dct, "clock_getres") == -1) { 19367db96d56Sopenharmony_ci PyErr_Clear(); 19377db96d56Sopenharmony_ci } 19387db96d56Sopenharmony_ci } 19397db96d56Sopenharmony_ci#endif 19407db96d56Sopenharmony_ci#if defined(__APPLE__) && defined(HAVE_THREAD_TIME) 19417db96d56Sopenharmony_ci if (HAVE_CLOCK_GETTIME_RUNTIME) { 19427db96d56Sopenharmony_ci /* pass: ^^^ cannot use '!' here */ 19437db96d56Sopenharmony_ci } else { 19447db96d56Sopenharmony_ci PyObject* dct = PyModule_GetDict(module); 19457db96d56Sopenharmony_ci 19467db96d56Sopenharmony_ci if (PyDict_DelItemString(dct, "thread_time") == -1) { 19477db96d56Sopenharmony_ci PyErr_Clear(); 19487db96d56Sopenharmony_ci } 19497db96d56Sopenharmony_ci if (PyDict_DelItemString(dct, "thread_time_ns") == -1) { 19507db96d56Sopenharmony_ci PyErr_Clear(); 19517db96d56Sopenharmony_ci } 19527db96d56Sopenharmony_ci } 19537db96d56Sopenharmony_ci#endif 19547db96d56Sopenharmony_ci /* Set, or reset, module variables like time.timezone */ 19557db96d56Sopenharmony_ci if (init_timezone(module) < 0) { 19567db96d56Sopenharmony_ci return -1; 19577db96d56Sopenharmony_ci } 19587db96d56Sopenharmony_ci 19597db96d56Sopenharmony_ci#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) 19607db96d56Sopenharmony_ci if (HAVE_CLOCK_GETTIME_RUNTIME) { 19617db96d56Sopenharmony_ci 19627db96d56Sopenharmony_ci#ifdef CLOCK_REALTIME 19637db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_REALTIME) < 0) { 19647db96d56Sopenharmony_ci return -1; 19657db96d56Sopenharmony_ci } 19667db96d56Sopenharmony_ci#endif 19677db96d56Sopenharmony_ci 19687db96d56Sopenharmony_ci#ifdef CLOCK_MONOTONIC 19697db96d56Sopenharmony_ci 19707db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC) < 0) { 19717db96d56Sopenharmony_ci return -1; 19727db96d56Sopenharmony_ci } 19737db96d56Sopenharmony_ci 19747db96d56Sopenharmony_ci#endif 19757db96d56Sopenharmony_ci#ifdef CLOCK_MONOTONIC_RAW 19767db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW) < 0) { 19777db96d56Sopenharmony_ci return -1; 19787db96d56Sopenharmony_ci } 19797db96d56Sopenharmony_ci#endif 19807db96d56Sopenharmony_ci 19817db96d56Sopenharmony_ci#ifdef CLOCK_HIGHRES 19827db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_HIGHRES) < 0) { 19837db96d56Sopenharmony_ci return -1; 19847db96d56Sopenharmony_ci } 19857db96d56Sopenharmony_ci#endif 19867db96d56Sopenharmony_ci#ifdef CLOCK_PROCESS_CPUTIME_ID 19877db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_PROCESS_CPUTIME_ID) < 0) { 19887db96d56Sopenharmony_ci return -1; 19897db96d56Sopenharmony_ci } 19907db96d56Sopenharmony_ci#endif 19917db96d56Sopenharmony_ci 19927db96d56Sopenharmony_ci#ifdef CLOCK_THREAD_CPUTIME_ID 19937db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_THREAD_CPUTIME_ID) < 0) { 19947db96d56Sopenharmony_ci return -1; 19957db96d56Sopenharmony_ci } 19967db96d56Sopenharmony_ci#endif 19977db96d56Sopenharmony_ci#ifdef CLOCK_PROF 19987db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_PROF) < 0) { 19997db96d56Sopenharmony_ci return -1; 20007db96d56Sopenharmony_ci } 20017db96d56Sopenharmony_ci#endif 20027db96d56Sopenharmony_ci#ifdef CLOCK_BOOTTIME 20037db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_BOOTTIME) < 0) { 20047db96d56Sopenharmony_ci return -1; 20057db96d56Sopenharmony_ci } 20067db96d56Sopenharmony_ci#endif 20077db96d56Sopenharmony_ci#ifdef CLOCK_TAI 20087db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_TAI) < 0) { 20097db96d56Sopenharmony_ci return -1; 20107db96d56Sopenharmony_ci } 20117db96d56Sopenharmony_ci#endif 20127db96d56Sopenharmony_ci#ifdef CLOCK_UPTIME 20137db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_UPTIME) < 0) { 20147db96d56Sopenharmony_ci return -1; 20157db96d56Sopenharmony_ci } 20167db96d56Sopenharmony_ci#endif 20177db96d56Sopenharmony_ci#ifdef CLOCK_UPTIME_RAW 20187db96d56Sopenharmony_ci 20197db96d56Sopenharmony_ci if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW) < 0) { 20207db96d56Sopenharmony_ci return -1; 20217db96d56Sopenharmony_ci } 20227db96d56Sopenharmony_ci#endif 20237db96d56Sopenharmony_ci } 20247db96d56Sopenharmony_ci 20257db96d56Sopenharmony_ci#endif /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */ 20267db96d56Sopenharmony_ci 20277db96d56Sopenharmony_ci if (PyModule_AddIntConstant(module, "_STRUCT_TM_ITEMS", 11)) { 20287db96d56Sopenharmony_ci return -1; 20297db96d56Sopenharmony_ci } 20307db96d56Sopenharmony_ci 20317db96d56Sopenharmony_ci // struct_time type 20327db96d56Sopenharmony_ci state->struct_time_type = PyStructSequence_NewType(&struct_time_type_desc); 20337db96d56Sopenharmony_ci if (state->struct_time_type == NULL) { 20347db96d56Sopenharmony_ci return -1; 20357db96d56Sopenharmony_ci } 20367db96d56Sopenharmony_ci if (PyModule_AddType(module, state->struct_time_type)) { 20377db96d56Sopenharmony_ci return -1; 20387db96d56Sopenharmony_ci } 20397db96d56Sopenharmony_ci 20407db96d56Sopenharmony_ci#if defined(__linux__) && !defined(__GLIBC__) 20417db96d56Sopenharmony_ci struct tm tm; 20427db96d56Sopenharmony_ci const time_t zero = 0; 20437db96d56Sopenharmony_ci if (gmtime_r(&zero, &tm) != NULL) 20447db96d56Sopenharmony_ci utc_string = tm.tm_zone; 20457db96d56Sopenharmony_ci#endif 20467db96d56Sopenharmony_ci 20477db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 20487db96d56Sopenharmony_ci if (timer_flags == (DWORD)-1) { 20497db96d56Sopenharmony_ci DWORD test_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION; 20507db96d56Sopenharmony_ci HANDLE timer = CreateWaitableTimerExW(NULL, NULL, test_flags, 20517db96d56Sopenharmony_ci TIMER_ALL_ACCESS); 20527db96d56Sopenharmony_ci if (timer == NULL) { 20537db96d56Sopenharmony_ci // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is not supported. 20547db96d56Sopenharmony_ci timer_flags = 0; 20557db96d56Sopenharmony_ci } 20567db96d56Sopenharmony_ci else { 20577db96d56Sopenharmony_ci // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is supported. 20587db96d56Sopenharmony_ci timer_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION; 20597db96d56Sopenharmony_ci CloseHandle(timer); 20607db96d56Sopenharmony_ci } 20617db96d56Sopenharmony_ci } 20627db96d56Sopenharmony_ci#endif 20637db96d56Sopenharmony_ci 20647db96d56Sopenharmony_ci return 0; 20657db96d56Sopenharmony_ci} 20667db96d56Sopenharmony_ci 20677db96d56Sopenharmony_ci 20687db96d56Sopenharmony_cistatic int 20697db96d56Sopenharmony_citime_module_traverse(PyObject *module, visitproc visit, void *arg) 20707db96d56Sopenharmony_ci{ 20717db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 20727db96d56Sopenharmony_ci Py_VISIT(state->struct_time_type); 20737db96d56Sopenharmony_ci return 0; 20747db96d56Sopenharmony_ci} 20757db96d56Sopenharmony_ci 20767db96d56Sopenharmony_ci 20777db96d56Sopenharmony_cistatic int 20787db96d56Sopenharmony_citime_module_clear(PyObject *module) 20797db96d56Sopenharmony_ci{ 20807db96d56Sopenharmony_ci time_module_state *state = get_time_state(module); 20817db96d56Sopenharmony_ci Py_CLEAR(state->struct_time_type); 20827db96d56Sopenharmony_ci return 0; 20837db96d56Sopenharmony_ci} 20847db96d56Sopenharmony_ci 20857db96d56Sopenharmony_ci 20867db96d56Sopenharmony_cistatic void 20877db96d56Sopenharmony_citime_module_free(void *module) 20887db96d56Sopenharmony_ci{ 20897db96d56Sopenharmony_ci time_module_clear((PyObject *)module); 20907db96d56Sopenharmony_ci} 20917db96d56Sopenharmony_ci 20927db96d56Sopenharmony_ci 20937db96d56Sopenharmony_cistatic struct PyModuleDef_Slot time_slots[] = { 20947db96d56Sopenharmony_ci {Py_mod_exec, time_exec}, 20957db96d56Sopenharmony_ci {0, NULL} 20967db96d56Sopenharmony_ci}; 20977db96d56Sopenharmony_ci 20987db96d56Sopenharmony_cistatic struct PyModuleDef timemodule = { 20997db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 21007db96d56Sopenharmony_ci .m_name = "time", 21017db96d56Sopenharmony_ci .m_doc = module_doc, 21027db96d56Sopenharmony_ci .m_size = sizeof(time_module_state), 21037db96d56Sopenharmony_ci .m_methods = time_methods, 21047db96d56Sopenharmony_ci .m_slots = time_slots, 21057db96d56Sopenharmony_ci .m_traverse = time_module_traverse, 21067db96d56Sopenharmony_ci .m_clear = time_module_clear, 21077db96d56Sopenharmony_ci .m_free = time_module_free, 21087db96d56Sopenharmony_ci}; 21097db96d56Sopenharmony_ci 21107db96d56Sopenharmony_ciPyMODINIT_FUNC 21117db96d56Sopenharmony_ciPyInit_time(void) 21127db96d56Sopenharmony_ci{ 21137db96d56Sopenharmony_ci return PyModuleDef_Init(&timemodule); 21147db96d56Sopenharmony_ci} 21157db96d56Sopenharmony_ci 21167db96d56Sopenharmony_ci 21177db96d56Sopenharmony_ci// time.sleep() implementation. 21187db96d56Sopenharmony_ci// On error, raise an exception and return -1. 21197db96d56Sopenharmony_ci// On success, return 0. 21207db96d56Sopenharmony_cistatic int 21217db96d56Sopenharmony_cipysleep(_PyTime_t timeout) 21227db96d56Sopenharmony_ci{ 21237db96d56Sopenharmony_ci assert(timeout >= 0); 21247db96d56Sopenharmony_ci 21257db96d56Sopenharmony_ci#ifndef MS_WINDOWS 21267db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_NANOSLEEP 21277db96d56Sopenharmony_ci struct timespec timeout_abs; 21287db96d56Sopenharmony_ci#elif defined(HAVE_NANOSLEEP) 21297db96d56Sopenharmony_ci struct timespec timeout_ts; 21307db96d56Sopenharmony_ci#else 21317db96d56Sopenharmony_ci struct timeval timeout_tv; 21327db96d56Sopenharmony_ci#endif 21337db96d56Sopenharmony_ci _PyTime_t deadline, monotonic; 21347db96d56Sopenharmony_ci int err = 0; 21357db96d56Sopenharmony_ci 21367db96d56Sopenharmony_ci if (get_monotonic(&monotonic) < 0) { 21377db96d56Sopenharmony_ci return -1; 21387db96d56Sopenharmony_ci } 21397db96d56Sopenharmony_ci deadline = monotonic + timeout; 21407db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_NANOSLEEP 21417db96d56Sopenharmony_ci if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) { 21427db96d56Sopenharmony_ci return -1; 21437db96d56Sopenharmony_ci } 21447db96d56Sopenharmony_ci#endif 21457db96d56Sopenharmony_ci 21467db96d56Sopenharmony_ci do { 21477db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_NANOSLEEP 21487db96d56Sopenharmony_ci // use timeout_abs 21497db96d56Sopenharmony_ci#elif defined(HAVE_NANOSLEEP) 21507db96d56Sopenharmony_ci if (_PyTime_AsTimespec(timeout, &timeout_ts) < 0) { 21517db96d56Sopenharmony_ci return -1; 21527db96d56Sopenharmony_ci } 21537db96d56Sopenharmony_ci#else 21547db96d56Sopenharmony_ci if (_PyTime_AsTimeval(timeout, &timeout_tv, _PyTime_ROUND_CEILING) < 0) { 21557db96d56Sopenharmony_ci return -1; 21567db96d56Sopenharmony_ci } 21577db96d56Sopenharmony_ci#endif 21587db96d56Sopenharmony_ci 21597db96d56Sopenharmony_ci int ret; 21607db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 21617db96d56Sopenharmony_ci#ifdef HAVE_CLOCK_NANOSLEEP 21627db96d56Sopenharmony_ci ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL); 21637db96d56Sopenharmony_ci err = ret; 21647db96d56Sopenharmony_ci#elif defined(HAVE_NANOSLEEP) 21657db96d56Sopenharmony_ci ret = nanosleep(&timeout_ts, NULL); 21667db96d56Sopenharmony_ci err = errno; 21677db96d56Sopenharmony_ci#else 21687db96d56Sopenharmony_ci ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout_tv); 21697db96d56Sopenharmony_ci err = errno; 21707db96d56Sopenharmony_ci#endif 21717db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 21727db96d56Sopenharmony_ci 21737db96d56Sopenharmony_ci if (ret == 0) { 21747db96d56Sopenharmony_ci break; 21757db96d56Sopenharmony_ci } 21767db96d56Sopenharmony_ci 21777db96d56Sopenharmony_ci if (err != EINTR) { 21787db96d56Sopenharmony_ci errno = err; 21797db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 21807db96d56Sopenharmony_ci return -1; 21817db96d56Sopenharmony_ci } 21827db96d56Sopenharmony_ci 21837db96d56Sopenharmony_ci /* sleep was interrupted by SIGINT */ 21847db96d56Sopenharmony_ci if (PyErr_CheckSignals()) { 21857db96d56Sopenharmony_ci return -1; 21867db96d56Sopenharmony_ci } 21877db96d56Sopenharmony_ci 21887db96d56Sopenharmony_ci#ifndef HAVE_CLOCK_NANOSLEEP 21897db96d56Sopenharmony_ci if (get_monotonic(&monotonic) < 0) { 21907db96d56Sopenharmony_ci return -1; 21917db96d56Sopenharmony_ci } 21927db96d56Sopenharmony_ci timeout = deadline - monotonic; 21937db96d56Sopenharmony_ci if (timeout < 0) { 21947db96d56Sopenharmony_ci break; 21957db96d56Sopenharmony_ci } 21967db96d56Sopenharmony_ci /* retry with the recomputed delay */ 21977db96d56Sopenharmony_ci#endif 21987db96d56Sopenharmony_ci } while (1); 21997db96d56Sopenharmony_ci 22007db96d56Sopenharmony_ci return 0; 22017db96d56Sopenharmony_ci#else // MS_WINDOWS 22027db96d56Sopenharmony_ci _PyTime_t timeout_100ns = _PyTime_As100Nanoseconds(timeout, 22037db96d56Sopenharmony_ci _PyTime_ROUND_CEILING); 22047db96d56Sopenharmony_ci 22057db96d56Sopenharmony_ci // Maintain Windows Sleep() semantics for time.sleep(0) 22067db96d56Sopenharmony_ci if (timeout_100ns == 0) { 22077db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 22087db96d56Sopenharmony_ci // A value of zero causes the thread to relinquish the remainder of its 22097db96d56Sopenharmony_ci // time slice to any other thread that is ready to run. If there are no 22107db96d56Sopenharmony_ci // other threads ready to run, the function returns immediately, and 22117db96d56Sopenharmony_ci // the thread continues execution. 22127db96d56Sopenharmony_ci Sleep(0); 22137db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 22147db96d56Sopenharmony_ci return 0; 22157db96d56Sopenharmony_ci } 22167db96d56Sopenharmony_ci 22177db96d56Sopenharmony_ci LARGE_INTEGER relative_timeout; 22187db96d56Sopenharmony_ci // No need to check for integer overflow, both types are signed 22197db96d56Sopenharmony_ci assert(sizeof(relative_timeout) == sizeof(timeout_100ns)); 22207db96d56Sopenharmony_ci // SetWaitableTimer(): a negative due time indicates relative time 22217db96d56Sopenharmony_ci relative_timeout.QuadPart = -timeout_100ns; 22227db96d56Sopenharmony_ci 22237db96d56Sopenharmony_ci HANDLE timer = CreateWaitableTimerExW(NULL, NULL, timer_flags, 22247db96d56Sopenharmony_ci TIMER_ALL_ACCESS); 22257db96d56Sopenharmony_ci if (timer == NULL) { 22267db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 22277db96d56Sopenharmony_ci return -1; 22287db96d56Sopenharmony_ci } 22297db96d56Sopenharmony_ci 22307db96d56Sopenharmony_ci if (!SetWaitableTimerEx(timer, &relative_timeout, 22317db96d56Sopenharmony_ci 0, // no period; the timer is signaled once 22327db96d56Sopenharmony_ci NULL, NULL, // no completion routine 22337db96d56Sopenharmony_ci NULL, // no wake context; do not resume from suspend 22347db96d56Sopenharmony_ci 0)) // no tolerable delay for timer coalescing 22357db96d56Sopenharmony_ci { 22367db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 22377db96d56Sopenharmony_ci goto error; 22387db96d56Sopenharmony_ci } 22397db96d56Sopenharmony_ci 22407db96d56Sopenharmony_ci // Only the main thread can be interrupted by SIGINT. 22417db96d56Sopenharmony_ci // Signal handlers are only executed in the main thread. 22427db96d56Sopenharmony_ci if (_PyOS_IsMainThread()) { 22437db96d56Sopenharmony_ci HANDLE sigint_event = _PyOS_SigintEvent(); 22447db96d56Sopenharmony_ci 22457db96d56Sopenharmony_ci while (1) { 22467db96d56Sopenharmony_ci // Check for pending SIGINT signal before resetting the event 22477db96d56Sopenharmony_ci if (PyErr_CheckSignals()) { 22487db96d56Sopenharmony_ci goto error; 22497db96d56Sopenharmony_ci } 22507db96d56Sopenharmony_ci ResetEvent(sigint_event); 22517db96d56Sopenharmony_ci 22527db96d56Sopenharmony_ci HANDLE events[] = {timer, sigint_event}; 22537db96d56Sopenharmony_ci DWORD rc; 22547db96d56Sopenharmony_ci 22557db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 22567db96d56Sopenharmony_ci rc = WaitForMultipleObjects(Py_ARRAY_LENGTH(events), events, 22577db96d56Sopenharmony_ci // bWaitAll 22587db96d56Sopenharmony_ci FALSE, 22597db96d56Sopenharmony_ci // No wait timeout 22607db96d56Sopenharmony_ci INFINITE); 22617db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 22627db96d56Sopenharmony_ci 22637db96d56Sopenharmony_ci if (rc == WAIT_FAILED) { 22647db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 22657db96d56Sopenharmony_ci goto error; 22667db96d56Sopenharmony_ci } 22677db96d56Sopenharmony_ci 22687db96d56Sopenharmony_ci if (rc == WAIT_OBJECT_0) { 22697db96d56Sopenharmony_ci // Timer signaled: we are done 22707db96d56Sopenharmony_ci break; 22717db96d56Sopenharmony_ci } 22727db96d56Sopenharmony_ci 22737db96d56Sopenharmony_ci assert(rc == (WAIT_OBJECT_0 + 1)); 22747db96d56Sopenharmony_ci // The sleep was interrupted by SIGINT: restart sleeping 22757db96d56Sopenharmony_ci } 22767db96d56Sopenharmony_ci } 22777db96d56Sopenharmony_ci else { 22787db96d56Sopenharmony_ci DWORD rc; 22797db96d56Sopenharmony_ci 22807db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 22817db96d56Sopenharmony_ci rc = WaitForSingleObject(timer, INFINITE); 22827db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 22837db96d56Sopenharmony_ci 22847db96d56Sopenharmony_ci if (rc == WAIT_FAILED) { 22857db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 22867db96d56Sopenharmony_ci goto error; 22877db96d56Sopenharmony_ci } 22887db96d56Sopenharmony_ci 22897db96d56Sopenharmony_ci assert(rc == WAIT_OBJECT_0); 22907db96d56Sopenharmony_ci // Timer signaled: we are done 22917db96d56Sopenharmony_ci } 22927db96d56Sopenharmony_ci 22937db96d56Sopenharmony_ci CloseHandle(timer); 22947db96d56Sopenharmony_ci return 0; 22957db96d56Sopenharmony_ci 22967db96d56Sopenharmony_cierror: 22977db96d56Sopenharmony_ci CloseHandle(timer); 22987db96d56Sopenharmony_ci return -1; 22997db96d56Sopenharmony_ci#endif 23007db96d56Sopenharmony_ci} 2301