clock_nanosleep.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // SPDX-License-Identifier: GPL-2.0
  2. #define _GNU_SOURCE
  3. #include <sched.h>
  4. #include <sys/timerfd.h>
  5. #include <sys/syscall.h>
  6. #include <time.h>
  7. #include <unistd.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <stdint.h>
  11. #include <pthread.h>
  12. #include <signal.h>
  13. #include <string.h>
  14. #include "log.h"
  15. #include "timens.h"
  16. void test_sig(int sig)
  17. {
  18. if (sig == SIGUSR2)
  19. pthread_exit(NULL);
  20. }
  21. struct thread_args {
  22. struct timespec *now, *rem;
  23. pthread_mutex_t *lock;
  24. int clockid;
  25. int abs;
  26. };
  27. void *call_nanosleep(void *_args)
  28. {
  29. struct thread_args *args = _args;
  30. clock_nanosleep(args->clockid, args->abs ? TIMER_ABSTIME : 0, args->now, args->rem);
  31. pthread_mutex_unlock(args->lock);
  32. return NULL;
  33. }
  34. int run_test(int clockid, int abs)
  35. {
  36. struct timespec now = {}, rem;
  37. struct thread_args args = { .now = &now, .rem = &rem, .clockid = clockid};
  38. struct timespec start;
  39. pthread_mutex_t lock;
  40. pthread_t thread;
  41. int j, ok, ret;
  42. signal(SIGUSR1, test_sig);
  43. signal(SIGUSR2, test_sig);
  44. pthread_mutex_init(&lock, NULL);
  45. pthread_mutex_lock(&lock);
  46. if (clock_gettime(clockid, &start) == -1) {
  47. if (errno == EINVAL && check_skip(clockid))
  48. return 0;
  49. return pr_perror("clock_gettime");
  50. }
  51. if (abs) {
  52. now.tv_sec = start.tv_sec;
  53. now.tv_nsec = start.tv_nsec;
  54. }
  55. now.tv_sec += 3600;
  56. args.abs = abs;
  57. args.lock = &lock;
  58. ret = pthread_create(&thread, NULL, call_nanosleep, &args);
  59. if (ret != 0) {
  60. pr_err("Unable to create a thread: %s", strerror(ret));
  61. return 1;
  62. }
  63. /* Wait when the thread will call clock_nanosleep(). */
  64. ok = 0;
  65. for (j = 0; j < 8; j++) {
  66. /* The maximum timeout is about 5 seconds. */
  67. usleep(10000 << j);
  68. /* Try to interrupt clock_nanosleep(). */
  69. pthread_kill(thread, SIGUSR1);
  70. usleep(10000 << j);
  71. /* Check whether clock_nanosleep() has been interrupted or not. */
  72. if (pthread_mutex_trylock(&lock) == 0) {
  73. /**/
  74. ok = 1;
  75. break;
  76. }
  77. }
  78. if (!ok)
  79. pthread_kill(thread, SIGUSR2);
  80. pthread_join(thread, NULL);
  81. pthread_mutex_destroy(&lock);
  82. if (!ok) {
  83. ksft_test_result_pass("clockid: %d abs:%d timeout\n", clockid, abs);
  84. return 1;
  85. }
  86. if (rem.tv_sec < 3300 || rem.tv_sec > 3900) {
  87. pr_fail("clockid: %d abs: %d remain: %ld\n",
  88. clockid, abs, rem.tv_sec);
  89. return 1;
  90. }
  91. ksft_test_result_pass("clockid: %d abs:%d\n", clockid, abs);
  92. return 0;
  93. }
  94. int main(int argc, char *argv[])
  95. {
  96. int ret, nsfd;
  97. nscheck();
  98. ksft_set_plan(4);
  99. check_supported_timers();
  100. if (unshare_timens())
  101. return 1;
  102. if (_settime(CLOCK_MONOTONIC, 7 * 24 * 3600))
  103. return 1;
  104. if (_settime(CLOCK_BOOTTIME, 9 * 24 * 3600))
  105. return 1;
  106. nsfd = open("/proc/self/ns/time_for_children", O_RDONLY);
  107. if (nsfd < 0)
  108. return pr_perror("Unable to open timens_for_children");
  109. if (setns(nsfd, CLONE_NEWTIME))
  110. return pr_perror("Unable to set timens");
  111. ret = 0;
  112. ret |= run_test(CLOCK_MONOTONIC, 0);
  113. ret |= run_test(CLOCK_MONOTONIC, 1);
  114. ret |= run_test(CLOCK_BOOTTIME_ALARM, 0);
  115. ret |= run_test(CLOCK_BOOTTIME_ALARM, 1);
  116. if (ret)
  117. ksft_exit_fail();
  118. ksft_exit_pass();
  119. return ret;
  120. }