MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mysys_my_rdtsc-t.cc
1 /* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 
17 /*
18  rdtsc3 -- multi-platform timer code
19  pgulutzan@mysql.com, 2005-08-29
20  modified 2008-11-02
21 
22  When you run rdtsc3, it will print the contents of
23  "my_timer_info". The display indicates
24  what timer routine is best for a given platform.
25 
26  For example, this is the display on production.mysql.com,
27  a 2.8GHz Xeon with Linux 2.6.17, gcc 3.3.3:
28 
29  cycles nanoseconds microseconds milliseconds ticks
30 ------------- ------------- ------------- ------------- -------------
31  1 11 13 18 17
32  2815019607 1000000000 1000000 1049 102
33  1 1000 1 1 1
34  88 4116 3888 4092 2044
35 
36  The first line shows routines, e.g. 1 = MY_TIMER_ROUTINE_ASM_X86.
37  The second line shows frequencies, e.g. 2815019607 is nearly 2.8GHz.
38  The third line shows resolutions, e.g. 1000 = very poor resolution.
39  The fourth line shows overheads, e.g. ticks takes 2044 cycles.
40 */
41 
42 // First include (the generated) my_config.h, to get correct platform defines.
43 #include "my_config.h"
44 #include <gtest/gtest.h>
45 
46 #include "my_global.h"
47 #include "my_rdtsc.h"
48 
49 namespace mysys_my_rdtsc_unittest {
50 
51 const int LOOP_COUNT= 100;
52 
53 class RDTimeStampCounter : public ::testing::Test
54 {
55 protected:
56  void SetUp()
57  {
58  test_init();
59  }
60  void test_init();
61 
62  MY_TIMER_INFO myt;
63 };
64 
65 
66 void RDTimeStampCounter::test_init()
67 {
68  my_timer_init(&myt);
69 
70 /*
71  diag("----- Routine ---------------");
72  diag("myt.cycles.routine : %13llu", myt.cycles.routine);
73  diag("myt.nanoseconds.routine : %13llu", myt.nanoseconds.routine);
74  diag("myt.microseconds.routine : %13llu", myt.microseconds.routine);
75  diag("myt.milliseconds.routine : %13llu", myt.milliseconds.routine);
76  diag("myt.ticks.routine : %13llu", myt.ticks.routine);
77 
78  diag("----- Frequency -------------");
79  diag("myt.cycles.frequency : %13llu", myt.cycles.frequency);
80  diag("myt.nanoseconds.frequency : %13llu", myt.nanoseconds.frequency);
81  diag("myt.microseconds.frequency : %13llu", myt.microseconds.frequency);
82  diag("myt.milliseconds.frequency : %13llu", myt.milliseconds.frequency);
83  diag("myt.ticks.frequency : %13llu", myt.ticks.frequency);
84 
85  diag("----- Resolution ------------");
86  diag("myt.cycles.resolution : %13llu", myt.cycles.resolution);
87  diag("myt.nanoseconds.resolution : %13llu", myt.nanoseconds.resolution);
88  diag("myt.microseconds.resolution : %13llu", myt.microseconds.resolution);
89  diag("myt.milliseconds.resolution : %13llu", myt.milliseconds.resolution);
90  diag("myt.ticks.resolution : %13llu", myt.ticks.resolution);
91 
92  diag("----- Overhead --------------");
93  diag("myt.cycles.overhead : %13llu", myt.cycles.overhead);
94  diag("myt.nanoseconds.overhead : %13llu", myt.nanoseconds.overhead);
95  diag("myt.microseconds.overhead : %13llu", myt.microseconds.overhead);
96  diag("myt.milliseconds.overhead : %13llu", myt.milliseconds.overhead);
97  diag("myt.ticks.overhead : %13llu", myt.ticks.overhead);
98 */
99 }
100 
101 
102 TEST_F(RDTimeStampCounter, TestCycle)
103 {
104  ulonglong t1= my_timer_cycles();
105  ulonglong t2;
106  int i;
107  int backward= 0;
108  int nonzero= 0;
109 
110  for (i=0 ; i < LOOP_COUNT ; i++)
111  {
112  t2= my_timer_cycles();
113  if (t1 >= t2)
114  backward++;
115  if (t2 != 0)
116  nonzero++;
117  t1= t2;
118  }
119 
120  /* Expect at most 1 backward, the cycle value can overflow */
121  EXPECT_TRUE((backward <= 1)) << "The cycle timer is strictly increasing";
122 
123  if (myt.cycles.routine != 0)
124  EXPECT_TRUE((nonzero != 0)) << "The cycle timer is implemented";
125  else
126  EXPECT_TRUE((nonzero == 0))
127  << "The cycle timer is not implemented and returns 0";
128 }
129 
130 
131 TEST_F(RDTimeStampCounter, TestNanosecond)
132 {
133  ulonglong t1= my_timer_nanoseconds();
134  ulonglong t2;
135  int i;
136  int backward= 0;
137  int nonzero= 0;
138 
139  for (i=0 ; i < LOOP_COUNT ; i++)
140  {
141  t2= my_timer_nanoseconds();
142  if (t1 > t2)
143  backward++;
144  if (t2 != 0)
145  nonzero++;
146  t1= t2;
147  }
148 
149  EXPECT_TRUE((backward == 0)) << "The nanosecond timer is increasing";
150 
151  if (myt.nanoseconds.routine != 0)
152  EXPECT_TRUE((nonzero != 0)) << "The nanosecond timer is implemented";
153  else
154  EXPECT_TRUE((nonzero == 0))
155  << "The nanosecond timer is not implemented and returns 0";
156 }
157 
158 
159 TEST_F(RDTimeStampCounter, TestMicrosecond)
160 {
161  ulonglong t1= my_timer_microseconds();
162  ulonglong t2;
163  int i;
164  int backward= 0;
165  int nonzero= 0;
166 
167  for (i=0 ; i < LOOP_COUNT ; i++)
168  {
169  t2= my_timer_microseconds();
170  if (t1 > t2)
171  backward++;
172  if (t2 != 0)
173  nonzero++;
174  t1= t2;
175  }
176 
177  EXPECT_TRUE((backward == 0)) << "The microsecond timer is increasing";
178 
179  if (myt.microseconds.routine != 0)
180  EXPECT_TRUE((nonzero != 0)) << "The microsecond timer is implemented";
181  else
182  EXPECT_TRUE((nonzero == 0))
183  << "The microsecond timer is not implemented and returns 0";
184 }
185 
186 
187 TEST_F(RDTimeStampCounter, TestMillisecond)
188 {
189  ulonglong t1= my_timer_milliseconds();
190  ulonglong t2;
191  int i;
192  int backward= 0;
193  int nonzero= 0;
194 
195  for (i=0 ; i < LOOP_COUNT ; i++)
196  {
197  t2= my_timer_milliseconds();
198  if (t1 > t2)
199  backward++;
200  if (t2 != 0)
201  nonzero++;
202  t1= t2;
203  }
204 
205  EXPECT_TRUE((backward == 0)) << "The millisecond timer is increasing";
206 
207  if (myt.milliseconds.routine != 0)
208  EXPECT_TRUE((nonzero != 0)) << "The millisecond timer is implemented";
209  else
210  EXPECT_TRUE((nonzero == 0))
211  << "The millisecond timer is not implemented and returns 0";
212 }
213 
214 
215 TEST_F(RDTimeStampCounter, TestTick)
216 {
217  ulonglong t1= my_timer_ticks();
218  ulonglong t2;
219  int i;
220  int backward= 0;
221  int nonzero= 0;
222 
223  for (i=0 ; i < LOOP_COUNT ; i++)
224  {
225  t2= my_timer_ticks();
226  if (t1 > t2)
227  backward++;
228  if (t2 != 0)
229  nonzero++;
230  t1= t2;
231  }
232 
233  EXPECT_TRUE((backward == 0)) << "The tick timer is increasing";
234 
235  if (myt.ticks.routine != 0)
236  EXPECT_TRUE((nonzero != 0)) << "The tick timer is implemented";
237  else
238  EXPECT_TRUE((nonzero == 0))
239  << "The tick timer is not implemented and returns 0";
240 }
241 
242 
243 }