Back to index

glibc  2.9
clock_settime.c
Go to the documentation of this file.
00001 /* Copyright (C) 1999-2004, 2006, 2007 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 <errno.h>
00020 #include <time.h>
00021 #include <sys/time.h>
00022 #include <libc-internal.h>
00023 #include <ldsodefs.h>
00024 
00025 
00026 #if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
00027 /* Clock frequency of the processor.  We make it a 64-bit variable
00028    because some jokers are already playing with processors with more
00029    than 4GHz.  */
00030 static hp_timing_t freq;
00031 
00032 
00033 /* This function is defined in the thread library.  */
00034 extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
00035      __attribute__ ((__weak__));
00036 
00037 
00038 static int
00039 hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
00040 {
00041   hp_timing_t tsc;
00042   hp_timing_t usertime;
00043 
00044   /* First thing is to get the current time.  */
00045   HP_TIMING_NOW (tsc);
00046 
00047   if (__builtin_expect (freq == 0, 0))
00048     {
00049       /* This can only happen if we haven't initialized the `freq'
00050         variable yet.  Do this now. We don't have to protect this
00051         code against multiple execution since all of them should lead
00052         to the same result.  */
00053       freq = __get_clockfreq ();
00054       if (__builtin_expect (freq == 0, 0))
00055        /* Something went wrong.  */
00056        return -1;
00057     }
00058 
00059   /* Convert the user-provided time into CPU ticks.  */
00060   usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull;
00061 
00062   /* Determine the offset and use it as the new base value.  */
00063   if (clock_id == CLOCK_PROCESS_CPUTIME_ID
00064       || __pthread_clock_settime == NULL)
00065     GL(dl_cpuclock_offset) = tsc - usertime;
00066   else
00067     __pthread_clock_settime (clock_id, tsc - usertime);
00068 
00069   return 0;
00070 }
00071 #endif
00072 
00073 
00074 /* Set CLOCK to value TP.  */
00075 int
00076 clock_settime (clockid_t clock_id, const struct timespec *tp)
00077 {
00078   int retval;
00079 
00080   /* Make sure the time cvalue is OK.  */
00081   if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
00082     {
00083       __set_errno (EINVAL);
00084       return -1;
00085     }
00086 
00087   switch (clock_id)
00088     {
00089 #define HANDLE_REALTIME \
00090       do {                                                           \
00091        struct timeval tv;                                            \
00092        TIMESPEC_TO_TIMEVAL (&tv, tp);                                       \
00093                                                                      \
00094        retval = settimeofday (&tv, NULL);                            \
00095       } while (0)
00096 
00097 #ifdef SYSDEP_SETTIME
00098       SYSDEP_SETTIME;
00099 #endif
00100 
00101 #ifndef HANDLED_REALTIME
00102     case CLOCK_REALTIME:
00103       HANDLE_REALTIME;
00104       break;
00105 #endif
00106 
00107     default:
00108 #ifdef SYSDEP_SETTIME_CPU
00109       SYSDEP_SETTIME_CPU;
00110 #endif
00111 #ifndef HANDLED_CPUTIME
00112 # if HP_TIMING_AVAIL
00113       if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID
00114          || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID)
00115        retval = hp_timing_settime (clock_id, tp);
00116       else
00117 # endif
00118        {
00119          __set_errno (EINVAL);
00120          retval = -1;
00121        }
00122 #endif
00123       break;
00124     }
00125 
00126   return retval;
00127 }