Skip to content

Commit 0a8396e

Browse files
committed
Change contrib/pg_test_fsync to control tests in terms of seconds per
test, rather than a number of test cycles. Changes -o/cycles option to -s/seconds.
1 parent dc66f1c commit 0a8396e

File tree

2 files changed

+65
-51
lines changed

2 files changed

+65
-51
lines changed

contrib/pg_test_fsync/pg_test_fsync.c

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,31 @@
2727
#define NA_FORMAT "%18s"
2828
#define OPS_FORMAT "%9.3f ops/sec"
2929

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+
3045
static const char *progname;
3146

32-
static int ops_per_test = 2000;
47+
static int secs_per_test = 2;
3348
static int needs_unlink = 0;
3449
static char full_buf[XLOG_SEG_SIZE],
3550
*buf,
3651
*filename = FSYNC_FILENAME;
3752
static struct timeval start_t,
3853
stop_t;
54+
static bool alarm_triggered = false;
3955

4056

4157
static void handle_args(int argc, char *argv[]);
@@ -46,12 +62,13 @@ static void test_sync(int writes_per_op);
4662
static void test_open_syncs(void);
4763
static void test_open_sync(const char *msg, int writes_size);
4864
static void test_file_descriptor_sync(void);
65+
static void process_alarm(int sig);
4966
static void signal_cleanup(int sig);
5067

5168
#ifdef HAVE_FSYNC_WRITETHROUGH
5269
static int pg_fsync_writethrough(int fd);
5370
#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);
5572
static void die(const char *str);
5673

5774

@@ -65,6 +82,7 @@ main(int argc, char *argv[])
6582
/* Prevent leaving behind the test file */
6683
signal(SIGINT, signal_cleanup);
6784
signal(SIGTERM, signal_cleanup);
85+
signal(SIGALRM, process_alarm);
6886
#ifdef SIGHUP
6987
/* Not defined on win32 */
7088
signal(SIGHUP, signal_cleanup);
@@ -96,7 +114,7 @@ handle_args(int argc, char *argv[])
96114
{
97115
static struct option long_options[] = {
98116
{"filename", required_argument, NULL, 'f'},
99-
{"ops-per-test", required_argument, NULL, 'o'},
117+
{"secs-per-test", required_argument, NULL, 's'},
100118
{NULL, 0, NULL, 0}
101119
};
102120
int option; /* Command line option */
@@ -107,7 +125,7 @@ handle_args(int argc, char *argv[])
107125
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ||
108126
strcmp(argv[1], "-?") == 0)
109127
{
110-
printf("Usage: %s [-f FILENAME] [-o OPS-PER-TEST]\n", progname);
128+
printf("Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n", progname);
111129
exit(0);
112130
}
113131
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
@@ -117,7 +135,7 @@ handle_args(int argc, char *argv[])
117135
}
118136
}
119137

120-
while ((option = getopt_long(argc, argv, "f:o:",
138+
while ((option = getopt_long(argc, argv, "f:s:",
121139
long_options, &optindex)) != -1)
122140
{
123141
switch (option)
@@ -126,8 +144,8 @@ handle_args(int argc, char *argv[])
126144
filename = strdup(optarg);
127145
break;
128146

129-
case 'o':
130-
ops_per_test = atoi(optarg);
147+
case 's':
148+
secs_per_test = atoi(optarg);
131149
break;
132150

133151
default:
@@ -148,7 +166,7 @@ handle_args(int argc, char *argv[])
148166
exit(1);
149167
}
150168

151-
printf("%d operations per test\n", ops_per_test);
169+
printf("%d seconds per test\n", secs_per_test);
152170
#if PG_O_DIRECT != 0
153171
printf("O_DIRECT supported on this platform for open_datasync and open_sync.\n");
154172
#else
@@ -220,18 +238,17 @@ test_sync(int writes_per_op)
220238
{
221239
if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT, 0)) == -1)
222240
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++)
225243
{
226244
for (writes = 0; writes < writes_per_op; writes++)
227245
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
228246
die("write failed");
229247
if (lseek(tmpfile, 0, SEEK_SET) == -1)
230248
die("seek failed");
231249
}
232-
gettimeofday(&stop_t, NULL);
250+
STOP_TIMER;
233251
close(tmpfile);
234-
print_elapse(start_t, stop_t);
235252
}
236253
#else
237254
printf(NA_FORMAT, "n/a\n");
@@ -246,8 +263,8 @@ test_sync(int writes_per_op)
246263
#ifdef HAVE_FDATASYNC
247264
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
248265
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++)
251268
{
252269
for (writes = 0; writes < writes_per_op; writes++)
253270
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -256,9 +273,8 @@ test_sync(int writes_per_op)
256273
if (lseek(tmpfile, 0, SEEK_SET) == -1)
257274
die("seek failed");
258275
}
259-
gettimeofday(&stop_t, NULL);
276+
STOP_TIMER;
260277
close(tmpfile);
261-
print_elapse(start_t, stop_t);
262278
#else
263279
printf(NA_FORMAT, "n/a\n");
264280
#endif
@@ -271,8 +287,8 @@ test_sync(int writes_per_op)
271287

