bench: use CLOCK_MONOTONIC
[libc-test] / common / bench.c
1 #define _POSIX_C_SOURCE 200809L
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <time.h>
7 #include "test.h"
8
9 #define T(t)
10 #define B(t) void t();
11 #include "main.h"
12 #undef B
13
14 //static int verbose;
15
16 void error__(const char *n, int l, const char *s, ...) {
17         fprintf(stderr, "use error in tests only\n");
18 }
19
20 int N;
21 static unsigned long long start;
22 static unsigned long long ns;
23 //static unsigned long long bytes;
24
25 #define SEC  1000000000ULL
26 #define MAXN 1000000000
27
28 static unsigned long long nsclock() {
29         struct timespec ts;
30         int r;
31
32         r = clock_gettime(CLOCK_MONOTONIC, &ts);
33         if (r < 0) {
34                 fprintf(stderr, "bench: clock_gettime failed: %s\n", strerror(errno));
35                 return 0;
36         }
37         return ts.tv_sec*SEC + ts.tv_nsec;
38 }
39
40 void start_timer() {
41         if (!start)
42                 start = nsclock();
43 }
44
45 void stop_timer() {
46         if (start)
47                 ns += nsclock() - start;
48         start = 0;
49 }
50
51 void reset_timer() {
52         if (start)
53                 start = nsclock();
54         ns = 0;
55 }
56
57 static int nextN() {
58         unsigned long long n = ns/N;
59
60         if (n)
61                 n = SEC/n;
62         else
63                 n = SEC;
64         n += n/4;
65         if (n > N*100ULL)
66                 n = N*100ULL;
67         else if (n <= N)
68                 n = N+1;
69         if (n > MAXN)
70                 n = MAXN;
71         return n;
72 }
73
74 static void run(const char *name, void (*f)()) {
75         fprintf(stderr, "%s:", name);
76         for (N=1; ; N=nextN()) {
77                 reset_timer();
78                 start_timer();
79                 f();
80                 stop_timer();
81 //              fprintf(stderr, "%10d%12llu\n", N, ns);
82                 if (ns > SEC || N >= MAXN)
83                         break;
84                 if (N <= 0) {
85                         fprintf(stderr, "bench: fatal: N <= 0\n");
86                         return;
87                 }
88         }
89         if (ns/N > 100)
90                 fprintf(stderr, "%10d%10llu ns/op\n", N, ns/N);
91         else
92                 fprintf(stderr, "%10d%13.2f ns/op\n", N, (double)ns/N);
93 }
94
95 int main() {
96 #define B(t) run(#t, t);
97 #include "main.h"
98         return 0;
99 }