Back to index

glibc  2.9
clock_nanosleep.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <time.h>
00020 #include <errno.h>
00021 
00022 #include <sysdep-cancel.h>
00023 #include <kernel-features.h>
00024 #include "kernel-posix-cpu-timers.h"
00025 
00026 
00027 #ifdef __ASSUME_POSIX_TIMERS
00028 /* We can simply use the syscall.  The CPU clocks are not supported
00029    with this function.  */
00030 int
00031 clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
00032                struct timespec *rem)
00033 {
00034   INTERNAL_SYSCALL_DECL (err);
00035   int r;
00036 
00037   if (clock_id == CLOCK_THREAD_CPUTIME_ID)
00038     return EINVAL;
00039   if (clock_id == CLOCK_PROCESS_CPUTIME_ID)
00040     clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
00041 
00042   if (SINGLE_THREAD_P)
00043     r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem);
00044   else
00045     {
00046       int oldstate = LIBC_CANCEL_ASYNC ();
00047 
00048       r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req,
00049                          rem);
00050 
00051       LIBC_CANCEL_RESET (oldstate);
00052     }
00053 
00054   return (INTERNAL_SYSCALL_ERROR_P (r, err)
00055          ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
00056 }
00057 
00058 #else
00059 # ifdef __NR_clock_nanosleep
00060 /* Is the syscall known to exist?  */
00061 extern int __libc_missing_posix_timers attribute_hidden;
00062 
00063 /* The REALTIME and MONOTONIC clock might be available.  Try the
00064    syscall first.  */
00065 #  define SYSDEP_NANOSLEEP \
00066   if (!__libc_missing_posix_timers)                                         \
00067     {                                                                \
00068       clockid_t syscall_clockid;                                     \
00069       INTERNAL_SYSCALL_DECL (err);                                   \
00070                                                                      \
00071       if (clock_id == CLOCK_THREAD_CPUTIME_ID)                              \
00072        return EINVAL;                                                       \
00073       if (clock_id == CLOCK_PROCESS_CPUTIME_ID)                             \
00074        syscall_clockid = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);         \
00075       else                                                           \
00076        syscall_clockid = clock_id;                                   \
00077                                                                      \
00078       int oldstate = LIBC_CANCEL_ASYNC ();                                  \
00079                                                                      \
00080       int r = INTERNAL_SYSCALL (clock_nanosleep, err, 4,                    \
00081                             syscall_clockid, flags, req, rem);       \
00082                                                                      \
00083       LIBC_CANCEL_RESET (oldstate);                                         \
00084                                                                      \
00085       if (!INTERNAL_SYSCALL_ERROR_P (r, err))                               \
00086        return 0;                                                     \
00087                                                                      \
00088       if (INTERNAL_SYSCALL_ERRNO (r, err) != ENOSYS)                        \
00089        return INTERNAL_SYSCALL_ERRNO (r, err);                              \
00090                                                                      \
00091       __libc_missing_posix_timers = 1;                                      \
00092     }
00093 # endif
00094 
00095 # include <sysdeps/unix/clock_nanosleep.c>
00096 #endif