time.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "pocketpy/pocketpy.h"
  2. #include "time.h"
  3. #include <stdint.h>
  4. #define NANOS_PER_SEC 1000000000
  5. static bool get_ns(int64_t* out) {
  6. struct timespec tms;
  7. /* The C11 way */
  8. if(!timespec_get(&tms, TIME_UTC)) {
  9. return py_exception(tp_OSError, "%s", "timespec_get() failed");
  10. }
  11. /* seconds, multiplied with 1 billion */
  12. int64_t nanos = tms.tv_sec * NANOS_PER_SEC;
  13. /* Add full nanoseconds */
  14. nanos += tms.tv_nsec;
  15. *out = nanos;
  16. return true;
  17. }
  18. static bool time_time(int argc, py_Ref argv) {
  19. PY_CHECK_ARGC(0);
  20. int64_t nanos;
  21. if(!get_ns(&nanos)) return false;
  22. py_newfloat(py_retval(), (double)nanos / NANOS_PER_SEC);
  23. return true;
  24. }
  25. static bool time_time_ns(int argc, py_Ref argv) {
  26. PY_CHECK_ARGC(0);
  27. int64_t nanos;
  28. if(!get_ns(&nanos)) return false;
  29. py_newint(py_retval(), nanos);
  30. return true;
  31. }
  32. static bool time_sleep(int argc, py_Ref argv) {
  33. PY_CHECK_ARGC(1);
  34. py_f64 secs;
  35. if(!py_castfloat(argv, &secs)) return false;
  36. int64_t start;
  37. if(!get_ns(&start)) return false;
  38. const int64_t end = start + secs * 1000000000;
  39. while(true) {
  40. int64_t now;
  41. if(!get_ns(&now)) return false;
  42. if(now >= end) break;
  43. }
  44. py_newnone(py_retval());
  45. return true;
  46. }
  47. void pk__add_module_time() {
  48. py_Ref mod = py_newmodule("time");
  49. py_bindfunc(mod, "time", time_time);
  50. py_bindfunc(mod, "time_ns", time_time_ns);
  51. py_bindfunc(mod, "sleep", time_sleep);
  52. }