1/* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc.
2 Use is subject to license terms.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
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#include "my_global.h"
43#include "my_rdtsc.h"
44#include "tap.h"
45
46#define LOOP_COUNT 100
47
48MY_TIMER_INFO myt;
49
50void test_init()
51{
52 my_timer_init(&myt);
53
54 diag("----- Routine ---------------");
55 diag("myt.cycles.routine : %13llu", myt.cycles.routine);
56 diag("myt.nanoseconds.routine : %13llu", myt.nanoseconds.routine);
57 diag("myt.microseconds.routine : %13llu", myt.microseconds.routine);
58 diag("myt.milliseconds.routine : %13llu", myt.milliseconds.routine);
59 diag("myt.ticks.routine : %13llu", myt.ticks.routine);
60
61 diag("----- Frequency -------------");
62 diag("myt.cycles.frequency : %13llu", myt.cycles.frequency);
63 diag("myt.nanoseconds.frequency : %13llu", myt.nanoseconds.frequency);
64 diag("myt.microseconds.frequency : %13llu", myt.microseconds.frequency);
65 diag("myt.milliseconds.frequency : %13llu", myt.milliseconds.frequency);
66 diag("myt.ticks.frequency : %13llu", myt.ticks.frequency);
67
68 diag("----- Resolution ------------");
69 diag("myt.cycles.resolution : %13llu", myt.cycles.resolution);
70 diag("myt.nanoseconds.resolution : %13llu", myt.nanoseconds.resolution);
71 diag("myt.microseconds.resolution : %13llu", myt.microseconds.resolution);
72 diag("myt.milliseconds.resolution : %13llu", myt.milliseconds.resolution);
73 diag("myt.ticks.resolution : %13llu", myt.ticks.resolution);
74
75 diag("----- Overhead --------------");
76 diag("myt.cycles.overhead : %13llu", myt.cycles.overhead);
77 diag("myt.nanoseconds.overhead : %13llu", myt.nanoseconds.overhead);
78 diag("myt.microseconds.overhead : %13llu", myt.microseconds.overhead);
79 diag("myt.milliseconds.overhead : %13llu", myt.milliseconds.overhead);
80 diag("myt.ticks.overhead : %13llu", myt.ticks.overhead);
81
82 ok(1, "my_timer_init() did not crash");
83}
84
85void test_cycle()
86{
87 ulonglong t1= my_timer_cycles();
88 ulonglong t2;
89 int i;
90 int backward= 0;
91 int nonzero= 0;
92
93 for (i=0 ; i < LOOP_COUNT ; i++)
94 {
95 t2= my_timer_cycles();
96 if (t1 >= t2)
97 backward++;
98 if (t2 != 0)
99 nonzero++;
100 t1= t2;
101 }
102
103 /* Expect at most 1 backward, the cycle value can overflow */
104 ok((backward <= 1), "The cycle timer is strictly increasing");
105
106 if (myt.cycles.routine != 0)
107 ok((nonzero != 0), "The cycle timer is implemented");
108 else
109 ok((nonzero == 0), "The cycle timer is not implemented and returns 0");
110}
111
112void test_nanosecond()
113{
114 ulonglong t1= my_timer_nanoseconds();
115 ulonglong t2;
116 int i;
117 int backward= 0;
118 int nonzero= 0;
119
120 for (i=0 ; i < LOOP_COUNT ; i++)
121 {
122 t2= my_timer_nanoseconds();
123 if (t1 > t2)
124 backward++;
125 if (t2 != 0)
126 nonzero++;
127 t1= t2;
128 }
129
130 ok((backward == 0), "The nanosecond timer is increasing");
131
132 if (myt.nanoseconds.routine != 0)
133 ok((nonzero != 0), "The nanosecond timer is implemented");
134 else
135 ok((nonzero == 0), "The nanosecond timer is not implemented and returns 0");
136}
137
138void test_microsecond()
139{
140 ulonglong t1= my_timer_microseconds();
141 ulonglong t2;
142 int i;
143 int backward= 0;
144 int nonzero= 0;
145
146 for (i=0 ; i < LOOP_COUNT ; i++)
147 {
148 t2= my_timer_microseconds();
149 if (t1 > t2)
150 backward++;
151 if (t2 != 0)
152 nonzero++;
153 t1= t2;
154 }
155
156 ok((backward == 0), "The microsecond timer is increasing");
157
158 if (myt.microseconds.routine != 0)
159 ok((nonzero != 0), "The microsecond timer is implemented");
160 else
161 ok((nonzero == 0), "The microsecond timer is not implemented and returns 0");
162}
163
164void test_millisecond()
165{
166 ulonglong t1= my_timer_milliseconds();
167 ulonglong t2;
168 int i;
169 int backward= 0;
170 int nonzero= 0;
171
172 for (i=0 ; i < LOOP_COUNT ; i++)
173 {
174 t2= my_timer_milliseconds();
175 if (t1 > t2)
176 backward++;
177 if (t2 != 0)
178 nonzero++;
179 t1= t2;
180 }
181
182 ok((backward == 0), "The millisecond timer is increasing");
183
184 if (myt.milliseconds.routine != 0)
185 ok((nonzero != 0), "The millisecond timer is implemented");
186 else
187 ok((nonzero == 0), "The millisecond timer is not implemented and returns 0");
188}
189
190void test_tick()
191{
192 ulonglong t1= my_timer_ticks();
193 ulonglong t2;
194 int i;
195 int backward= 0;
196 int nonzero= 0;
197
198 for (i=0 ; i < LOOP_COUNT ; i++)
199 {
200 t2= my_timer_ticks();
201 if (t1 > t2)
202 backward++;
203 if (t2 != 0)
204 nonzero++;
205 t1= t2;
206 }
207
208 ok((backward == 0), "The tick timer is increasing");
209
210 if (myt.ticks.routine != 0)
211 ok((nonzero != 0), "The tick timer is implemented");
212 else
213 ok((nonzero == 0), "The tick timer is not implemented and returns 0");
214}
215
216int main(int argc __attribute__((unused)),
217 char ** argv __attribute__((unused)))
218{
219 plan(11);
220
221 test_init();
222 test_cycle();
223 test_nanosecond();
224 test_microsecond();
225 test_millisecond();
226 test_tick();
227
228 return 0;
229}
230
231