espidf_clock.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (C) 2023 Amazon Inc. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "libc_errno.h"
  6. #include "platform_api_extension.h"
  7. #define NANOSECONDS_PER_SECOND 1000000000ULL
  8. static __wasi_errno_t
  9. wasi_clockid_to_clockid(__wasi_clockid_t in, clockid_t *out)
  10. {
  11. switch (in) {
  12. case __WASI_CLOCK_MONOTONIC:
  13. *out = CLOCK_MONOTONIC;
  14. return __WASI_ESUCCESS;
  15. case __WASI_CLOCK_REALTIME:
  16. *out = CLOCK_REALTIME;
  17. return __WASI_ESUCCESS;
  18. case __WASI_CLOCK_PROCESS_CPUTIME_ID:
  19. #if defined(CLOCK_PROCESS_CPUTIME_ID)
  20. *out = CLOCK_PROCESS_CPUTIME_ID;
  21. return __WASI_ESUCCESS;
  22. #else
  23. return __WASI_ENOTSUP;
  24. #endif
  25. case __WASI_CLOCK_THREAD_CPUTIME_ID:
  26. #if defined(CLOCK_THREAD_CPUTIME_ID)
  27. *out = CLOCK_THREAD_CPUTIME_ID;
  28. return __WASI_ESUCCESS;
  29. #else
  30. return __WASI_ENOTSUP;
  31. #endif
  32. default:
  33. return __WASI_EINVAL;
  34. }
  35. }
  36. static __wasi_timestamp_t
  37. timespec_to_nanoseconds(const struct timespec *ts)
  38. {
  39. if (ts->tv_sec < 0)
  40. return 0;
  41. if ((__wasi_timestamp_t)ts->tv_sec >= UINT64_MAX / NANOSECONDS_PER_SECOND)
  42. return UINT64_MAX;
  43. return (__wasi_timestamp_t)ts->tv_sec * NANOSECONDS_PER_SECOND
  44. + (__wasi_timestamp_t)ts->tv_nsec;
  45. }
  46. __wasi_errno_t
  47. os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
  48. {
  49. clockid_t nclock_id;
  50. __wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
  51. if (error != __WASI_ESUCCESS)
  52. return error;
  53. struct timespec ts;
  54. if (clock_getres(nclock_id, &ts) < 0)
  55. return convert_errno(errno);
  56. *resolution = timespec_to_nanoseconds(&ts);
  57. return error;
  58. }
  59. __wasi_errno_t
  60. os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
  61. __wasi_timestamp_t *time)
  62. {
  63. clockid_t nclock_id;
  64. __wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
  65. (void)precision;
  66. if (error != __WASI_ESUCCESS)
  67. return error;
  68. struct timespec ts;
  69. if (clock_gettime(nclock_id, &ts) < 0)
  70. return convert_errno(errno);
  71. *time = timespec_to_nanoseconds(&ts);
  72. return error;
  73. }