Back to index

glibc  2.9
clock_getcpuclockid.c
Go to the documentation of this file.
00001 /* clock_getcpuclockid -- Get a clockid_t for process CPU time.  Linux version.
00002    Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <time.h>
00022 #include <unistd.h>
00023 #include <kernel-features.h>
00024 #include "kernel-posix-cpu-timers.h"
00025 
00026 #ifndef HAS_CPUCLOCK
00027 # define HAS_CPUCLOCK 1
00028 #endif
00029 
00030 int
00031 clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
00032 {
00033 #ifdef __NR_clock_getres
00034   /* The clockid_t value is a simple computation from the PID.
00035      But we do a clock_getres call to validate it.  */
00036 
00037   const clockid_t pidclock = MAKE_PROCESS_CPUCLOCK (pid, CPUCLOCK_SCHED);
00038 
00039 # if !(__ASSUME_POSIX_CPU_TIMERS > 0)
00040   extern int __libc_missing_posix_cpu_timers attribute_hidden;
00041 #  if !(__ASSUME_POSIX_TIMERS > 0)
00042   extern int __libc_missing_posix_timers attribute_hidden;
00043   if (__libc_missing_posix_timers && !__libc_missing_posix_cpu_timers)
00044     __libc_missing_posix_cpu_timers = 1;
00045 #  endif
00046   if (!__libc_missing_posix_cpu_timers)
00047 # endif
00048     {
00049       INTERNAL_SYSCALL_DECL (err);
00050       int r = INTERNAL_SYSCALL (clock_getres, err, 2, pidclock, NULL);
00051       if (!INTERNAL_SYSCALL_ERROR_P (r, err))
00052        {
00053          *clock_id = pidclock;
00054          return 0;
00055        }
00056 
00057 # if !(__ASSUME_POSIX_TIMERS > 0)
00058       if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
00059        {
00060          /* The kernel doesn't support these calls at all.  */
00061          __libc_missing_posix_timers = 1;
00062          __libc_missing_posix_cpu_timers = 1;
00063        }
00064       else
00065 # endif
00066        if (INTERNAL_SYSCALL_ERRNO (r, err) == EINVAL)
00067          {
00068 # if !(__ASSUME_POSIX_CPU_TIMERS > 0)
00069            if (pidclock == MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
00070               || INTERNAL_SYSCALL_ERROR_P (INTERNAL_SYSCALL
00071                                         (clock_getres, err, 2,
00072                                          MAKE_PROCESS_CPUCLOCK
00073                                          (0, CPUCLOCK_SCHED), NULL),
00074                                         err))
00075              /* The kernel doesn't support these clocks at all.  */
00076              __libc_missing_posix_cpu_timers = 1;
00077            else
00078 # endif
00079              /* The clock_getres system call checked the PID for us.  */
00080              return ESRCH;
00081          }
00082        else
00083          return INTERNAL_SYSCALL_ERRNO (r, err);
00084     }
00085 #endif
00086 
00087   /* We don't allow any process ID but our own.  */
00088   if (pid != 0 && pid != getpid ())
00089     return EPERM;
00090 
00091 #ifdef CLOCK_PROCESS_CPUTIME_ID
00092   if (HAS_CPUCLOCK)
00093     {
00094       /* Store the number.  */
00095       *clock_id = CLOCK_PROCESS_CPUTIME_ID;
00096 
00097       return 0;
00098     }
00099 #endif
00100 
00101   /* We don't have a timer for that.  */
00102   return ENOENT;
00103 }