| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #define _XOPEN_SOURCE 700
- #include <time.h>
- #undef _XOPEN_SOURCE
- #include "pocketpy/pocketpy.h"
- #include "pocketpy/common/threads.h"
- #include <assert.h>
- #define NANOS_PER_SEC 1000000000
- #ifndef __circle__
- int64_t time_ns() {
- struct timespec tms;
- #ifdef CLOCK_REALTIME
- clock_gettime(CLOCK_REALTIME, &tms);
- #else
- /* The C11 way */
- timespec_get(&tms, TIME_UTC);
- #endif
- /* seconds, multiplied with 1 billion */
- int64_t nanos = tms.tv_sec * (int64_t)NANOS_PER_SEC;
- /* Add full nanoseconds */
- nanos += tms.tv_nsec;
- return nanos;
- }
- #else
- int64_t time_ns() { return 0; }
- #endif
- static bool time_time(int argc, py_Ref argv) {
- PY_CHECK_ARGC(0);
- int64_t nanos = time_ns();
- py_newfloat(py_retval(), (double)nanos / NANOS_PER_SEC);
- return true;
- }
- static bool time_time_ns(int argc, py_Ref argv) {
- PY_CHECK_ARGC(0);
- int64_t nanos = time_ns();
- py_newint(py_retval(), nanos);
- return true;
- }
- static bool time_perf_counter(int argc, py_Ref argv) {
- PY_CHECK_ARGC(0);
- py_newfloat(py_retval(), (double)clock() / CLOCKS_PER_SEC);
- return true;
- }
- static bool time_sleep(int argc, py_Ref argv) {
- PY_CHECK_ARGC(1);
- py_f64 secs;
- if(!py_castfloat(argv, &secs)) return false;
- int64_t start = time_ns();
- const int64_t end = start + secs * NANOS_PER_SEC;
- while(true) {
- int64_t now = time_ns();
- if(now >= end) break;
- #if PK_ENABLE_THREADS
- c11_thrd__yield();
- #endif
- }
- py_newnone(py_retval());
- return true;
- }
- static bool time_localtime(int argc, py_Ref argv) {
- PY_CHECK_ARGC(0);
- py_Type tp_struct_time = py_gettype("time", py_name("struct_time"));
- assert(tp_struct_time);
- struct tm* ud = py_newobject(py_retval(), tp_struct_time, 0, sizeof(struct tm));
- time_t t = time(NULL);
- *ud = *localtime(&t);
- return true;
- }
- #define DEF_STRUCT_TIME__PROPERTY(name, expr) \
- static bool struct_time__##name(int argc, py_Ref argv) { \
- PY_CHECK_ARGC(1); \
- struct tm* tm = py_touserdata(argv); \
- py_newint(py_retval(), expr); \
- return true; \
- }
- DEF_STRUCT_TIME__PROPERTY(tm_year, tm->tm_year + 1900)
- DEF_STRUCT_TIME__PROPERTY(tm_mon, tm->tm_mon + 1)
- DEF_STRUCT_TIME__PROPERTY(tm_mday, tm->tm_mday)
- DEF_STRUCT_TIME__PROPERTY(tm_hour, tm->tm_hour)
- DEF_STRUCT_TIME__PROPERTY(tm_min, tm->tm_min)
- DEF_STRUCT_TIME__PROPERTY(tm_sec, tm->tm_sec)
- DEF_STRUCT_TIME__PROPERTY(tm_wday, (tm->tm_wday + 6) % 7)
- DEF_STRUCT_TIME__PROPERTY(tm_yday, tm->tm_yday + 1)
- DEF_STRUCT_TIME__PROPERTY(tm_isdst, tm->tm_isdst)
- #undef DEF_STRUCT_TIME__PROPERTY
- void pk__add_module_time() {
- py_Ref mod = py_newmodule("time");
- py_Type tp_struct_time = py_newtype("struct_time", tp_object, mod, NULL);
- py_bindproperty(tp_struct_time, "tm_year", struct_time__tm_year, NULL);
- py_bindproperty(tp_struct_time, "tm_mon", struct_time__tm_mon, NULL);
- py_bindproperty(tp_struct_time, "tm_mday", struct_time__tm_mday, NULL);
- py_bindproperty(tp_struct_time, "tm_hour", struct_time__tm_hour, NULL);
- py_bindproperty(tp_struct_time, "tm_min", struct_time__tm_min, NULL);
- py_bindproperty(tp_struct_time, "tm_sec", struct_time__tm_sec, NULL);
- py_bindproperty(tp_struct_time, "tm_wday", struct_time__tm_wday, NULL);
- py_bindproperty(tp_struct_time, "tm_yday", struct_time__tm_yday, NULL);
- py_bindproperty(tp_struct_time, "tm_isdst", struct_time__tm_isdst, NULL);
- py_bindfunc(mod, "time", time_time);
- py_bindfunc(mod, "time_ns", time_time_ns);
- py_bindfunc(mod, "perf_counter", time_perf_counter);
- py_bindfunc(mod, "sleep", time_sleep);
- py_bindfunc(mod, "localtime", time_localtime);
- }
- #undef NANOS_PER_SEC
- #undef DEF_STRUCT_TIME__PROPERTY
|