Back to index

glibc  2.9
hp-timing.h
Go to the documentation of this file.
00001 /* High precision, low overhead timing functions.  Alpha version.
00002    Copyright (C) 2001 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Richard Henderson <rth@redhat.com>, 2001.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #ifndef _HP_TIMING_H
00022 #define _HP_TIMING_H 1
00023 
00024 #include <string.h>
00025 #include <sys/param.h>
00026 #include <stdio-common/_itoa.h>
00027 
00028 /* The macros defined here use the timestamp counter in IA-64.  They
00029    provide a very accurate way to measure the time with very little
00030    overhead.  The time values themself have no real meaning, only
00031    differences are interesting.
00032 
00033    The list of macros we need includes the following:
00034 
00035    - HP_TIMING_AVAIL: test for availability.
00036 
00037    - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
00038      implemented using function calls but instead uses some inlined code
00039      which might simply consist of a few assembler instructions.  We have to
00040      know this since we might want to use the macros here in places where we
00041      cannot make function calls.
00042 
00043    - hp_timing_t: This is the type for variables used to store the time
00044      values.
00045 
00046    - HP_TIMING_ZERO: clear `hp_timing_t' object.
00047 
00048    - HP_TIMING_NOW: place timestamp for current time in variable given as
00049      parameter.
00050 
00051    - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
00052      HP_TIMING_DIFF macro.
00053 
00054    - HP_TIMING_DIFF: compute difference between two times and store it
00055      in a third.  Source and destination might overlap.
00056 
00057    - HP_TIMING_ACCUM: add time difference to another variable.  This might
00058      be a bit more complicated to implement for some platforms as the
00059      operation should be thread-safe and 64bit arithmetic on 32bit platforms
00060      is not.
00061 
00062    - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
00063      there are no threads involved.
00064 
00065    - HP_TIMING_PRINT: write decimal representation of the timing value into
00066      the given string.  This operation need not be inline even though
00067      HP_TIMING_INLINE is specified.
00068 */
00069 
00070 /* We always have the timestamp register, but it's got only a 4 second
00071    range.  Use it for ld.so profiling only.  */
00072 #define HP_TIMING_AVAIL            (0)
00073 #define HP_SMALL_TIMING_AVAIL      (1)
00074 
00075 /* We indeed have inlined functions.  */
00076 #define HP_TIMING_INLINE    (1)
00077 
00078 /* We use 32 bit values for the times.  */
00079 typedef unsigned int hp_timing_t;
00080 
00081 /* Set timestamp value to zero.  */
00082 #define HP_TIMING_ZERO(VAR) (VAR) = (0)
00083 
00084 /* The "rpcc" instruction returns a 32-bit counting half and a 32-bit
00085    "virtual cycle counter displacement".  Subtracting the two gives us
00086    a virtual cycle count.  */
00087 #define HP_TIMING_NOW(VAR) \
00088   do {                                                               \
00089     unsigned long int x_;                                            \
00090     asm volatile ("rpcc %0" : "=r"(x_));                             \
00091     (VAR) = (int) (x_) - (int) (x_ >> 32);                                  \
00092   } while (0)
00093 
00094 /* ??? Two rpcc instructions can be scheduled simultaneously.  */
00095 #define HP_TIMING_DIFF_INIT() do { } while (0)
00096 
00097 /* It's simple arithmetic for us.  */
00098 #define HP_TIMING_DIFF(Diff, Start, End)  (Diff) = ((End) - (Start))
00099 
00100 /* ??? Don't bother, since we're only used for ld.so.  */
00101 #define HP_TIMING_ACCUM(Sum, Diff)  not implemented
00102 
00103 /* No threads, no extra work.  */
00104 #define HP_TIMING_ACCUM_NT(Sum, Diff)     (Sum) += (Diff)
00105 
00106 /* Print the time value.  */
00107 #define HP_TIMING_PRINT(Buf, Len, Val) \
00108   do {                                                               \
00109     char __buf[20];                                                  \
00110     char *__cp = _itoa_word (Val, __buf + sizeof (__buf), 10, 0);           \
00111     int __len = (Len);                                                      \
00112     char *__dest = (Buf);                                            \
00113     while (__len-- > 0 && __cp < __buf + sizeof (__buf))                    \
00114       *__dest++ = *__cp++;                                           \
00115     memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles")));  \
00116   } while (0)
00117 
00118 #endif /* hp-timing.h */