Statistics
| Branch: | Revision:

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