27
27
#define NA_FORMAT "%18s"
28
28
#define OPS_FORMAT "%9.3f ops/sec"
29
29
30
+ /* These are macros to avoid timing the function call overhead. */
31
+ #define START_TIMER \
32
+ do { \
33
+ alarm_triggered = false; \
34
+ alarm(secs_per_test); \
35
+ gettimeofday(&start_t, NULL); \
36
+ } while (0)
37
+
38
+ #define STOP_TIMER \
39
+ do { \
40
+ gettimeofday(&stop_t, NULL); \
41
+ print_elapse(start_t, stop_t, ops); \
42
+ } while (0)
43
+
44
+
30
45
static const char * progname ;
31
46
32
- static int ops_per_test = 2000 ;
47
+ static int secs_per_test = 2 ;
33
48
static int needs_unlink = 0 ;
34
49
static char full_buf [XLOG_SEG_SIZE ],
35
50
* buf ,
36
51
* filename = FSYNC_FILENAME ;
37
52
static struct timeval start_t ,
38
53
stop_t ;
54
+ static bool alarm_triggered = false;
39
55
40
56
41
57
static void handle_args (int argc , char * argv []);
@@ -46,12 +62,13 @@ static void test_sync(int writes_per_op);
46
62
static void test_open_syncs (void );
47
63
static void test_open_sync (const char * msg , int writes_size );
48
64
static void test_file_descriptor_sync (void );
65
+ static void process_alarm (int sig );
49
66
static void signal_cleanup (int sig );
50
67
51
68
#ifdef HAVE_FSYNC_WRITETHROUGH
52
69
static int pg_fsync_writethrough (int fd );
53
70
#endif
54
- static void print_elapse (struct timeval start_t , struct timeval stop_t );
71
+ static void print_elapse (struct timeval start_t , struct timeval stop_t , int ops );
55
72
static void die (const char * str );
56
73
57
74
@@ -65,6 +82,7 @@ main(int argc, char *argv[])
65
82
/* Prevent leaving behind the test file */
66
83
signal (SIGINT , signal_cleanup );
67
84
signal (SIGTERM , signal_cleanup );
85
+ signal (SIGALRM , process_alarm );
68
86
#ifdef SIGHUP
69
87
/* Not defined on win32 */
70
88
signal (SIGHUP , signal_cleanup );
@@ -96,7 +114,7 @@ handle_args(int argc, char *argv[])
96
114
{
97
115
static struct option long_options [] = {
98
116
{"filename" , required_argument , NULL , 'f' },
99
- {"ops -per-test" , required_argument , NULL , 'o ' },
117
+ {"secs -per-test" , required_argument , NULL , 's ' },
100
118
{NULL , 0 , NULL , 0 }
101
119
};
102
120
int option ; /* Command line option */
@@ -107,7 +125,7 @@ handle_args(int argc, char *argv[])
107
125
if (strcmp (argv [1 ], "--help" ) == 0 || strcmp (argv [1 ], "-h" ) == 0 ||
108
126
strcmp (argv [1 ], "-?" ) == 0 )
109
127
{
110
- printf ("Usage: %s [-f FILENAME] [-o OPS -PER-TEST]\n" , progname );
128
+ printf ("Usage: %s [-f FILENAME] [-s SECS -PER-TEST]\n" , progname );
111
129
exit (0 );
112
130
}
113
131
if (strcmp (argv [1 ], "--version" ) == 0 || strcmp (argv [1 ], "-V" ) == 0 )
@@ -117,7 +135,7 @@ handle_args(int argc, char *argv[])
117
135
}
118
136
}
119
137
120
- while ((option = getopt_long (argc , argv , "f:o :" ,
138
+ while ((option = getopt_long (argc , argv , "f:s :" ,
121
139
long_options , & optindex )) != -1 )
122
140
{
123
141
switch (option )
@@ -126,8 +144,8 @@ handle_args(int argc, char *argv[])
126
144
filename = strdup (optarg );
127
145
break ;
128
146
129
- case 'o ' :
130
- ops_per_test = atoi (optarg );
147
+ case 's ' :
148
+ secs_per_test = atoi (optarg );
131
149
break ;
132
150
133
151
default :
@@ -148,7 +166,7 @@ handle_args(int argc, char *argv[])
148
166
exit (1 );
149
167
}
150
168
151
- printf ("%d operations per test\n" , ops_per_test );
169
+ printf ("%d seconds per test\n" , secs_per_test );
152
170
#if PG_O_DIRECT != 0
153
171
printf ("O_DIRECT supported on this platform for open_datasync and open_sync.\n" );
154
172
#else
@@ -220,18 +238,17 @@ test_sync(int writes_per_op)
220
238
{
221
239
if ((tmpfile = open (filename , O_RDWR | O_DSYNC | PG_O_DIRECT , 0 )) == -1 )
222
240
die ("could not open output file" );
223
- gettimeofday ( & start_t , NULL ) ;
224
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
241
+ START_TIMER ;
242
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
225
243
{
226
244
for (writes = 0 ; writes < writes_per_op ; writes ++ )
227
245
if (write (tmpfile , buf , XLOG_BLCKSZ ) != XLOG_BLCKSZ )
228
246
die ("write failed" );
229
247
if (lseek (tmpfile , 0 , SEEK_SET ) == -1 )
230
248
die ("seek failed" );
231
249
}
232
- gettimeofday ( & stop_t , NULL ) ;
250
+ STOP_TIMER ;
233
251
close (tmpfile );
234
- print_elapse (start_t , stop_t );
235
252
}
236
253
#else
237
254
printf (NA_FORMAT , "n/a\n" );
@@ -246,8 +263,8 @@ test_sync(int writes_per_op)
246
263
#ifdef HAVE_FDATASYNC
247
264
if ((tmpfile = open (filename , O_RDWR , 0 )) == -1 )
248
265
die ("could not open output file" );
249
- gettimeofday ( & start_t , NULL ) ;
250
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
266
+ START_TIMER ;
267
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
251
268
{
252
269
for (writes = 0 ; writes < writes_per_op ; writes ++ )
253
270
if (write (tmpfile , buf , XLOG_BLCKSZ ) != XLOG_BLCKSZ )
@@ -256,9 +273,8 @@ test_sync(int writes_per_op)
256
273
if (lseek (tmpfile , 0 , SEEK_SET ) == -1 )
257
274
die ("seek failed" );
258
275
}
259
- gettimeofday ( & stop_t , NULL ) ;
276
+ STOP_TIMER ;
260
277
close (tmpfile );
261
- print_elapse (start_t , stop_t );
262
278
#else
263
279
printf (NA_FORMAT , "n/a\n" );
264
280
#endif
@@ -271,8 +287,8 @@ test_sync(int writes_per_op)
271
287
272
288
if ((tmpfile = open (filename , O_RDWR , 0 )) == -1 )
273
289
die ("could not open output file" );
274
- gettimeofday ( & start_t , NULL ) ;
275
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
290
+ START_TIMER ;
291
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
276
292
{
277
293
for (writes = 0 ; writes < writes_per_op ; writes ++ )
278
294
if (write (tmpfile , buf , XLOG_BLCKSZ ) != XLOG_BLCKSZ )
@@ -282,9 +298,8 @@ test_sync(int writes_per_op)
282
298
if (lseek (tmpfile , 0 , SEEK_SET ) == -1 )
283
299
die ("seek failed" );
284
300
}
285
- gettimeofday ( & stop_t , NULL ) ;
301
+ STOP_TIMER ;
286
302
close (tmpfile );
287
- print_elapse (start_t , stop_t );
288
303
289
304
/*
290
305
* If fsync_writethrough is available, test as well
@@ -295,8 +310,8 @@ test_sync(int writes_per_op)
295
310
#ifdef HAVE_FSYNC_WRITETHROUGH
296
311
if ((tmpfile = open (filename , O_RDWR , 0 )) == -1 )
297
312
die ("could not open output file" );
298
- gettimeofday ( & start_t , NULL ) ;
299
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
313
+ START_TIMER ;
314
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
300
315
{
301
316
for (writes = 0 ; writes < writes_per_op ; writes ++ )
302
317
if (write (tmpfile , buf , XLOG_BLCKSZ ) != XLOG_BLCKSZ )
@@ -306,9 +321,8 @@ test_sync(int writes_per_op)
306
321
if (lseek (tmpfile , 0 , SEEK_SET ) == -1 )
307
322
die ("seek failed" );
308
323
}
309
- gettimeofday ( & stop_t , NULL ) ;
324
+ STOP_TIMER ;
310
325
close (tmpfile );
311
- print_elapse (start_t , stop_t );
312
326
#else
313
327
printf (NA_FORMAT , "n/a\n" );
314
328
#endif
@@ -327,18 +341,17 @@ test_sync(int writes_per_op)
327
341
}
328
342
else
329
343
{
330
- gettimeofday ( & start_t , NULL ) ;
331
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
344
+ START_TIMER ;
345
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
332
346
{
333
347
for (writes = 0 ; writes < writes_per_op ; writes ++ )
334
348
if (write (tmpfile , buf , XLOG_BLCKSZ ) != XLOG_BLCKSZ )
335
349
die ("write failed" );
336
350
if (lseek (tmpfile , 0 , SEEK_SET ) == -1 )
337
351
die ("seek failed" );
338
352
}
339
- gettimeofday ( & stop_t , NULL ) ;
353
+ STOP_TIMER ;
340
354
close (tmpfile );
341
- print_elapse (start_t , stop_t );
342
355
}
343
356
#else
344
357
printf (NA_FORMAT , "n/a\n" );
@@ -385,8 +398,8 @@ test_open_sync(const char *msg, int writes_size)
385
398
printf (NA_FORMAT , "n/a*\n" );
386
399
else
387
400
{
388
- gettimeofday ( & start_t , NULL ) ;
389
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
401
+ START_TIMER ;
402
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
390
403
{
391
404
for (writes = 0 ; writes < 16 / writes_size ; writes ++ )
392
405
if (write (tmpfile , buf , writes_size * 1024 ) !=
@@ -395,9 +408,8 @@ test_open_sync(const char *msg, int writes_size)
395
408
if (lseek (tmpfile , 0 , SEEK_SET ) == -1 )
396
409
die ("seek failed" );
397
410
}
398
- gettimeofday ( & stop_t , NULL ) ;
411
+ STOP_TIMER ;
399
412
close (tmpfile );
400
- print_elapse (start_t , stop_t );
401
413
}
402
414
#else
403
415
printf (NA_FORMAT , "n/a\n" );
@@ -427,8 +439,8 @@ test_file_descriptor_sync(void)
427
439
printf (LABEL_FORMAT , "write, fsync, close" );
428
440
fflush (stdout );
429
441
430
- gettimeofday ( & start_t , NULL ) ;
431
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
442
+ START_TIMER ;
443
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
432
444
{
433
445
if ((tmpfile = open (filename , O_RDWR , 0 )) == -1 )
434
446
die ("could not open output file" );
@@ -446,8 +458,7 @@ test_file_descriptor_sync(void)
446
458
die ("could not open output file" );
447
459
close (tmpfile );
448
460
}
449
- gettimeofday (& stop_t , NULL );
450
- print_elapse (start_t , stop_t );
461
+ STOP_TIMER ;
451
462
452
463
/*
453
464
* Now open, write, close, open again and fsync This simulates processes
@@ -456,8 +467,8 @@ test_file_descriptor_sync(void)
456
467
printf (LABEL_FORMAT , "write, close, fsync" );
457
468
fflush (stdout );
458
469
459
- gettimeofday ( & start_t , NULL ) ;
460
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
470
+ START_TIMER ;
471
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
461
472
{
462
473
if ((tmpfile = open (filename , O_RDWR , 0 )) == -1 )
463
474
die ("could not open output file" );
@@ -471,9 +482,7 @@ test_file_descriptor_sync(void)
471
482
die ("fsync failed" );
472
483
close (tmpfile );
473
484
}
474
- gettimeofday (& stop_t , NULL );
475
- print_elapse (start_t , stop_t );
476
-
485
+ STOP_TIMER ;
477
486
}
478
487
479
488
static void
@@ -489,17 +498,16 @@ test_non_sync(void)
489
498
printf (LABEL_FORMAT , "write" );
490
499
fflush (stdout );
491
500
492
- gettimeofday ( & start_t , NULL ) ;
493
- for (ops = 0 ; ops < ops_per_test ; ops ++ )
501
+ START_TIMER ;
502
+ for (ops = 0 ; alarm_triggered == false ; ops ++ )
494
503
{
495
504
if ((tmpfile = open (filename , O_RDWR , 0 )) == -1 )
496
505
die ("could not open output file" );
497
506
if (write (tmpfile , buf , XLOG_BLCKSZ ) != XLOG_BLCKSZ )
498
507
die ("write failed" );
499
508
close (tmpfile );
500
509
}
501
- gettimeofday (& stop_t , NULL );
502
- print_elapse (start_t , stop_t );
510
+ STOP_TIMER ;
503
511
}
504
512
505
513
static void
@@ -533,15 +541,21 @@ pg_fsync_writethrough(int fd)
533
541
* print out the writes per second for tests
534
542
*/
535
543
static void
536
- print_elapse (struct timeval start_t , struct timeval stop_t )
544
+ print_elapse (struct timeval start_t , struct timeval stop_t , int ops )
537
545
{
538
546
double total_time = (stop_t .tv_sec - start_t .tv_sec ) +
539
547
(stop_t .tv_usec - start_t .tv_usec ) * 0.000001 ;
540
- double per_second = ops_per_test / total_time ;
548
+ double per_second = ops / total_time ;
541
549
542
550
printf (OPS_FORMAT "\n" , per_second );
543
551
}
544
552
553
+ static void
554
+ process_alarm (int sig )
555
+ {
556
+ alarm_triggered = true;
557
+ }
558
+
545
559
static void
546
560
die (const char * str )
547
561
{
0 commit comments