[block][biotime] Add a -iter switch to biotime.
Add a -iter switch to biotime, to allow the test to run repeatedly many
times. This is a convenience in terms of being able to run biotime in
the background, while collecting data on the serial console. Thanks to
Venkatesh for suggesting this.
Test: Test the new -iter switch with different iter values.
Change-Id: I67b39c1d5b393c0f4a5c3dc8dcf58f99329f601a
diff --git a/zircon/system/uapp/biotime/biotime.cpp b/zircon/system/uapp/biotime/biotime.cpp
index bd5f651..cb7b6f7 100644
--- a/zircon/system/uapp/biotime/biotime.cpp
+++ b/zircon/system/uapp/biotime/biotime.cpp
@@ -276,6 +276,7 @@
"\n"
"args: -bs <num> transfer block size (multiple of 4K)\n"
" -total-bytes-to-transfer <num> total amount to read or write\n"
+ " -iter <num-iterations> total number of iterations (0 stands for infinite)\n"
" -mo <num> maximum outstanding ops (1..128)\n"
" -read test reading from the block device (default)\n"
" -write test writing to the block device\n"
@@ -301,12 +302,15 @@
bool live_dangerously = false;
bio_random_args_t a = {};
+ bool opt_write = false;
+ bool opt_linear = true;
+ int opt_max_pending = 128;
+ size_t opt_xfer_size = 32768;
+ uint64_t opt_num_iter = 1;
+ bool loop_forever = false;
+
a.blk = &blk;
- a.xfer = 32768;
a.seed = 7891263897612ULL;
- a.max_pending = 128;
- a.write = false;
- a.linear = true;
const char* output_file = nullptr;
size_t total = 0;
@@ -318,8 +322,8 @@
}
if (!strcmp(argv[0], "-bs")) {
needparam();
- a.xfer = number(argv[0]);
- if ((a.xfer == 0) || (a.xfer % 4096)) {
+ opt_xfer_size = number(argv[0]);
+ if ((opt_xfer_size == 0) || (opt_xfer_size % 4096)) {
error("error: block size must be multiple of 4K\n");
}
} else if (!strcmp(argv[0], "-total-bytes-to-transfer")) {
@@ -331,23 +335,28 @@
if ((n < 1) || (n > 128)) {
error("error: max pending must be between 1 and 128\n");
}
- a.max_pending = static_cast<int>(n);
+ opt_max_pending = static_cast<int>(n);
} else if (!strcmp(argv[0], "-read")) {
- a.write = false;
+ opt_write = false;
} else if (!strcmp(argv[0], "-write")) {
- a.write = true;
+ opt_write = true;
} else if (!strcmp(argv[0], "-live-dangerously")) {
live_dangerously = true;
} else if (!strcmp(argv[0], "-linear")) {
- a.linear = true;
+ opt_linear = true;
} else if (!strcmp(argv[0], "-random")) {
- a.linear = false;
+ opt_linear = false;
} else if (!strcmp(argv[0], "-output-file")) {
needparam();
output_file = argv[0];
} else if (!strcmp(argv[0], "-h")) {
usage();
return 0;
+ } else if (!strcmp(argv[0], "-iter")) {
+ needparam();
+ opt_num_iter = strtoull(argv[0], NULL, 10);
+ if (opt_num_iter == 0)
+ loop_forever = true;
} else {
error("error: unknown option: %s\n", argv[0]);
}
@@ -365,44 +374,51 @@
}
const char* device_filename = argv[0];
- int fd;
- if ((fd = open(device_filename, O_RDONLY)) < 0) {
- fprintf(stderr, "error: cannot open '%s'\n", device_filename);
- return -1;
- }
- if (blkdev_open(fd, device_filename, 8*1024*1024, &blk) != ZX_OK) {
- return -1;
- }
-
- size_t devtotal = blk.info.block_count * blk.info.block_size;
-
- // default to entire device
- if ((total == 0) || (total > devtotal)) {
- total = devtotal;
- }
- a.count = total / a.xfer;
-
- zx_duration_t res = 0;
- total = 0;
- if (bio_random(&a, &total, &res) != ZX_OK) {
- return -1;
- }
-
- fprintf(stderr, "%zu bytes in %zu ns: ", total, res);
- bytes_per_second(total, res);
- fprintf(stderr, "%zu ops in %zu ns: ", a.count, res);
- ops_per_second(a.count, res);
-
- if (output_file) {
- perftest::ResultsSet results;
- auto* test_case = results.AddTestCase(
- "fuchsia.zircon", "BlockDeviceThroughput", "bytes/second");
- double time_in_seconds = static_cast<double>(res) / 1e9;
- test_case->AppendValue(static_cast<double>(total) / time_in_seconds);
- if (!results.WriteJSONFile(output_file)) {
- return 1;
+ do {
+ int fd;
+ a.xfer = opt_xfer_size;
+ a.max_pending = opt_max_pending;
+ a.write = opt_write;
+ a.linear = opt_linear;
+ if ((fd = open(device_filename, O_RDONLY)) < 0) {
+ fprintf(stderr, "error: cannot open '%s'\n", device_filename);
+ return -1;
}
- }
+ if (blkdev_open(fd, device_filename, 8*1024*1024, &blk) != ZX_OK) {
+ return -1;
+ }
+
+ size_t devtotal = blk.info.block_count * blk.info.block_size;
+
+ // default to entire device
+ if ((total == 0) || (total > devtotal)) {
+ total = devtotal;
+ }
+ a.count = total / a.xfer;
+
+ zx_duration_t res = 0;
+ total = 0;
+ if (bio_random(&a, &total, &res) != ZX_OK) {
+ return -1;
+ }
+
+ fprintf(stderr, "%zu bytes in %zu ns: ", total, res);
+ bytes_per_second(total, res);
+ fprintf(stderr, "%zu ops in %zu ns: ", a.count, res);
+ ops_per_second(a.count, res);
+
+ if (output_file) {
+ perftest::ResultsSet results;
+ auto* test_case = results.AddTestCase(
+ "fuchsia.zircon", "BlockDeviceThroughput", "bytes/second");
+ double time_in_seconds = static_cast<double>(res) / 1e9;
+ test_case->AppendValue(static_cast<double>(total) / time_in_seconds);
+ if (!results.WriteJSONFile(output_file)) {
+ return 1;
+ }
+ }
+ blkdev_close(&blk);
+ } while (loop_forever || (--opt_num_iter > 0));
return 0;
}