clock_nanosleep.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, write to the Free
  13. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA. */
  15. #include <time.h>
  16. #include <errno.h>
  17. #include <sysdep-cancel.h>
  18. #include <bits/kernel-features.h>
  19. #include "kernel-posix-cpu-timers.h"
  20. #ifdef __ASSUME_POSIX_TIMERS
  21. /* We can simply use the syscall. The CPU clocks are not supported
  22. with this function. */
  23. int
  24. clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
  25. struct timespec *rem)
  26. {
  27. INTERNAL_SYSCALL_DECL (err);
  28. int r;
  29. if (clock_id == CLOCK_THREAD_CPUTIME_ID)
  30. return EINVAL;
  31. if (clock_id == CLOCK_PROCESS_CPUTIME_ID)
  32. clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
  33. if (SINGLE_THREAD_P)
  34. r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem);
  35. else
  36. {
  37. int oldstate = LIBC_CANCEL_ASYNC ();
  38. r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req,
  39. rem);
  40. LIBC_CANCEL_RESET (oldstate);
  41. }
  42. return (INTERNAL_SYSCALL_ERROR_P (r, err)
  43. ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
  44. }
  45. #else
  46. # ifdef __NR_clock_nanosleep
  47. /* Is the syscall known to exist? */
  48. extern int __libc_missing_posix_timers attribute_hidden;
  49. /* The REALTIME and MONOTONIC clock might be available. Try the
  50. syscall first. */
  51. # define SYSDEP_NANOSLEEP \
  52. if (!__libc_missing_posix_timers) \
  53. { \
  54. clockid_t syscall_clockid; \
  55. INTERNAL_SYSCALL_DECL (err); \
  56. \
  57. if (clock_id == CLOCK_THREAD_CPUTIME_ID) \
  58. return EINVAL; \
  59. if (clock_id == CLOCK_PROCESS_CPUTIME_ID) \
  60. syscall_clockid = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED); \
  61. else \
  62. syscall_clockid = clock_id; \
  63. \
  64. int oldstate = LIBC_CANCEL_ASYNC (); \
  65. \
  66. int r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, \
  67. syscall_clockid, flags, req, rem); \
  68. \
  69. LIBC_CANCEL_RESET (oldstate); \
  70. \
  71. if (!INTERNAL_SYSCALL_ERROR_P (r, err)) \
  72. return 0; \
  73. \
  74. if (INTERNAL_SYSCALL_ERRNO (r, err) != ENOSYS) \
  75. return INTERNAL_SYSCALL_ERRNO (r, err); \
  76. \
  77. __libc_missing_posix_timers = 1; \
  78. }
  79. # endif
  80. # include <sysdeps/unix/clock_nanosleep.c>
  81. #endif