root / synthbench / bonnie++ / bon_time.cpp @ 0:839f52ef7657
History | View | Annotate | Download (9.1 kB)
1 |
|
---|---|
2 |
using namespace std; |
3 |
|
4 |
#include <sys/time.h> |
5 |
#ifdef OS2
|
6 |
#define INCL_DOSFILEMGR
|
7 |
#define INCL_BASE
|
8 |
#include <os2.h> |
9 |
#include "os2-perfutil.h" |
10 |
/*
|
11 |
Convert 8-byte (low, high) time value to double
|
12 |
*/
|
13 |
#define LL2F(high, low) (4294967296.0*(high)+(low)) |
14 |
#else
|
15 |
#include <unistd.h> |
16 |
#include <sys/resource.h> |
17 |
#endif
|
18 |
#include "bon_time.h" |
19 |
#include <time.h> |
20 |
#include <string.h> |
21 |
|
22 |
#ifndef NON_UNIX
|
23 |
#include "conf.h" |
24 |
#endif
|
25 |
|
26 |
#ifdef HAVE_ALGORITHM
|
27 |
#include <algorithm> |
28 |
#else
|
29 |
|
30 |
#ifdef HAVE_ALGO
|
31 |
#include <algo> |
32 |
#else
|
33 |
#ifdef HAVE_ALGO_H
|
34 |
#include <algo.h> |
35 |
#else
|
36 |
#define min(XX,YY) ((XX) < (YY) ? (XX) : (YY))
|
37 |
#define max(XX,YY) ((XX) > (YY) ? (XX) : (YY))
|
38 |
#endif
|
39 |
#endif
|
40 |
|
41 |
#endif
|
42 |
|
43 |
#define TIMEVAL_TO_DOUBLE(XX) (double((XX).tv_sec) + double((XX).tv_usec) / 1000000.0) |
44 |
|
45 |
void BonTimer::timestamp()
|
46 |
{ |
47 |
m_last_timestamp = get_cur_time(); |
48 |
m_last_cpustamp = get_cpu_use(); |
49 |
} |
50 |
|
51 |
double
|
52 |
BonTimer::time_so_far() |
53 |
{ |
54 |
return get_cur_time() - m_last_timestamp;
|
55 |
} |
56 |
|
57 |
double
|
58 |
BonTimer::cpu_so_far() |
59 |
{ |
60 |
return get_cpu_use() - m_last_cpustamp;
|
61 |
} |
62 |
|
63 |
double
|
64 |
BonTimer::get_cur_time() |
65 |
{ |
66 |
#ifdef OS2
|
67 |
ULONG count = 0;
|
68 |
ULONG rc = DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &count, sizeof(count));
|
69 |
if(rc)
|
70 |
return 0.0; |
71 |
return double(count)/1000.0; |
72 |
#else
|
73 |
struct timeval tp;
|
74 |
|
75 |
if (gettimeofday(&tp, static_cast<struct timezone *>(NULL)) == -1) |
76 |
io_error("gettimeofday", true); |
77 |
return TIMEVAL_TO_DOUBLE(tp);
|
78 |
#endif
|
79 |
} |
80 |
|
81 |
double
|
82 |
BonTimer::get_cpu_use() |
83 |
{ |
84 |
#ifdef OS2
|
85 |
double busy_val, busy_val_prev;
|
86 |
double intr_val, intr_val_prev;
|
87 |
CPUUTIL CPUUtil; |
88 |
|
89 |
ULONG rc = DosPerfSysCall(CMD_KI_RDCNT,(ULONG) &CPUUtil,0,0); |
90 |
if(rc)
|
91 |
io_error("times", true); |
92 |
return LL2F(CPUUtil.ulBusyHigh, CPUUtil.ulBusyLow)
|
93 |
+ LL2F(CPUUtil.ulIntrHigh, CPUUtil.ulIntrLow); |
94 |
#else
|
95 |
struct rusage res_usage;
|
96 |
|
97 |
getrusage(RUSAGE_SELF, &res_usage); |
98 |
return TIMEVAL_TO_DOUBLE(res_usage.ru_utime) + TIMEVAL_TO_DOUBLE(res_usage.ru_stime);
|
99 |
#endif
|
100 |
} |
101 |
|
102 |
void BonTimer::get_delta_t(tests_t test)
|
103 |
{ |
104 |
m_delta[test].Elapsed = time_so_far(); |
105 |
m_delta[test].CPU = cpu_so_far(); |
106 |
timestamp(); |
107 |
} |
108 |
|
109 |
void BonTimer::get_delta_report(report_s &rep)
|
110 |
{ |
111 |
rep.EndTime = get_cur_time(); |
112 |
rep.CPU = cpu_so_far(); |
113 |
timestamp(); |
114 |
} |
115 |
|
116 |
void BonTimer::add_delta_report(report_s &rep, tests_t test)
|
117 |
{ |
118 |
if(m_delta[test].CPU == 0.0) |
119 |
{ |
120 |
m_delta[test].FirstStart = rep.StartTime; |
121 |
m_delta[test].LastStop = rep.EndTime; |
122 |
} |
123 |
else
|
124 |
{ |
125 |
m_delta[test].FirstStart = min(m_delta[test].FirstStart, rep.StartTime); |
126 |
m_delta[test].LastStop = max(m_delta[test].LastStop, rep.EndTime); |
127 |
} |
128 |
m_delta[test].CPU += rep.CPU; |
129 |
m_delta[test].Elapsed = m_delta[test].LastStop - m_delta[test].FirstStart; |
130 |
} |
131 |
|
132 |
BonTimer::BonTimer() |
133 |
: m_type(txt) |
134 |
{ |
135 |
Initialize(); |
136 |
} |
137 |
|
138 |
void
|
139 |
BonTimer::Initialize() |
140 |
{ |
141 |
for(int i = 0; i < TestCount; i++) |
142 |
{ |
143 |
m_delta[i].CPU = 0.0; |
144 |
m_delta[i].Elapsed = 0.0; |
145 |
} |
146 |
timestamp(); |
147 |
} |
148 |
|
149 |
int BonTimer::print_cpu_stat(tests_t test)
|
150 |
{ |
151 |
if(m_delta[test].Elapsed == 0.0) |
152 |
{ |
153 |
if(m_type == txt)
|
154 |
fprintf(m_fp, " ");
|
155 |
else
|
156 |
fprintf(m_fp, ",");
|
157 |
return 0; |
158 |
} |
159 |
if(m_delta[test].Elapsed < MinTime)
|
160 |
{ |
161 |
if(m_type == txt)
|
162 |
fprintf(m_fp, " +++");
|
163 |
else
|
164 |
fprintf(m_fp, ",+++");
|
165 |
return 0; |
166 |
} |
167 |
int cpu = int(m_delta[test].CPU / m_delta[test].Elapsed * 100.0); |
168 |
if(m_type == txt)
|
169 |
fprintf(m_fp, " %3d", cpu);
|
170 |
else
|
171 |
fprintf(m_fp, ",%d", cpu);
|
172 |
return 0; |
173 |
} |
174 |
|
175 |
int BonTimer::print_stat(tests_t test)
|
176 |
{ |
177 |
if(m_delta[test].Elapsed == 0.0) |
178 |
{ |
179 |
if(m_type == txt)
|
180 |
fprintf(m_fp, " ");
|
181 |
else
|
182 |
fprintf(m_fp, ",");
|
183 |
} |
184 |
else if(m_delta[test].Elapsed < MinTime) |
185 |
{ |
186 |
if(m_type == txt)
|
187 |
fprintf(m_fp, " +++++");
|
188 |
else
|
189 |
fprintf(m_fp, ",+++++");
|
190 |
} |
191 |
else
|
192 |
{ |
193 |
if(test == Lseek)
|
194 |
{ |
195 |
double seek_stat = double(Seeks) / m_delta[test].Elapsed; |
196 |
if(m_type == txt)
|
197 |
{ |
198 |
if(seek_stat >= 1000.0) |
199 |
fprintf(m_fp, " %5.0f", seek_stat);
|
200 |
else
|
201 |
fprintf(m_fp, " %5.1f", seek_stat);
|
202 |
} |
203 |
else
|
204 |
fprintf(m_fp, ",%.1f", seek_stat);
|
205 |
} |
206 |
else
|
207 |
{ |
208 |
int res = int(double(m_file_size) / (m_delta[test].Elapsed / 1024.0)); |
209 |
if(m_type == txt)
|
210 |
fprintf(m_fp, " %5d", res);
|
211 |
else
|
212 |
fprintf(m_fp, ",%d", res);
|
213 |
} |
214 |
} |
215 |
return print_cpu_stat(test);
|
216 |
} |
217 |
|
218 |
int BonTimer::print_file_stat(tests_t test)
|
219 |
{ |
220 |
if(m_delta[test].Elapsed == 0.0) |
221 |
{ |
222 |
if(m_type == txt)
|
223 |
fprintf(m_fp, " ");
|
224 |
else
|
225 |
fprintf(m_fp, ",");
|
226 |
} |
227 |
else if(m_delta[test].Elapsed < MinTime) |
228 |
{ |
229 |
if(m_type == txt)
|
230 |
fprintf(m_fp, " +++++");
|
231 |
else
|
232 |
fprintf(m_fp, ",+++++");
|
233 |
} |
234 |
else
|
235 |
{ |
236 |
int res = int(double(m_directory_size) * double(DirectoryUnit) |
237 |
/ m_delta[test].Elapsed); |
238 |
if(m_type == txt)
|
239 |
fprintf(m_fp, " %5d", res);
|
240 |
else
|
241 |
fprintf(m_fp, ",%d", res);
|
242 |
} |
243 |
|
244 |
return print_cpu_stat(test);
|
245 |
} |
246 |
|
247 |
void
|
248 |
BonTimer::PrintHeader(FILE *fp) |
249 |
{ |
250 |
fprintf(fp, "name");
|
251 |
fprintf(fp, ",file_size,putc,putc_cpu,put_block,put_block_cpu,rewrite,rewrite_cpu,getc,getc_cpu,get_block,get_block_cpu,seeks,seeks_cpu");
|
252 |
fprintf(fp, ",num_files,seq_create,seq_create_cpu,seq_stat,seq_stat_cpu,seq_del,seq_del_cpu,ran_create,ran_create_cpu,ran_stat,ran_stat_cpu,ran_del,ran_del_cpu");
|
253 |
fprintf(fp, "\n");
|
254 |
fflush(NULL);
|
255 |
} |
256 |
|
257 |
int
|
258 |
BonTimer::DoReport(CPCCHAR machine, int file_size, int directory_size |
259 |
, int max_size, int min_size, int num_directories |
260 |
, int chunk_size, FILE *fp)
|
261 |
{ |
262 |
m_fp = fp; |
263 |
m_file_size = file_size; |
264 |
m_directory_size = directory_size; |
265 |
m_chunk_size = chunk_size; |
266 |
const int txt_machine_size = 20; |
267 |
if(m_file_size)
|
268 |
{ |
269 |
if(m_type == txt)
|
270 |
{ |
271 |
fprintf(m_fp, "Version %5s ", BON_VERSION);
|
272 |
fprintf(m_fp, |
273 |
"------Sequential Output------ --Sequential Input- --Random-\n");
|
274 |
fprintf(m_fp, " ");
|
275 |
fprintf(m_fp, |
276 |
"-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--\n");
|
277 |
if(m_chunk_size == DefaultChunkSize)
|
278 |
fprintf(m_fp, "Machine Size ");
|
279 |
else
|
280 |
fprintf(m_fp, "Machine Size:chnk ");
|
281 |
fprintf(m_fp, "K/sec %%CP K/sec %%CP K/sec %%CP K/sec %%CP K/sec ");
|
282 |
fprintf(m_fp, "%%CP /sec %%CP\n");
|
283 |
} |
284 |
char size_buf[1024]; |
285 |
if(m_file_size % 1024 == 0) |
286 |
sprintf(size_buf, "%dG", m_file_size / 1024); |
287 |
else
|
288 |
sprintf(size_buf, "%dM", m_file_size);
|
289 |
if(m_chunk_size != DefaultChunkSize)
|
290 |
{ |
291 |
char *tmp = size_buf + strlen(size_buf);
|
292 |
if(m_chunk_size >= 1024) |
293 |
sprintf(tmp, ":%dk", m_chunk_size / 1024); |
294 |
else
|
295 |
sprintf(tmp, ":%d", m_chunk_size);
|
296 |
} |
297 |
char buf[4096]; |
298 |
if(m_type == txt)
|
299 |
{ |
300 |
// copy machine name to buf
|
301 |
//
|
302 |
snprintf(buf |
303 |
#ifndef NO_SNPRINTF
|
304 |
, txt_machine_size - 1
|
305 |
#endif
|
306 |
, "%s ", machine);
|
307 |
buf[txt_machine_size - 1] = '\0'; |
308 |
// set cur to point to a byte past where we end the machine name
|
309 |
// size of the buf - size of the new data - 1 for the space - 1 for the
|
310 |
// terminating zero on the string
|
311 |
char *cur = &buf[txt_machine_size - strlen(size_buf) - 2]; |
312 |
*cur = ' '; // make cur a space |
313 |
cur++; // increment to where we store the size
|
314 |
strcpy(cur, size_buf); // copy the size in
|
315 |
fputs(buf, m_fp); |
316 |
} |
317 |
else
|
318 |
{ |
319 |
printf("%s,%s", machine, size_buf);
|
320 |
} |
321 |
print_stat(Putc); |
322 |
print_stat(FastWrite); |
323 |
print_stat(ReWrite); |
324 |
print_stat(Getc); |
325 |
print_stat(FastRead); |
326 |
print_stat(Lseek); |
327 |
if(m_type == txt)
|
328 |
fprintf(m_fp, "\n");
|
329 |
} |
330 |
else if(m_type == csv) |
331 |
{ |
332 |
fprintf(m_fp, "%s,,,,,,,,,,,,,", machine);
|
333 |
} |
334 |
|
335 |
if(m_directory_size)
|
336 |
{ |
337 |
char buf[128]; |
338 |
char *tmp;
|
339 |
sprintf(buf, "%d", m_directory_size);
|
340 |
if(max_size == -1) |
341 |
{ |
342 |
strcat(buf, ":link");
|
343 |
} |
344 |
else if(max_size == -2) |
345 |
{ |
346 |
strcat(buf, ":symlink");
|
347 |
} |
348 |
else if(max_size) |
349 |
{ |
350 |
tmp = &buf[strlen(buf)]; |
351 |
sprintf(tmp, ":%d:%d", max_size, min_size);
|
352 |
} |
353 |
if(num_directories > 1) |
354 |
{ |
355 |
tmp = &buf[strlen(buf)]; |
356 |
sprintf(tmp, "/%d", num_directories);
|
357 |
} |
358 |
if(m_type == txt)
|
359 |
{ |
360 |
if(m_file_size)
|
361 |
fprintf(m_fp, " ");
|
362 |
else
|
363 |
fprintf(m_fp, "Version %5s ", BON_VERSION);
|
364 |
fprintf(m_fp, |
365 |
"------Sequential Create------ --------Random Create--------\n");
|
366 |
if(m_file_size)
|
367 |
fprintf(m_fp, " ");
|
368 |
else
|
369 |
fprintf(m_fp, "%-19.19s ", machine);
|
370 |
fprintf(m_fp, |
371 |
"-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--\n");
|
372 |
if(min_size)
|
373 |
{ |
374 |
fprintf(m_fp, "files:max:min ");
|
375 |
} |
376 |
else
|
377 |
{ |
378 |
if(max_size)
|
379 |
fprintf(m_fp, "files:max ");
|
380 |
else
|
381 |
fprintf(m_fp, " files ");
|
382 |
} |
383 |
fprintf(m_fp, " /sec %%CP /sec %%CP /sec %%CP /sec %%CP /sec ");
|
384 |
fprintf(m_fp, "%%CP /sec %%CP\n");
|
385 |
fprintf(m_fp, "%19s", buf);
|
386 |
} |
387 |
else
|
388 |
{ |
389 |
fprintf(m_fp, ",%s", buf);
|
390 |
} |
391 |
print_file_stat(CreateSeq); |
392 |
print_file_stat(StatSeq); |
393 |
print_file_stat(DelSeq); |
394 |
print_file_stat(CreateRand); |
395 |
print_file_stat(StatRand); |
396 |
print_file_stat(DelRand); |
397 |
fprintf(m_fp, "\n");
|
398 |
} |
399 |
else if(m_type == csv) |
400 |
{ |
401 |
fprintf(m_fp, ",,,,,,,,,,,,,\n");
|
402 |
} |
403 |
fflush(stdout); |
404 |
return 0; |
405 |
} |
406 |
|