CUBRID Engine  latest
tsc_timer.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * tsc_timer.c - Time Stamp Counter(TSC) timer implementations
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <fcntl.h>
28 #include "tsc_timer.h"
29 #if !defined(WINDOWS)
30 #include <sys/time.h>
31 #endif
32 
33 #define CHECK_CPU_FREQ(v) \
34 do { \
35  if ((v) == 0) \
36  { \
37  (v) = get_clock_freq (); \
38  } \
39 } while (0)
40 
41 #define CALCULATE_ELAPSED_TIME_USEC(time, diff, freq) \
42 do { \
43  (time)->tv_sec = (long)((diff) / (freq)); \
44  (time)->tv_usec = (long)((((diff) % (freq)) * (TSC_UINT64) (1000000)) / (freq)); \
45 } while (0)
46 
47 #define CALCULATE_ELAPSED_TIMEVAL(time, end, start) \
48 do { \
49  (time)->tv_sec = (end).tv_sec - (start).tv_sec; \
50  (time)->tv_usec = (end).tv_usec - (start).tv_usec; \
51  if ((time)->tv_usec < 0) \
52  { \
53  (time)->tv_sec--; \
54  (time)->tv_usec += 1000000; \
55  } \
56 } while (0)
57 
58 static int power_Savings = -1;
60 
61 static void check_power_savings (void);
62 
63 /*
64  * tsc_init() - initialize the tsc_timer
65  */
66 void
67 tsc_init (void)
68 {
71  return;
72 }
73 
74 /*
75  * tsc_getticks() - get the current Time Stamp Counter
76  * tck(out): current CPU ticks or timeval
77  *
78  * Note: Ticks does not mean the current TIME.
79  */
80 void
82 {
83  if (power_Savings == 0)
84  {
85  tck->tc = getticks ();
86  }
87  else
88  {
89  gettimeofday (&(tck->tv), NULL);
90  }
91  return;
92 }
93 
94 /*
95  * tsc_elapsed_time_usec() - measure the elapsed time in microseconds
96  * tv(out) : elapsed time (sec, usec)
97  * end_tick(in) : end time
98  * start_tick(in): start time
99  */
100 void
102 {
103  if (power_Savings == 0)
104  {
105  TSC_UINT64 diff_tsc;
106 
107  /* Sometimes the time goes backwards in the MULTI-CORE processor world. But it is a negligible level. */
108  if (end_tick.tc < start_tick.tc)
109  {
110  tv->tv_sec = 0;
111  tv->tv_usec = 0;
112  return;
113  }
114 
116  diff_tsc = (TSC_UINT64) elapsed ((ticks) end_tick.tc, (ticks) start_tick.tc);
118  }
119  else
120  {
121  CALCULATE_ELAPSED_TIMEVAL (tv, end_tick.tv, start_tick.tv);
122  }
123  return;
124 }
125 
126 /*
127  * tsc_elapsed_utime () - measure the elapsed time in microseconds (not
128  * seconds, microseconds like tsc_elapsed_time_usec).
129  *
130  * return : Elapsed time (microseconds).
131  * end_tick (in) : End time.
132  * start_tick (in) : Start time.
133  */
134 UINT64
135 tsc_elapsed_utime (TSC_TICKS end_tick, TSC_TICKS start_tick)
136 {
137  TSCTIMEVAL tv;
138  tsc_elapsed_time_usec (&tv, end_tick, start_tick);
139  return tv.tv_sec * 1000000LL + tv.tv_usec;
140 }
141 
142 /*
143  * tsc_start_time_usec() - get the current Time Stamp Counter
144  * tck(out): current CPU ticks or timeval
145  *
146  * Note: This function does exactly same thing with tsc_getticks().
147  * It pairs up with tsc_end_time_usec().
148  */
149 void
151 {
152  tsc_getticks (tck);
153  return;
154 }
155 
156 /*
157  * tsc_end_time_usec() - measure the elapsed time in microseconds
158  * tv(out) : elapsed time (sec, usec)
159  * start_tick(in): start time
160  */
161 void
163 {
164  TSC_TICKS end_tick;
165  tsc_getticks (&end_tick);
166 
167  if (power_Savings == 0)
168  {
169  TSC_UINT64 diff_tsc;
170  if (end_tick.tc < start_tick.tc)
171  {
172  tv->tv_sec = 0;
173  tv->tv_usec = 0;
174  return;
175  }
176 
178  diff_tsc = (TSC_UINT64) elapsed ((ticks) end_tick.tc, (ticks) start_tick.tc);
180  }
181  else
182  {
183  CALCULATE_ELAPSED_TIMEVAL (tv, end_tick.tv, start_tick.tv);
184  }
185  return;
186 }
187 
188 /*
189  * check_power_savings() - check power saving options
190  */
191 static void
193 {
194 #if defined (WINDOWS)
195  /*
196  * Note: Windows's QueryPerformanceFrequency always returns
197  * the stable CPU or mainboard clock rate.
198  */
199  power_Savings = 0;
200 
201 #elif defined (LINUX)
202  /*
203  * Note: 'power_saving value == zero' means that the CPU clock rate is fixed.
204  */
205  int fd_mc, fd_smt;
206  char mc = 0, smt = 0;
207 
208  fd_mc = open ("/sys/devices/system/cpu/sched_mc_power_savings", O_RDONLY);
209  if (fd_mc != -1)
210  {
211  char tmp = 0;
212  ssize_t n;
213 
214  n = read (fd_mc, &tmp, 1);
215  if (n > 0)
216  {
217  mc = tmp;
218  }
219  close (fd_mc);
220  }
221 
222  fd_smt = open ("/sys/devices/system/cpu/sched_smt_power_savings", O_RDONLY);
223  if (fd_smt != -1)
224  {
225  char tmp = 0;
226  ssize_t n;
227 
228  n = read (fd_smt, &tmp, 1);
229  if (n > 0)
230  {
231  smt = tmp;
232  }
233  close (fd_smt);
234  }
235 
236  if (mc == '0' && smt == '0')
237  {
238  power_Savings = 0;
239  return;
240  }
241 
242  power_Savings = 1;
243 
244 #else
245  /*
246  * Note: We assume that the unknown OS performs the power-saving policy.
247  */
248  power_Savings = 1;
249 
250 #endif
251  return;
252 }
#define CALCULATE_ELAPSED_TIMEVAL(time, end, start)
Definition: tsc_timer.c:47
static int power_Savings
Definition: tsc_timer.c:58
static void check_power_savings(void)
Definition: tsc_timer.c:192
UINT64 tsc_elapsed_utime(TSC_TICKS end_tick, TSC_TICKS start_tick)
Definition: tsc_timer.c:135
#define CHECK_CPU_FREQ(v)
Definition: tsc_timer.c:33
struct timeval TSCTIMEVAL
Definition: tsc_timer.h:40
#define CALCULATE_ELAPSED_TIME_USEC(time, diff, freq)
Definition: tsc_timer.c:41
void tsc_elapsed_time_usec(TSCTIMEVAL *tv, TSC_TICKS end_tick, TSC_TICKS start_tick)
Definition: tsc_timer.c:101
void tsc_start_time_usec(TSC_TICKS *tck)
Definition: tsc_timer.c:150
void tsc_end_time_usec(TSCTIMEVAL *tv, TSC_TICKS start_tick)
Definition: tsc_timer.c:162
UINT64 TSC_UINT64
Definition: tsc_timer.h:39
#define NULL
Definition: freelistheap.h:34
void tsc_getticks(TSC_TICKS *tck)
Definition: tsc_timer.c:81
struct timeval tv
Definition: tsc_timer.h:46
void tsc_init(void)
Definition: tsc_timer.c:67
static TSC_UINT64 cpu_Clock_rate
Definition: tsc_timer.c:59
TSC_UINT64 get_clock_freq(void)
ticks tc
Definition: tsc_timer.h:45