summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/timebench.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/cmd/timebench.c b/src/cmd/timebench.c
new file mode 100644
index 0000000..9985c7f
--- /dev/null
+++ b/src/cmd/timebench.c
@@ -0,0 +1,98 @@
+#include <camellia.h>
+#include <camellia/syscalls.h>
+#include <err.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+uint64_t
+gettime_ascii(hid_t h)
+{
+ char buf[32];
+ _sys_read(h, buf, 32, 0);
+ return strtol(buf, NULL, 10);
+}
+
+uint64_t
+gettime_binary(hid_t h)
+{
+ uint64_t t;
+ _sys_read(h, &t, 8, 0);
+ return t;
+}
+
+uint64_t
+gettime_syscall(hid_t)
+{
+ return _sys_time(0);
+}
+
+void
+usage(int ret)
+{
+ fprintf(stderr,
+ "usage: timebench [-a file | -b file | -s]\n"
+ " e.g. timebench -a /dev/ntp\n"
+ " timebench -b /dev/bintime\n"
+ " timebench -s\n"
+ );
+ exit(ret);
+}
+
+int
+main(int argc, char *argv[])
+{
+ uint64_t (*fn)(hid_t) = NULL;
+ hid_t h = -1;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "abs")) != -1) {
+ switch (opt) {
+ case 'a':
+ if (fn) usage(1);
+ fn = gettime_ascii;
+ break;
+ case 'b':
+ if (fn) usage(1);
+ fn = gettime_binary;
+ break;
+ case 's':
+ if (fn) usage(1);
+ fn = gettime_syscall;
+ break;
+ default:
+ usage(1);
+ }
+ }
+ if (fn == NULL) {
+ usage(1);
+ } else if (fn == gettime_syscall) {
+ if (optind < argc) {
+ usage(1);
+ }
+ } else {
+ if (optind + 1 != argc) {
+ usage(1);
+ }
+ h = camellia_open(argv[optind], OPEN_READ);
+ if (h < 0) {
+ err(1, "open %s", argv[optind]);
+ }
+ }
+
+ uint64_t target = 5000l * 1000000l;
+ uint64_t start;
+ uint64_t count = 0;
+ uint64_t last;
+
+ start = fn(h);
+ target += start;
+ for (;;) {
+ last = fn(h);
+ count++;
+ if (last >= target) break;
+ }
+ printf("%lu calls in %lums\n", count, (last-start) / 1000000);
+ printf("%luμs per call\n", (last-start) / count);
+ printf("last %lu\n", last);
+}