vdso_clock_gettime.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Copyright (c) 2006-2026 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2026-04-21 rcitach init ver.
  9. */
  10. #include "vdso_user_internal.h"
  11. static int rt_vdso_resolve_clock_index(clockid_t clock, unsigned int *index)
  12. {
  13. switch (clock)
  14. {
  15. case CLOCK_REALTIME:
  16. case CLOCK_REALTIME_COARSE:
  17. *index = RT_VDSO_CLOCK_REALTIME_INDEX;
  18. return 0;
  19. case CLOCK_MONOTONIC:
  20. case CLOCK_MONOTONIC_COARSE:
  21. case CLOCK_MONOTONIC_RAW:
  22. case CLOCK_BOOTTIME:
  23. *index = RT_VDSO_CLOCK_MONOTONIC_INDEX;
  24. return 0;
  25. default:
  26. if ((unsigned int)clock >= RT_VDSO_CLOCK_ID_MAX)
  27. {
  28. return -EINVAL;
  29. }
  30. return -ENOSYS;
  31. }
  32. }
  33. int rt_vdso_clock_gettime_impl(clockid_t clock, struct timespec *ts)
  34. {
  35. const struct rt_vdso_data_page *data_page = rt_vdso_get_data_page();
  36. uint32_t seq;
  37. unsigned int index;
  38. uint64_t last;
  39. uint64_t freq;
  40. uint64_t now;
  41. uint64_t delta_ns;
  42. struct timespec base_time;
  43. int ret;
  44. ret = rt_vdso_resolve_clock_index(clock, &index);
  45. if (ret != 0)
  46. {
  47. return ret;
  48. }
  49. do
  50. {
  51. seq = rt_vdso_data_read_begin(data_page);
  52. if (index == RT_VDSO_CLOCK_REALTIME_INDEX &&
  53. !(data_page->flags & RT_VDSO_FLAG_REALTIME_VALID))
  54. {
  55. return -ENOSYS;
  56. }
  57. base_time = data_page->base_time[index];
  58. last = data_page->counter_last;
  59. freq = data_page->counter_freq;
  60. now = rt_vdso_arch_read_counter();
  61. } while (unlikely(rt_vdso_data_read_retry(data_page, seq)));
  62. if (freq == 0)
  63. {
  64. return -ENOSYS;
  65. }
  66. delta_ns = rt_vdso_counter_delta_to_ns(now, last, freq);
  67. rt_vdso_timespec_add_nanoseconds(&base_time, delta_ns);
  68. *ts = base_time;
  69. return 0;
  70. }
  71. int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
  72. __attribute__((alias("rt_vdso_clock_gettime_impl"), visibility("default")));
  73. int __kernel_clock_gettime(clockid_t clock, struct timespec *ts)
  74. __attribute__((alias("rt_vdso_clock_gettime_impl"), visibility("default")));