]>
Commit | Line | Data |
---|---|---|
3c9057f3 SS |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
e2882c85 | 3 | Copyright 2010-2018 Free Software Foundation, Inc. |
3c9057f3 SS |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 3 of the License, or | |
8 | (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 | |
13 | GNU 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, see <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | /* This program tests tracepoint speed. It consists of two identical | |
19 | loops, which in normal execution will run for exactly the same | |
20 | amount of time. A tracepoint in the second loop will slow it down | |
21 | by some amount, and then the program will report the slowdown | |
22 | observed. */ | |
23 | ||
24 | /* While primarily designed for the testsuite, it can also be used | |
25 | for interactive testing. */ | |
26 | ||
27 | #include <stdio.h> | |
28 | #include <time.h> | |
29 | #include <sys/time.h> | |
30 | #include <sys/resource.h> | |
31 | ||
32 | int trace_speed_test (void); | |
33 | ||
34 | /* We mark these globals as volatile so the speed-measuring loops | |
35 | don't get totally emptied out at high optimization levels. */ | |
36 | ||
37 | volatile int globfoo, globfoo2, globfoo3; | |
38 | ||
39 | volatile short globarr[80000]; | |
40 | ||
41 | int init_iters = 10 * 1000; | |
42 | ||
43 | int iters; | |
44 | ||
45 | int max_iters = 1000 * 1000 * 1000; | |
46 | ||
47 | int numtps = 1; | |
48 | ||
49 | unsigned long long now2, now3, now4, now5; | |
50 | int total1, total2, idelta, mindelta, nsdelta; | |
51 | int nspertp = 0; | |
52 | ||
53 | /* Return CPU usage (both user and system - trap-based tracepoints use | |
54 | a bunch of system time). */ | |
55 | ||
56 | unsigned long long | |
57 | myclock () | |
58 | { | |
fbb7bcbe WW |
59 | struct timeval tm; |
60 | gettimeofday (&tm, NULL); | |
61 | return (((unsigned long long) tm.tv_sec) * 1000000) + tm.tv_usec; | |
3c9057f3 SS |
62 | } |
63 | ||
64 | int | |
65 | main(int argc, char **argv) | |
66 | { | |
67 | int problem; | |
68 | ||
69 | iters = init_iters; | |
70 | ||
71 | while (1) | |
72 | { | |
73 | numtps = 1; /* set pre-run breakpoint here */ | |
74 | ||
75 | /* Keep trying the speed test, with more iterations, until | |
76 | we get to a reasonable number. */ | |
77 | while (problem = trace_speed_test()) | |
78 | { | |
79 | /* If iteration isn't working, give up. */ | |
80 | if (iters > max_iters) | |
81 | { | |
82 | printf ("Gone over %d iterations, giving up\n", max_iters); | |
83 | break; | |
84 | } | |
85 | if (problem < 0) | |
86 | { | |
87 | printf ("Negative times, giving up\n", max_iters); | |
88 | break; | |
89 | } | |
90 | ||
91 | iters *= 2; | |
92 | printf ("Doubled iterations to %d\n", iters); | |
93 | } | |
94 | ||
95 | printf ("Tracepoint time is %d ns\n", nspertp); | |
96 | ||
97 | /* This is for the benefit of interactive testing and attaching, | |
98 | keeps the program from pegging the machine. */ | |
99 | sleep (1); /* set post-run breakpoint here */ | |
100 | ||
101 | /* Issue a little bit of output periodically, so we can see if | |
102 | program is alive or hung. */ | |
103 | printf ("%s keeping busy, clock=%llu\n", argv[0], myclock ()); | |
104 | } | |
105 | return 0; | |
106 | } | |
107 | ||
108 | int | |
109 | trace_speed_test (void) | |
110 | { | |
111 | int i; | |
112 | ||
113 | /* Overall loop run time deltas under 1 ms are likely noise and | |
114 | should be ignored. */ | |
115 | mindelta = 1000; | |
116 | ||
117 | // The bodies of the two loops following must be identical. | |
118 | ||
119 | now2 = myclock (); | |
120 | globfoo2 = 1; | |
121 | for (i = 0; i < iters; ++i) | |
122 | { | |
123 | globfoo2 *= 45; | |
124 | globfoo2 += globfoo + globfoo3; | |
125 | globfoo2 *= globfoo + globfoo3; | |
126 | globfoo2 -= globarr[4] + globfoo3; | |
127 | globfoo2 *= globfoo + globfoo3; | |
128 | globfoo2 += globfoo + globfoo3; | |
129 | } | |
130 | now3 = myclock (); | |
131 | total1 = now3 - now2; | |
132 | ||
133 | now4 = myclock (); | |
134 | globfoo2 = 1; | |
135 | for (i = 0; i < iters; ++i) | |
136 | { | |
137 | globfoo2 *= 45; | |
138 | globfoo2 += globfoo + globfoo3; /* set tracepoint here */ | |
139 | globfoo2 *= globfoo + globfoo3; | |
140 | globfoo2 -= globarr[4] + globfoo3; | |
141 | globfoo2 *= globfoo + globfoo3; | |
142 | globfoo2 += globfoo + globfoo3; | |
143 | } | |
144 | now5 = myclock (); | |
145 | total2 = now5 - now4; | |
146 | ||
147 | /* Report on the test results. */ | |
148 | ||
149 | nspertp = 0; | |
150 | ||
151 | idelta = total2 - total1; | |
152 | ||
153 | printf ("Loops took %d usec and %d usec, delta is %d usec, %d iterations\n", | |
154 | total1, total2, idelta, iters); | |
155 | ||
156 | /* If the second loop seems to run faster, things are weird so give up. */ | |
157 | if (idelta < 0) | |
158 | return -1; | |
159 | ||
160 | if (idelta > mindelta | |
fbb7bcbe WW |
161 | /* Total test time should be between 15 and 30 seconds. */ |
162 | && (total1 + total2) > (15 * 1000000) | |
163 | && (total1 + total2) < (30 * 1000000)) | |
3c9057f3 SS |
164 | { |
165 | nsdelta = (((unsigned long long) idelta) * 1000) / iters; | |
166 | printf ("Second loop took %d ns longer per iter than first\n", nsdelta); | |
167 | nspertp = nsdelta / numtps; | |
168 | printf ("%d ns per tracepoint\n", nspertp); | |
169 | printf ("Base iteration time %d ns\n", | |
170 | ((int) (((unsigned long long) total1) * 1000) / iters)); | |
171 | printf ("Total test time %d secs\n", ((int) ((now5 - now2) / 1000000))); | |
172 | ||
173 | /* Speed test ran with no problem. */ | |
174 | return 0; | |
175 | } | |
176 | ||
177 | /* The test run was too brief, or otherwise not useful. */ | |
178 | return 1; | |
179 | } |