Back to index

glibc  2.9
Functions | Variables
pthread_getcpuclockid.c File Reference
#include <errno.h>
#include <pthreadP.h>
#include <sys/time.h>
#include <tls.h>
#include <kernel-features.h>
#include <kernel-posix-cpu-timers.h>

Go to the source code of this file.

Functions

int pthread_getcpuclockid (pthread_t threadid, clockid_t *clockid)

Variables

int __libc_missing_posix_cpu_timers attribute_hidden

Function Documentation

int pthread_getcpuclockid ( pthread_t  threadid,
clockid_t *  clockid 
)

Definition at line 36 of file pthread_getcpuclockid.c.

{
  struct pthread *pd = (struct pthread *) threadid;

  /* Make sure the descriptor is valid.  */
  if (INVALID_TD_P (pd))
    /* Not a valid thread handle.  */
    return ESRCH;

#ifdef __NR_clock_getres
  /* The clockid_t value is a simple computation from the TID.
     But we do a clock_getres call to validate it if we aren't
     yet sure we have the kernel support.  */

  const clockid_t tidclock = MAKE_THREAD_CPUCLOCK (pd->tid, CPUCLOCK_SCHED);

# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
#  if !(__ASSUME_POSIX_TIMERS > 0)
  if (__libc_missing_posix_timers && !__libc_missing_posix_cpu_timers)
    __libc_missing_posix_cpu_timers = 1;
#  endif
  if (!__libc_missing_posix_cpu_timers)
    {
      INTERNAL_SYSCALL_DECL (err);
      int r = INTERNAL_SYSCALL (clock_getres, err, 2, tidclock, NULL);
      if (!INTERNAL_SYSCALL_ERROR_P (r, err))
# endif
       {
         *clockid = tidclock;
         return 0;
       }

# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
#  if !(__ASSUME_POSIX_TIMERS > 0)
      if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
       {
         /* The kernel doesn't support these calls at all.  */
         __libc_missing_posix_timers = 1;
         __libc_missing_posix_cpu_timers = 1;
       }
      else
#  endif
       if (INTERNAL_SYSCALL_ERRNO (r, err) == EINVAL)
         {
           /* The kernel doesn't support these clocks at all.  */
           __libc_missing_posix_cpu_timers = 1;
         }
      else
       return INTERNAL_SYSCALL_ERRNO (r, err);
    }
# endif
#endif

#ifdef CLOCK_THREAD_CPUTIME_ID
  /* We need to store the thread ID in the CLOCKID variable together
     with a number identifying the clock.  We reserve the low 3 bits
     for the clock ID and the rest for the thread ID.  This is
     problematic if the thread ID is too large.  But 29 bits should be
     fine.

     If some day more clock IDs are needed the ID part can be
     enlarged.  The IDs are entirely internal.  */
  if (pd->tid >= 1 << (8 * sizeof (*clockid) - CLOCK_IDFIELD_SIZE))
    return ERANGE;

  /* Store the number.  */
  *clockid = CLOCK_THREAD_CPUTIME_ID | (pd->tid << CLOCK_IDFIELD_SIZE);

  return 0;
#else
  /* We don't have a timer for that.  */
  return ENOENT;
#endif
}

Here is the call graph for this function:


Variable Documentation

int __libc_missing_posix_timers attribute_hidden

Definition at line 29 of file pthread_getcpuclockid.c.