"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 }