diff options
Diffstat (limited to 'sysdeps/unix/clock_gettime.c')
-rw-r--r-- | sysdeps/unix/clock_gettime.c | 117 |
1 files changed, 62 insertions, 55 deletions
diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c index 7a3db29744..b7b0428e0b 100644 --- a/sysdeps/unix/clock_gettime.c +++ b/sysdeps/unix/clock_gettime.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +/* clock_gettime -- Get the current time from a POSIX clockid_t. Unix version. + Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -35,9 +36,58 @@ static hp_timing_t freq; extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, struct timespec *tp) __attribute__ ((__weak__)); + +static int +hp_timing_gettime (clockid_t clock_id, struct timespec *tp) +{ + hp_timing_t tsc; + + if (__builtin_expect (freq == 0, 0)) + { + /* This can only happen if we haven't initialized the `freq' + variable yet. Do this now. We don't have to protect this + code against multiple execution since all of them should + lead to the same result. */ + freq = __get_clockfreq (); + if (__builtin_expect (freq == 0, 0)) + /* Something went wrong. */ + return -1; + } + + if (clock_id != CLOCK_PROCESS_CPUTIME_ID + && __pthread_clock_gettime != NULL) + return __pthread_clock_gettime (clock_id, freq, tp); + + /* Get the current counter. */ + HP_TIMING_NOW (tsc); + + /* Compute the offset since the start time of the process. */ + tsc -= GL(dl_cpuclock_offset); + + /* Compute the seconds. */ + tp->tv_sec = tsc / freq; + + /* And the nanoseconds. This computation should be stable until + we get machines with about 16GHz frequency. */ + tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq; + + return 0; +} #endif +static inline int +realtime_gettime (struct timespec *tp) +{ + struct timeval tv; + int retval = gettimeofday (&tv, NULL); + if (retval == 0) + /* Convert into `timespec'. */ + TIMEVAL_TO_TIMESPEC (&tv, tp); + return retval; +} + + /* Get current value of CLOCK and store it in TP. */ int clock_gettime (clockid_t clock_id, struct timespec *tp) @@ -46,15 +96,6 @@ clock_gettime (clockid_t clock_id, struct timespec *tp) switch (clock_id) { -#define HANDLE_REALTIME \ - do { \ - struct timeval tv; \ - retval = gettimeofday (&tv, NULL); \ - if (retval == 0) \ - /* Convert into `timespec'. */ \ - TIMEVAL_TO_TIMESPEC (&tv, tp); \ - } while (0) - #ifdef SYSDEP_GETTIME SYSDEP_GETTIME; #endif @@ -66,56 +107,22 @@ clock_gettime (clockid_t clock_id, struct timespec *tp) #endif default: +#ifdef SYSDEP_GETTIME_CPU + SYSDEP_GETTIME_CPU; +#endif #if HP_TIMING_AVAIL if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) - != CLOCK_THREAD_CPUTIME_ID) + == CLOCK_THREAD_CPUTIME_ID) + retval = hp_timing_gettime (clock_id, tp); + else #endif - { - __set_errno (EINVAL); - break; - } + __set_errno (EINVAL); + break; -#if HP_TIMING_AVAIL - /* FALLTHROUGH. */ +#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME case CLOCK_PROCESS_CPUTIME_ID: - { - hp_timing_t tsc; - - if (__builtin_expect (freq == 0, 0)) - { - /* This can only happen if we haven't initialized the `freq' - variable yet. Do this now. We don't have to protect this - code against multiple execution since all of them should - lead to the same result. */ - freq = __get_clockfreq (); - if (__builtin_expect (freq == 0, 0)) - /* Something went wrong. */ - break; - } - - if (clock_id != CLOCK_PROCESS_CPUTIME_ID - && __pthread_clock_gettime != NULL) - { - retval = __pthread_clock_gettime (clock_id, freq, tp); - break; - } - - /* Get the current counter. */ - HP_TIMING_NOW (tsc); - - /* Compute the offset since the start time of the process. */ - tsc -= GL(dl_cpuclock_offset); - - /* Compute the seconds. */ - tp->tv_sec = tsc / freq; - - /* And the nanoseconds. This computation should be stable until - we get machines with about 16GHz frequency. */ - tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq; - - retval = 0; - } - break; + retval = hp_timing_gettime (clock_id, tp); + break; #endif } |