b179bf855d6fa6b56dff525ce5bc0a38997eb0d3
[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 = ns/N;
67         if (n == 0)
68                 n = SEC;
69         else
70                 n = SEC/n;
71         if (n > N*100ULL)
72                 n = N*100ULL;
73         else if (n <= N)
74                 n = N+1;
75         if (n > MAXN)
76                 n = MAXN;
77         return n;
78 }
79
80 static void run(const char *name, void (*f)()) {
81         fprintf(stderr, "%s:", name);
82         for (N=1; ; N=nextN()) {
83                 reset_timer();
84                 start_timer();
85                 f();
86                 stop_timer();
87 //              fprintf(stderr, "%10d%12llu\n", N, ns);
88                 if (ns > SEC || N >= MAXN)
89                         break;
90                 if (N <= 0) {
91                         fprintf(stderr, "bench: fatal: N <= 0\n");
92                         return;
93                 }
94         }
95         if (ns/N > 100)
96                 fprintf(stderr, "%10d%10llu ns/op\n", N, ns/N);
97         else
98                 fprintf(stderr, "%10d%13.2f ns/op\n", N, (double)ns/N);
99 }
100
101 int main() {
102 #define B(t) run(#t, t);
103 #include "main.h"
104         return 0;
105 }