0436f67b8c5a2d1b7cb867d395dd46db17a0d19a
[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 #ifdef _POSIX_CPUTIME
33         r = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
34 #else
35 #ifdef _POSIX_MONOTONIC_CLOCK
36         r = clock_gettime(CLOCK_MONOTONIC, &ts);
37 #else
38         r = clock_gettime(CLOCK_REALTIME, &ts);
39 #endif
40 #endif
41         if (r < 0) {
42                 fprintf(stderr, "bench: clock_gettime failed: %s\n", strerror(errno));
43                 return 0;
44         }
45         return ts.tv_sec*SEC + ts.tv_nsec;
46 }
47
48 void start_timer() {
49         if (!start)
50                 start = nsclock();
51 }
52
53 void stop_timer() {
54         if (start)
55                 ns += nsclock() - start;
56         start = 0;
57 }
58
59 void reset_timer() {
60         if (start)
61                 start = nsclock();
62         ns = 0;
63 }
64
65 static int nextN() {
66         unsigned long long n = 2*SEC/(ns/N + 1);
67         if (n > N*100ULL)
68                 n = N*100ULL;
69         else if (n <= N)
70                 n = N+1;
71         if (n > MAXN)
72                 n = MAXN;
73         return n;
74 }
75
76 static void run(const char *name, void (*f)()) {
77         fprintf(stderr, "%s:", name);
78         for (N=1; ; N=nextN()) {
79                 reset_timer();
80                 start_timer();
81                 f();
82                 stop_timer();
83 //              fprintf(stderr, "%10d%12llu\n", N, ns);
84                 if (ns > SEC || N >= MAXN)
85                         break;
86                 if (N <= 0) {
87                         fprintf(stderr, "bench: fatal: N <= 0\n");
88                         return;
89                 }
90         }
91         if (ns/N > 100)
92                 fprintf(stderr, "%10d%10llu ns/op\n", N, ns/N);
93         else
94                 fprintf(stderr, "%10d%13.2f ns/op\n", N, (double)ns/N);
95 }
96
97 int main() {
98 #define B(t) run(#t, t);
99 #include "main.h"
100         return 0;
101 }