"Fossies" - the Fresh Open Source Software Archive

Member "FunctionCheck-3.2.0/src/share/fc_time.c" (29 May 2012, 5015 Bytes) of package /linux/privat/old/FunctionCheck-3.2.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * FunctionCheck profiler
    3  * (C) Copyright 2000-2012 Yannick Perret
    4  * 
    5  *  This program is free software; you can redistribute it and/or
    6  *  modify it under the terms of the GNU General Public License as
    7  *  published by the Free Software Foundation; either version 2 of the
    8  *  License, or (at your option) any later version.
    9  *
   10  *  This program is distributed in the hope that it will be useful,
   11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13  *  General Public License for more details.
   14  *
   15  *  You should have received a copy of the GNU General Public License
   16  *  along with this program; if not, write to the Free Software
   17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18  */
   19 
   20 #include "fc_time.h"
   21 #include "fc_tools.h"
   22 
   23 /* time mode */
   24 int fc_time_tmode = FC_MTIME_TSC;
   25 
   26 static clock_t fc_first_time_clock = 0;
   27 static struct timeval fc_first_time_tv = {0, 0};
   28 static unsigned long long fc_first_time_tsc = 0;
   29 
   30 static void rdtsc(unsigned long long *val);
   31 void fc_timer_tsc(unsigned long long *val);
   32 void fc_timer_ext(unsigned long long *val);
   33 void fc_timer_cpu(unsigned long long *val);
   34 
   35 /** function pointer on the effective timer. needed by fc_gettimeofday **/
   36 void (*FC_TIMER_PTR)(unsigned long long *) = fc_timer_tsc;
   37 
   38 /* get time for external unit */
   39 inline void fc_timer_ext(unsigned long long *val)
   40 {
   41     struct timeval tv;
   42 
   43     gettimeofday(&tv, NULL);
   44 
   45     if (tv.tv_sec == fc_first_time_tv.tv_sec)
   46     {
   47         *val = tv.tv_usec - fc_first_time_tv.tv_usec;
   48         return;
   49     }
   50 
   51     *val = (tv.tv_sec - fc_first_time_tv.tv_sec - 1)*1000000 +
   52             tv.tv_usec + 1000000 - fc_first_time_tv.tv_usec;
   53 }
   54 
   55 /* get time for internal unit */
   56 inline void fc_timer_cpu(unsigned long long *val)
   57 {
   58     clock_t result;
   59     unsigned int delta;
   60 
   61     /* CPU/SYS time */
   62     result = (unsigned int) clock();
   63 
   64     /* over the limit ? */
   65     if (fc_first_time_clock < result)
   66     {
   67         delta = result - fc_first_time_clock;
   68     }
   69     else
   70     {
   71         /* all bits set except the highest bit is clock_t max value? */
   72         static const clock_t max_clock = ~(1 << (sizeof(clock_t)*8 - 1));
   73 
   74         delta = result + (max_clock - fc_first_time_clock);
   75     }
   76 
   77     *val = delta;
   78 }
   79 
   80 /* get time using cpu tsc */
   81 inline void fc_timer_tsc(unsigned long long *val)
   82 {
   83     unsigned long long result;
   84 
   85     rdtsc(&result);
   86 
   87     *val = result - fc_first_time_tsc;
   88 
   89     return;
   90 }
   91 
   92 inline void rdtsc(unsigned long long *val)
   93 {
   94 #if defined (__GNUC__) && defined (__i386__)
   95     unsigned long lo, hi;
   96     asm volatile (
   97             "pushl %%ebx\n" /* ebx is used in PIC shared library? */
   98             "pushl %%ecx\n" /* ecx is overwritten by CPUID (6C65746EH i.e. 'ntel') */
   99             "xorl %%eax, %%eax\n"
  100             "cpuid\n"
  101             "rdtsc\n"
  102             "popl %%ecx\n"
  103             "popl %%ebx\n"
  104             : "=a" (lo), "=d" (hi)
  105             );
  106     *val = (unsigned long long) hi << 32 | lo;
  107 #elif defined (__GNUC__) && defined (__x86_64__)
  108     unsigned long lo, hi;
  109     asm volatile (
  110             "push %%rbx\n" /* ebx is used in PIC shared library? */
  111             "push %%rcx\n" /* ecx is overwritten by CPUID (6C65746EH i.e. 'ntel') */
  112             "xor %%rax, %%rax\n"
  113             "cpuid\n"
  114             "rdtsc\n"
  115             "pop %%rcx\n"
  116             "pop %%rbx\n"
  117             : "=a" (lo), "=d" (hi)
  118             );
  119     *val = (unsigned long long) hi << 32 | lo;
  120 #else
  121     printf("Error! rdtsc opcode not available\n");
  122     *val = 0;
  123 #endif
  124 }
  125 
  126 /* set the time mode */
  127 inline int fc_set_time_type(char *buf)
  128 {
  129     if (strcasecmp(buf, "ext") == 0)
  130     {
  131         FC_TIMER_PTR = fc_timer_ext;
  132         fc_time_tmode = FC_MTIME_EXT;
  133         return (FC_MTIME_EXT);
  134     }
  135     else
  136         if (strcasecmp(buf, "cpu") == 0)
  137     {
  138         FC_TIMER_PTR = fc_timer_cpu;
  139         fc_time_tmode = FC_MTIME_CPU;
  140         return (FC_MTIME_CPU);
  141     }
  142     else
  143         if (strcasecmp(buf, "sys") == 0)
  144     {
  145         FC_TIMER_PTR = fc_timer_cpu;
  146         fc_time_tmode = FC_MTIME_CPU;
  147         return (FC_MTIME_CPU);
  148     }
  149     else
  150         if (strcasecmp(buf, "tsc") == 0)
  151     {
  152         FC_TIMER_PTR = fc_timer_tsc;
  153         fc_time_tmode = FC_MTIME_TSC;
  154         return (FC_MTIME_TSC);
  155     }
  156     else
  157     {
  158         fc_message("time: invalid value for 'FC_TIME_MODE' (%s).", buf);
  159         fc_message("time: ignored (TSC used).");
  160         FC_TIMER_PTR = fc_timer_tsc;
  161         fc_time_tmode = FC_MTIME_TSC;
  162         return (FC_MTIME_TSC);
  163     }
  164 }
  165 
  166 /* get the time mode */
  167 inline int fc_get_time_type()
  168 {
  169     return (fc_time_tmode);
  170 }
  171 
  172 /* init the time system */
  173 inline void fc_init_time()
  174 {
  175     fc_first_time_clock = clock();
  176     gettimeofday(&fc_first_time_tv, NULL);
  177     rdtsc(&fc_first_time_tsc);
  178 }
  179 
  180 /* my 'gettimeofday'. returns a 'timeval' structure containing
  181    the current time (in the good clock-mode) */
  182 inline void fc_gettimeofday(unsigned long long *val)
  183 {
  184     /* just call the good function */
  185     FC_TIMER_PTR(val);
  186 }