time.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #define _XOPEN_SOURCE 700
  2. #include "pocketpy/pocketpy.h"
  3. #include <time.h>
  4. #include <assert.h>
  5. #define NANOS_PER_SEC 1000000000
  6. #ifndef __circle__
  7. int64_t time_ns() {
  8. struct timespec tms;
  9. #ifdef CLOCK_REALTIME
  10. clock_gettime(CLOCK_REALTIME, &tms);
  11. #else
  12. /* The C11 way */
  13. timespec_get(&tms, TIME_UTC);
  14. #endif
  15. /* seconds, multiplied with 1 billion */
  16. int64_t nanos = tms.tv_sec * (int64_t)NANOS_PER_SEC;
  17. /* Add full nanoseconds */
  18. nanos += tms.tv_nsec;
  19. return nanos;
  20. }
  21. #else
  22. int64_t time_ns() { return 0; }
  23. #endif
  24. static bool time_time(int argc, py_Ref argv) {
  25. PY_CHECK_ARGC(0);
  26. int64_t nanos = time_ns();
  27. py_newfloat(py_retval(), (double)nanos / NANOS_PER_SEC);
  28. return true;
  29. }
  30. static bool time_time_ns(int argc, py_Ref argv) {
  31. PY_CHECK_ARGC(0);
  32. int64_t nanos = time_ns();
  33. py_newint(py_retval(), nanos);
  34. return true;
  35. }
  36. static bool time_perf_counter(int argc, py_Ref argv) {
  37. PY_CHECK_ARGC(0);
  38. py_newfloat(py_retval(), (double)clock() / CLOCKS_PER_SEC);
  39. return true;
  40. }
  41. static bool time_sleep(int argc, py_Ref argv) {
  42. PY_CHECK_ARGC(1);
  43. py_f64 secs;
  44. if(!py_castfloat(argv, &secs)) return false;
  45. clock_t start = clock();
  46. const clock_t end = start + (clock_t)(secs * CLOCKS_PER_SEC);
  47. while(true) {
  48. clock_t now = clock();
  49. if(now >= end) break;
  50. }
  51. py_newnone(py_retval());
  52. return true;
  53. }
  54. static bool time_localtime(int argc, py_Ref argv) {
  55. PY_CHECK_ARGC(0);
  56. py_Type tp_struct_time = py_gettype("time", py_name("struct_time"));
  57. assert(tp_struct_time);
  58. struct tm* ud = py_newobject(py_retval(), tp_struct_time, 0, sizeof(struct tm));
  59. time_t t = time(NULL);
  60. *ud = *localtime(&t);
  61. return true;
  62. }
  63. #define DEF_STRUCT_TIME__PROPERTY(name, expr) \
  64. static bool struct_time__##name(int argc, py_Ref argv) { \
  65. PY_CHECK_ARGC(1); \
  66. struct tm* tm = py_touserdata(argv); \
  67. py_newint(py_retval(), expr); \
  68. return true; \
  69. }
  70. DEF_STRUCT_TIME__PROPERTY(tm_year, tm->tm_year + 1900)
  71. DEF_STRUCT_TIME__PROPERTY(tm_mon, tm->tm_mon + 1)
  72. DEF_STRUCT_TIME__PROPERTY(tm_mday, tm->tm_mday)
  73. DEF_STRUCT_TIME__PROPERTY(tm_hour, tm->tm_hour)
  74. DEF_STRUCT_TIME__PROPERTY(tm_min, tm->tm_min)
  75. DEF_STRUCT_TIME__PROPERTY(tm_sec, tm->tm_sec)
  76. DEF_STRUCT_TIME__PROPERTY(tm_wday, (tm->tm_wday + 6) % 7)
  77. DEF_STRUCT_TIME__PROPERTY(tm_yday, tm->tm_yday + 1)
  78. DEF_STRUCT_TIME__PROPERTY(tm_isdst, tm->tm_isdst)
  79. #undef DEF_STRUCT_TIME__PROPERTY
  80. void pk__add_module_time() {
  81. py_Ref mod = py_newmodule("time");
  82. py_Type tp_struct_time = py_newtype("struct_time", tp_object, mod, NULL);
  83. py_bindproperty(tp_struct_time, "tm_year", struct_time__tm_year, NULL);
  84. py_bindproperty(tp_struct_time, "tm_mon", struct_time__tm_mon, NULL);
  85. py_bindproperty(tp_struct_time, "tm_mday", struct_time__tm_mday, NULL);
  86. py_bindproperty(tp_struct_time, "tm_hour", struct_time__tm_hour, NULL);
  87. py_bindproperty(tp_struct_time, "tm_min", struct_time__tm_min, NULL);
  88. py_bindproperty(tp_struct_time, "tm_sec", struct_time__tm_sec, NULL);
  89. py_bindproperty(tp_struct_time, "tm_wday", struct_time__tm_wday, NULL);
  90. py_bindproperty(tp_struct_time, "tm_yday", struct_time__tm_yday, NULL);
  91. py_bindproperty(tp_struct_time, "tm_isdst", struct_time__tm_isdst, NULL);
  92. py_bindfunc(mod, "time", time_time);
  93. py_bindfunc(mod, "time_ns", time_time_ns);
  94. py_bindfunc(mod, "perf_counter", time_perf_counter);
  95. py_bindfunc(mod, "sleep", time_sleep);
  96. py_bindfunc(mod, "localtime", time_localtime);
  97. }
  98. #undef NANOS_PER_SEC
  99. #undef DEF_STRUCT_TIME__PROPERTY