• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

ink_hrtime.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /**************************************************************************
00025 
00026   ink_hrtime.h
00027 
00028   This file contains code supporting the Inktomi high-resolution timer.
00029 **************************************************************************/
00030 
00031 #if !defined (_ink_hrtime_h_)
00032 #define _ink_hrtime_h_
00033 
00034 #include "ink_config.h"
00035 #include "ink_assert.h"
00036 #include "Compatability.h"
00037 
00038 int squid_timestamp_to_buf(char *buf, unsigned int buf_size, long timestamp_sec, long timestamp_usec);
00039 char *int64_to_str(char *buf, unsigned int buf_size, int64_t val, unsigned int *total_chars, unsigned int req_width=0, char pad_char='0');
00040 
00041 #ifdef NEED_HRTIME
00042 #include <time.h>
00043 #include <sys/time.h>
00044 #include <stdlib.h>
00045 typedef int64_t ink_hrtime;
00046 #else /* !defined (NEED_HRTIME) */
00047 #include <sys/time.h>
00048 typedef hrtime_t ink_hrtime;
00049 #endif
00050 
00051 
00052 //////////////////////////////////////////////////////////////////////////////
00053 //
00054 // Time Stamp Counter
00055 //
00056 //////////////////////////////////////////////////////////////////////////////
00057 #ifdef USE_TIME_STAMP_COUNTER_HRTIME
00058 extern ink_hrtime init_hrtime_TSC();
00059 extern uint32_t hrtime_freq;
00060 extern double hrtime_freq_float;
00061 static inline ink_hrtime
00062 hrtime_rdtsc()
00063 {
00064   ink_hrtime rv;
00065   asm volatile (".byte 0x0f, 0x31":"=A" (rv));
00066   return (rv);
00067 }
00068 static inline uint64_t
00069 get_hrtime_rdtsc()
00070 {
00071   // do it fixed point if you have better hardware support
00072   return (uint64_t) (hrtime_freq_float * hrtime_rdtsc());
00073 }
00074 #endif
00075 
00076 //////////////////////////////////////////////////////////////////////////////
00077 //
00078 //      Factors to multiply units by to obtain coresponding ink_hrtime values.
00079 //
00080 //////////////////////////////////////////////////////////////////////////////
00081 
00082 #define HRTIME_FOREVER  (10*HRTIME_DECADE)
00083 #define HRTIME_DECADE   (10*HRTIME_YEAR)
00084 #define HRTIME_YEAR     (365*HRTIME_DAY+HRTIME_DAY/4)
00085 #define HRTIME_WEEK     (7*HRTIME_DAY)
00086 #define HRTIME_DAY      (24*HRTIME_HOUR)
00087 #define HRTIME_HOUR     (60*HRTIME_MINUTE)
00088 #define HRTIME_MINUTE   (60*HRTIME_SECOND)
00089 #define HRTIME_SECOND   (1000*HRTIME_MSECOND)
00090 #define HRTIME_MSECOND  (1000*HRTIME_USECOND)
00091 #define HRTIME_USECOND  (1000*HRTIME_NSECOND)
00092 #define HRTIME_NSECOND  (1LL)
00093 
00094 #define HRTIME_APPROX_SECONDS(_x) ((_x)>>30)    // off by 7.3%
00095 #define HRTIME_APPROX_FACTOR      (((float)(1<<30))/(((float)HRTIME_SECOND)))
00096 
00097 //////////////////////////////////////////////////////////////////////////////
00098 //
00099 //      Map from units to ink_hrtime values
00100 //
00101 //////////////////////////////////////////////////////////////////////////////
00102 
00103 // simple macros
00104 
00105 #define HRTIME_YEARS(_x)    ((_x)*HRTIME_YEAR)
00106 #define HRTIME_WEEKS(_x)    ((_x)*HRTIME_WEEK)
00107 #define HRTIME_DAYS(_x)     ((_x)*HRTIME_DAY)
00108 #define HRTIME_HOURS(_x)    ((_x)*HRTIME_HOUR)
00109 #define HRTIME_MINUTES(_x)  ((_x)*HRTIME_MINUTE)
00110 #define HRTIME_SECONDS(_x)  ((_x)*HRTIME_SECOND)
00111 #define HRTIME_MSECONDS(_x) ((_x)*HRTIME_MSECOND)
00112 #define HRTIME_USECONDS(_x) ((_x)*HRTIME_USECOND)
00113 #define HRTIME_NSECONDS(_x) ((_x)*HRTIME_NSECOND)
00114 
00115 // gratuituous wrappers
00116 
00117 static inline ink_hrtime
00118 ink_hrtime_from_years(unsigned int years)
00119 {
00120   return (HRTIME_YEARS(years));
00121 }
00122 static inline ink_hrtime
00123 ink_hrtime_from_weeks(unsigned int weeks)
00124 {
00125   return (HRTIME_WEEKS(weeks));
00126 }
00127 static inline ink_hrtime
00128 ink_hrtime_from_days(unsigned int days)
00129 {
00130   return (HRTIME_DAYS(days));
00131 }
00132 static inline ink_hrtime
00133 ink_hrtime_from_mins(unsigned int mins)
00134 {
00135   return (HRTIME_MINUTES(mins));
00136 }
00137 static inline ink_hrtime
00138 ink_hrtime_from_sec(unsigned int sec)
00139 {
00140   return (HRTIME_SECONDS(sec));
00141 }
00142 static inline ink_hrtime
00143 ink_hrtime_from_msec(unsigned int msec)
00144 {
00145   return (HRTIME_MSECONDS(msec));
00146 }
00147 static inline ink_hrtime
00148 ink_hrtime_from_usec(unsigned int usec)
00149 {
00150   return (HRTIME_USECONDS(usec));
00151 }
00152 static inline ink_hrtime
00153 ink_hrtime_from_nsec(unsigned int nsec)
00154 {
00155   return (HRTIME_NSECONDS(nsec));
00156 }
00157 
00158 static inline ink_hrtime
00159 ink_hrtime_from_timespec(const struct timespec * ts)
00160 {
00161   return ink_hrtime_from_sec(ts->tv_sec) + ink_hrtime_from_nsec(ts->tv_nsec);
00162 }
00163 
00164 static inline ink_hrtime
00165 ink_hrtime_from_timeval(const struct timeval * tv)
00166 {
00167   return ink_hrtime_from_sec(tv->tv_sec) + ink_hrtime_from_usec(tv->tv_usec);
00168 }
00169 
00170 //////////////////////////////////////////////////////////////////////////////
00171 //
00172 //      Map from ink_hrtime values to other units
00173 //
00174 //////////////////////////////////////////////////////////////////////////////
00175 
00176 static inline ink_hrtime
00177 ink_hrtime_to_years(ink_hrtime t)
00178 {
00179   return ((ink_hrtime) (t / HRTIME_YEAR));
00180 }
00181 static inline ink_hrtime
00182 ink_hrtime_to_weeks(ink_hrtime t)
00183 {
00184   return ((ink_hrtime) (t / HRTIME_WEEK));
00185 }
00186 static inline ink_hrtime
00187 ink_hrtime_to_days(ink_hrtime t)
00188 {
00189   return ((ink_hrtime) (t / HRTIME_DAY));
00190 }
00191 static inline ink_hrtime
00192 ink_hrtime_to_mins(ink_hrtime t)
00193 {
00194   return ((ink_hrtime) (t / HRTIME_MINUTE));
00195 }
00196 static inline ink_hrtime
00197 ink_hrtime_to_sec(ink_hrtime t)
00198 {
00199   return ((ink_hrtime) (t / HRTIME_SECOND));
00200 }
00201 static inline ink_hrtime
00202 ink_hrtime_to_msec(ink_hrtime t)
00203 {
00204   return ((ink_hrtime) (t / HRTIME_MSECOND));
00205 }
00206 static inline ink_hrtime
00207 ink_hrtime_to_usec(ink_hrtime t)
00208 {
00209   return ((ink_hrtime) (t / HRTIME_USECOND));
00210 }
00211 static inline ink_hrtime
00212 ink_hrtime_to_nsec(ink_hrtime t)
00213 {
00214   return ((ink_hrtime) (t / HRTIME_NSECOND));
00215 }
00216 
00217 static inline struct timespec
00218 ink_hrtime_to_timespec(ink_hrtime t)
00219 {
00220   struct timespec ts;
00221 
00222   ts.tv_sec = ink_hrtime_to_sec(t);
00223   ts.tv_nsec = t % HRTIME_SECOND;
00224   return (ts);
00225 }
00226 
00227 static inline struct timeval
00228 ink_hrtime_to_timeval(ink_hrtime t)
00229 {
00230   int64_t usecs;
00231   struct timeval tv;
00232 
00233   usecs = ink_hrtime_to_usec(t);
00234   tv.tv_sec = usecs / 1000000;
00235   tv.tv_usec = usecs % 1000000;
00236   return (tv);
00237 }
00238 
00239 static inline int
00240 ink_hrtime_to_timeval2(ink_hrtime t, struct timeval *tv)
00241 {
00242   int64_t usecs = ink_hrtime_to_usec(t);
00243   tv->tv_sec = usecs / 1000000;
00244   tv->tv_usec = usecs % 1000000;
00245   return 0;
00246 }
00247 
00248 
00249 /*
00250    using Jan 1 1970 as the base year, instead of Jan 1 1601,
00251    which translates to (365 + 0.25)369*24*60*60 seconds   */
00252 #define NT_TIMEBASE_DIFFERENCE_100NSECS 116444736000000000i64
00253 
00254 
00255 static inline ink_hrtime
00256 ink_get_hrtime_internal()
00257 {
00258 #if defined (NEED_HRTIME)
00259 #if defined (USE_TIME_STAMP_COUNTER_HRTIME)
00260   return get_hrtime_rdtsc();
00261 #elif defined(freebsd)
00262   timespec ts;
00263   clock_gettime(CLOCK_REALTIME, &ts);
00264   return ink_hrtime_from_timespec(&ts);
00265 #else
00266   timeval tv;
00267   gettimeofday(&tv, NULL);
00268   return ink_hrtime_from_timeval(&tv);
00269 #endif
00270 #else /* !defined (NEED_HRTIME) */
00271   return gethrtime();
00272 #endif
00273 }
00274 
00275 static inline ink_hrtime
00276 ink_get_based_hrtime_internal()
00277 {
00278 #if defined(USE_TIME_STAMP_COUNTER_HRTIME)
00279   return hrtime_offset + ink_get_hrtime_internal();
00280 #elif !HAVE_CLOCK_GETTIME
00281   timeval tv;
00282   gettimeofday(&tv, NULL);
00283   return ink_hrtime_from_timeval(&tv);
00284 #else
00285   timespec ts;
00286   clock_gettime(CLOCK_REALTIME, &ts);
00287   return ink_hrtime_from_timespec(&ts);
00288 #endif
00289 }
00290 
00291 
00292 
00293 static inline struct timeval
00294 ink_gettimeofday()
00295 {
00296   return ink_hrtime_to_timeval(ink_get_based_hrtime_internal());
00297 }
00298 
00299 static inline int
00300 ink_gethrtimeofday(struct timeval *tp, void *)
00301 {
00302   return ink_hrtime_to_timeval2(ink_get_based_hrtime_internal(), tp);
00303 }
00304 
00305 static inline int
00306 ink_time()
00307 {
00308   return (int) ink_hrtime_to_sec(ink_get_based_hrtime_internal());
00309 }
00310 
00311 static inline int
00312 ink_hrtime_diff_msec(ink_hrtime t1, ink_hrtime t2)
00313 {
00314   return (int) ink_hrtime_to_msec(t1 - t2);
00315 }
00316 
00317 static inline ink_hrtime
00318 ink_hrtime_diff(ink_hrtime t1, ink_hrtime t2)
00319 {
00320   return (t1 - t2);
00321 }
00322 
00323 static inline ink_hrtime
00324 ink_hrtime_add(ink_hrtime t1, ink_hrtime t2)
00325 {
00326   return (t1 + t2);
00327 }
00328 
00329 static inline void
00330 ink_hrtime_sleep(ink_hrtime delay)
00331 {
00332   struct timespec ts = ink_hrtime_to_timespec(delay);
00333   nanosleep(&ts, NULL);
00334 }
00335 
00336 #endif /* _ink_hrtime_h_ */

Generated by  doxygen 1.7.1