272288
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
273289
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++)
276292
{
277293
for (writes = 0; writes < writes_per_op; writes++)
278294
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -282,9 +298,8 @@ test_sync(int writes_per_op)
282298
if (lseek(tmpfile, 0, SEEK_SET) == -1)
283299
die("seek failed");
284300
}
285-
gettimeofday(&stop_t, NULL);
301+
STOP_TIMER;
286302
close(tmpfile);
287-
print_elapse(start_t, stop_t);
288303

289304
/*
290305
* If fsync_writethrough is available, test as well
@@ -295,8 +310,8 @@ test_sync(int writes_per_op)
295310
#ifdef HAVE_FSYNC_WRITETHROUGH
296311
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
297312
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++)
300315
{
301316
for (writes = 0; writes < writes_per_op; writes++)
302317
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -306,9 +321,8 @@ test_sync(int writes_per_op)
306321
if (lseek(tmpfile, 0, SEEK_SET) == -1)
307322
die("seek failed");
308323
}
309-
gettimeofday(&stop_t, NULL);
324+
STOP_TIMER;
310325
close(tmpfile);
311-
print_elapse(start_t, stop_t);
312326
#else
313327
printf(NA_FORMAT, "n/a\n");
314328
#endif
@@ -327,18 +341,17 @@ test_sync(int writes_per_op)
327341
}
328342
else
329343
{
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++)
332346
{
333347
for (writes = 0; writes < writes_per_op; writes++)
334348
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
335349
die("write failed");
336350
if (lseek(tmpfile, 0, SEEK_SET) == -1)
337351
die("seek failed");
338352
}
339-
gettimeofday(&stop_t, NULL);
353+
STOP_TIMER;
340354
close(tmpfile);
341-
print_elapse(start_t, stop_t);
342355
}
343356
#else
344357
printf(NA_FORMAT, "n/a\n");
@@ -385,8 +398,8 @@ test_open_sync(const char *msg, int writes_size)
385398
printf(NA_FORMAT, "n/a*\n");
386399
else
387400
{
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++)
390403
{
391404
for (writes = 0; writes < 16 / writes_size; writes++)
392405
if (write(tmpfile, buf, writes_size * 1024) !=
@@ -395,9 +408,8 @@ test_open_sync(const char *msg, int writes_size)
395408
if (lseek(tmpfile, 0, SEEK_SET) == -1)
396409
die("seek failed");
397410
}
398-
gettimeofday(&stop_t, NULL);
411+
STOP_TIMER;
399412
close(tmpfile);
400-
print_elapse(start_t, stop_t);
401413
}
402414
#else
403415
printf(NA_FORMAT, "n/a\n");
@@ -427,8 +439,8 @@ test_file_descriptor_sync(void)
427439
printf(LABEL_FORMAT, "write, fsync, close");
428440
fflush(stdout);
429441

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++)
432444
{
433445
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
434446
die("could not open output file");
@@ -446,8 +458,7 @@ test_file_descriptor_sync(void)
446458
die("could not open output file");
447459
close(tmpfile);
448460
}
449-
gettimeofday(&stop_t, NULL);
450-
print_elapse(start_t, stop_t);
461+
STOP_TIMER;
451462

452463
/*
453464
* Now open, write, close, open again and fsync This simulates processes
@@ -456,8 +467,8 @@ test_file_descriptor_sync(void)
456467
printf(LABEL_FORMAT, "write, close, fsync");
457468
fflush(stdout);
458469

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++)
461472
{
462473
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
463474
die("could not open output file");
@@ -471,9 +482,7 @@ test_file_descriptor_sync(void)
471482
die("fsync failed");
472483
close(tmpfile);
473484
}
474-
gettimeofday(&stop_t, NULL);
475-
print_elapse(start_t, stop_t);
476-
485+
STOP_TIMER;
477486
}
478487

479488
static void
@@ -489,17 +498,16 @@ test_non_sync(void)
489498
printf(LABEL_FORMAT, "write");
490499
fflush(stdout);
491500

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++)
494503
{
495504
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
496505
die("could not open output file");
497506
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
498507
die("write failed");
499508
close(tmpfile);
500509
}
501-
gettimeofday(&stop_t, NULL);
502-
print_elapse(start_t, stop_t);
510+
STOP_TIMER;
503511
}
504512

505513
static void
@@ -533,15 +541,21 @@ pg_fsync_writethrough(int fd)
533541
* print out the writes per second for tests
534542
*/
535543
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)
537545
{
538546
double total_time = (stop_t.tv_sec - start_t.tv_sec) +
539547
(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;
541549

542550
printf(OPS_FORMAT "\n", per_second);
543551
}
544552

553+
static void
554+
process_alarm(int sig)
555+
{
556+
alarm_triggered = true;
557+
}
558+
545559
static void
546560
die(const char *str)
547561
{

doc/src/sgml/pgtestfsync.sgml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ pg_test_fsync [options]
4747
</varlistentry>
4848

4949
<varlistentry>
50-
<term><option>-o</option></term>
51-
<term><option>--ops-per-test</option></term>
50+
<term><option>-s</option></term>
51+
<term><option>--secs-per-test</option></term>
5252
<listitem>
5353
<para>
54-
Specifies the number of operations per test. The more operations
54+
Specifies the number of seconds for each test. The more time
5555
per test, the greater the test's accuracy, but the longer it takes
56-
to run. The default is 2000.
56+
to run. The default is 2 seconds.
5757
</para>
5858
</listitem>
5959
</varlistentry>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy