aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2012-02-14 11:09:49 -0500
committerBruce Momjian <bruce@momjian.us>2012-02-14 11:10:03 -0500
commit0a8396e35e2e230da7539372b32968c0d959fba8 (patch)
treed3faee5f3a4a0a9a9e0763095ed8508824ceb91f
parentdc66f1c5f2a6e93d949252a0ad661388e1fe7856 (diff)
downloadpostgresql-0a8396e35e2e230da7539372b32968c0d959fba8.tar.gz
postgresql-0a8396e35e2e230da7539372b32968c0d959fba8.zip
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.
-rw-r--r--contrib/pg_test_fsync/pg_test_fsync.c108
-rw-r--r--doc/src/sgml/pgtestfsync.sgml8
2 files changed, 65 insertions, 51 deletions
diff --git a/contrib/pg_test_fsync/pg_test_fsync.c b/contrib/pg_test_fsync/pg_test_fsync.c
index 3fcb087f2a2..02a9e2112fd 100644
--- a/contrib/pg_test_fsync/pg_test_fsync.c
+++ b/contrib/pg_test_fsync/pg_test_fsync.c
@@ -27,15 +27,31 @@
#define NA_FORMAT "%18s"
#define OPS_FORMAT "%9.3f ops/sec"
+/* These are macros to avoid timing the function call overhead. */
+#define START_TIMER \
+do { \
+ alarm_triggered = false; \
+ alarm(secs_per_test); \
+ gettimeofday(&start_t, NULL); \
+} while (0)
+
+#define STOP_TIMER \
+do { \
+ gettimeofday(&stop_t, NULL); \
+ print_elapse(start_t, stop_t, ops); \
+} while (0)
+
+
static const char *progname;
-static int ops_per_test = 2000;
+static int secs_per_test = 2;
static int needs_unlink = 0;
static char full_buf[XLOG_SEG_SIZE],
*buf,
*filename = FSYNC_FILENAME;
static struct timeval start_t,
stop_t;
+static bool alarm_triggered = false;
static void handle_args(int argc, char *argv[]);
@@ -46,12 +62,13 @@ static void test_sync(int writes_per_op);
static void test_open_syncs(void);
static void test_open_sync(const char *msg, int writes_size);
static void test_file_descriptor_sync(void);
+static void process_alarm(int sig);
static void signal_cleanup(int sig);
#ifdef HAVE_FSYNC_WRITETHROUGH
static int pg_fsync_writethrough(int fd);
#endif
-static void print_elapse(struct timeval start_t, struct timeval stop_t);
+static void print_elapse(struct timeval start_t, struct timeval stop_t, int ops);
static void die(const char *str);
@@ -65,6 +82,7 @@ main(int argc, char *argv[])
/* Prevent leaving behind the test file */
signal(SIGINT, signal_cleanup);
signal(SIGTERM, signal_cleanup);
+ signal(SIGALRM, process_alarm);
#ifdef SIGHUP
/* Not defined on win32 */
signal(SIGHUP, signal_cleanup);
@@ -96,7 +114,7 @@ handle_args(int argc, char *argv[])
{
static struct option long_options[] = {
{"filename", required_argument, NULL, 'f'},
- {"ops-per-test", required_argument, NULL, 'o'},
+ {"secs-per-test", required_argument, NULL, 's'},
{NULL, 0, NULL, 0}
};
int option; /* Command line option */
@@ -107,7 +125,7 @@ handle_args(int argc, char *argv[])
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ||
strcmp(argv[1], "-?") == 0)
{
- printf("Usage: %s [-f FILENAME] [-o OPS-PER-TEST]\n", progname);
+ printf("Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n", progname);
exit(0);
}
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
@@ -117,7 +135,7 @@ handle_args(int argc, char *argv[])
}
}
- while ((option = getopt_long(argc, argv, "f:o:",
+ while ((option = getopt_long(argc, argv, "f:s:",
long_options, &optindex)) != -1)
{
switch (option)
@@ -126,8 +144,8 @@ handle_args(int argc, char *argv[])
filename = strdup(optarg);
break;
- case 'o':
- ops_per_test = atoi(optarg);
+ case 's':
+ secs_per_test = atoi(optarg);
break;
default:
@@ -148,7 +166,7 @@ handle_args(int argc, char *argv[])
exit(1);
}
- printf("%d operations per test\n", ops_per_test);
+ printf("%d seconds per test\n", secs_per_test);
#if PG_O_DIRECT != 0
printf("O_DIRECT supported on this platform for open_datasync and open_sync.\n");
#else
@@ -220,8 +238,8 @@ test_sync(int writes_per_op)
{
if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT, 0)) == -1)
die("could not open output file");
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
for (writes = 0; writes < writes_per_op; writes++)
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -229,9 +247,8 @@ test_sync(int writes_per_op)
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
- gettimeofday(&stop_t, NULL);
+ STOP_TIMER;
close(tmpfile);
- print_elapse(start_t, stop_t);
}
#else
printf(NA_FORMAT, "n/a\n");
@@ -246,8 +263,8 @@ test_sync(int writes_per_op)
#ifdef HAVE_FDATASYNC
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
die("could not open output file");
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
for (writes = 0; writes < writes_per_op; writes++)
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -256,9 +273,8 @@ test_sync(int writes_per_op)
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
- gettimeofday(&stop_t, NULL);
+ STOP_TIMER;
close(tmpfile);
- print_elapse(start_t, stop_t);
#else
printf(NA_FORMAT, "n/a\n");
#endif
@@ -271,8 +287,8 @@ test_sync(int writes_per_op)
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
die("could not open output file");
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
for (writes = 0; writes < writes_per_op; writes++)
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -282,9 +298,8 @@ test_sync(int writes_per_op)
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
- gettimeofday(&stop_t, NULL);
+ STOP_TIMER;
close(tmpfile);
- print_elapse(start_t, stop_t);
/*
* If fsync_writethrough is available, test as well
@@ -295,8 +310,8 @@ test_sync(int writes_per_op)
#ifdef HAVE_FSYNC_WRITETHROUGH
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
die("could not open output file");
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
for (writes = 0; writes < writes_per_op; writes++)
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -306,9 +321,8 @@ test_sync(int writes_per_op)
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
- gettimeofday(&stop_t, NULL);
+ STOP_TIMER;
close(tmpfile);
- print_elapse(start_t, stop_t);
#else
printf(NA_FORMAT, "n/a\n");
#endif
@@ -327,8 +341,8 @@ test_sync(int writes_per_op)
}
else
{
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
for (writes = 0; writes < writes_per_op; writes++)
if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
@@ -336,9 +350,8 @@ test_sync(int writes_per_op)
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
- gettimeofday(&stop_t, NULL);
+ STOP_TIMER;
close(tmpfile);
- print_elapse(start_t, stop_t);
}
#else
printf(NA_FORMAT, "n/a\n");
@@ -385,8 +398,8 @@ test_open_sync(const char *msg, int writes_size)
printf(NA_FORMAT, "n/a*\n");
else
{
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
for (writes = 0; writes < 16 / writes_size; writes++)
if (write(tmpfile, buf, writes_size * 1024) !=
@@ -395,9 +408,8 @@ test_open_sync(const char *msg, int writes_size)
if (lseek(tmpfile, 0, SEEK_SET) == -1)
die("seek failed");
}
- gettimeofday(&stop_t, NULL);
+ STOP_TIMER;
close(tmpfile);
- print_elapse(start_t, stop_t);
}
#else
printf(NA_FORMAT, "n/a\n");
@@ -427,8 +439,8 @@ test_file_descriptor_sync(void)
printf(LABEL_FORMAT, "write, fsync, close");
fflush(stdout);
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
die("could not open output file");
@@ -446,8 +458,7 @@ test_file_descriptor_sync(void)
die("could not open output file");
close(tmpfile);
}
- gettimeofday(&stop_t, NULL);
- print_elapse(start_t, stop_t);
+ STOP_TIMER;
/*
* Now open, write, close, open again and fsync This simulates processes
@@ -456,8 +467,8 @@ test_file_descriptor_sync(void)
printf(LABEL_FORMAT, "write, close, fsync");
fflush(stdout);
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
die("could not open output file");
@@ -471,9 +482,7 @@ test_file_descriptor_sync(void)
die("fsync failed");
close(tmpfile);
}
- gettimeofday(&stop_t, NULL);
- print_elapse(start_t, stop_t);
-
+ STOP_TIMER;
}
static void
@@ -489,8 +498,8 @@ test_non_sync(void)
printf(LABEL_FORMAT, "write");
fflush(stdout);
- gettimeofday(&start_t, NULL);
- for (ops = 0; ops < ops_per_test; ops++)
+ START_TIMER;
+ for (ops = 0; alarm_triggered == false; ops++)
{
if ((tmpfile = open(filename, O_RDWR, 0)) == -1)
die("could not open output file");
@@ -498,8 +507,7 @@ test_non_sync(void)
die("write failed");
close(tmpfile);
}
- gettimeofday(&stop_t, NULL);
- print_elapse(start_t, stop_t);
+ STOP_TIMER;
}
static void
@@ -533,16 +541,22 @@ pg_fsync_writethrough(int fd)
* print out the writes per second for tests
*/
static void
-print_elapse(struct timeval start_t, struct timeval stop_t)
+print_elapse(struct timeval start_t, struct timeval stop_t, int ops)
{
double total_time = (stop_t.tv_sec - start_t.tv_sec) +
(stop_t.tv_usec - start_t.tv_usec) * 0.000001;
- double per_second = ops_per_test / total_time;
+ double per_second = ops / total_time;
printf(OPS_FORMAT "\n", per_second);
}
static void
+process_alarm(int sig)
+{
+ alarm_triggered = true;
+}
+
+static void
die(const char *str)
{
fprintf(stderr, "%s: %s\n", str, strerror(errno));
diff --git a/doc/src/sgml/pgtestfsync.sgml b/doc/src/sgml/pgtestfsync.sgml
index 2889059c82c..ba9f0c1eb18 100644
--- a/doc/src/sgml/pgtestfsync.sgml
+++ b/doc/src/sgml/pgtestfsync.sgml
@@ -47,13 +47,13 @@ pg_test_fsync [options]
</varlistentry>
<varlistentry>
- <term><option>-o</option></term>
- <term><option>--ops-per-test</option></term>
+ <term><option>-s</option></term>
+ <term><option>--secs-per-test</option></term>
<listitem>
<para>
- Specifies the number of operations per test. The more operations
+ Specifies the number of seconds for each test. The more time
per test, the greater the test's accuracy, but the longer it takes
- to run. The default is 2000.
+ to run. The default is 2 seconds.
</para>
</listitem>
</varlistentry>