1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sys/syscall.h>
18 #include <sys/time.h>
19 #include <time.h>
20 #include <unistd.h>
21 
22 #include <benchmark/benchmark.h>
23 #include "util.h"
24 
25 // Musl doesn't define __NR_gettimeofday, __NR_clock_gettime32, __NR_gettimeofday_time32 or
26 // __NR_clock_getres on 32-bit architectures.
27 #if !defined(__NR_gettimeofday)
28 #define __NR_gettimeofday __NR_gettimeofday_time32
29 #endif
30 #if !defined(__NR_clock_gettime)
31 #define __NR_clock_gettime __NR_clock_gettime32
32 #endif
33 #if !defined(__NR_gettimeofday)
34 #define __NR_gettimeofday __NR_gettimeofday_time32
35 #endif
36 #if !defined(__NR_clock_getres)
37 #define __NR_clock_getres __NR_clock_getres_time32
38 #endif
39 
BM_time_clock_gettime(benchmark::State & state)40 static void BM_time_clock_gettime(benchmark::State& state) {
41   // CLOCK_MONOTONIC is required supported in vdso
42   timespec t;
43   while (state.KeepRunning()) {
44     clock_gettime(CLOCK_MONOTONIC, &t);
45   }
46 }
47 BIONIC_BENCHMARK(BM_time_clock_gettime);
48 
BM_time_clock_gettime_syscall(benchmark::State & state)49 static void BM_time_clock_gettime_syscall(benchmark::State& state) {
50   // CLOCK_MONOTONIC is required supported in vdso
51   timespec t;
52   while (state.KeepRunning()) {
53     syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &t);
54   }
55 }
56 BIONIC_BENCHMARK(BM_time_clock_gettime_syscall);
57 
BM_time_clock_gettime_MONOTONIC_COARSE(benchmark::State & state)58 static void BM_time_clock_gettime_MONOTONIC_COARSE(benchmark::State& state) {
59   // CLOCK_MONOTONIC_COARSE is required supported in vdso
60   timespec t;
61   while (state.KeepRunning()) {
62     clock_gettime(CLOCK_MONOTONIC_COARSE, &t);
63   }
64 }
65 BIONIC_BENCHMARK(BM_time_clock_gettime_MONOTONIC_COARSE);
66 
BM_time_clock_gettime_MONOTONIC_RAW(benchmark::State & state)67 static void BM_time_clock_gettime_MONOTONIC_RAW(benchmark::State& state) {
68   // CLOCK_MONOTONIC_RAW is required supported in vdso
69   timespec t;
70   while (state.KeepRunning()) {
71     clock_gettime(CLOCK_MONOTONIC_RAW, &t);
72   }
73 }
74 BIONIC_BENCHMARK(BM_time_clock_gettime_MONOTONIC_RAW);
75 
BM_time_clock_gettime_REALTIME(benchmark::State & state)76 static void BM_time_clock_gettime_REALTIME(benchmark::State& state) {
77   // CLOCK_REALTIME is required supported in vdso
78   timespec t;
79   while (state.KeepRunning()) {
80     clock_gettime(CLOCK_REALTIME, &t);
81   }
82 }
83 BIONIC_BENCHMARK(BM_time_clock_gettime_REALTIME);
84 
BM_time_clock_gettime_REALTIME_COARSE(benchmark::State & state)85 static void BM_time_clock_gettime_REALTIME_COARSE(benchmark::State& state) {
86   // CLOCK_REALTIME_COARSE is required supported in vdso
87   timespec t;
88   while (state.KeepRunning()) {
89     clock_gettime(CLOCK_REALTIME_COARSE, &t);
90   }
91 }
92 BIONIC_BENCHMARK(BM_time_clock_gettime_REALTIME_COARSE);
93 
BM_time_clock_gettime_BOOTTIME(benchmark::State & state)94 static void BM_time_clock_gettime_BOOTTIME(benchmark::State& state) {
95   // CLOCK_BOOTTIME is optionally supported in vdso
96   timespec t;
97   while (state.KeepRunning()) {
98     clock_gettime(CLOCK_BOOTTIME, &t);
99   }
100 }
101 BIONIC_BENCHMARK(BM_time_clock_gettime_BOOTTIME);
102 
BM_time_clock_getres(benchmark::State & state)103 static void BM_time_clock_getres(benchmark::State& state) {
104   // CLOCK_MONOTONIC is required supported in vdso
105   timespec t;
106   while (state.KeepRunning()) {
107     clock_getres(CLOCK_MONOTONIC, &t);
108   }
109 }
110 BIONIC_BENCHMARK(BM_time_clock_getres);
111 
BM_time_clock_getres_syscall(benchmark::State & state)112 static void BM_time_clock_getres_syscall(benchmark::State& state) {
113   // CLOCK_MONOTONIC is required supported in vdso
114   timespec t;
115   while (state.KeepRunning()) {
116     syscall(__NR_clock_getres, CLOCK_MONOTONIC, &t);
117   }
118 }
119 BIONIC_BENCHMARK(BM_time_clock_getres_syscall);
120 
BM_time_clock_getres_MONOTONIC_COARSE(benchmark::State & state)121 static void BM_time_clock_getres_MONOTONIC_COARSE(benchmark::State& state) {
122   // CLOCK_MONOTONIC_COARSE is required supported in vdso
123   timespec t;
124   while (state.KeepRunning()) {
125     clock_getres(CLOCK_MONOTONIC_COARSE, &t);
126   }
127 }
128 BIONIC_BENCHMARK(BM_time_clock_getres_MONOTONIC_COARSE);
129 
BM_time_clock_getres_MONOTONIC_RAW(benchmark::State & state)130 static void BM_time_clock_getres_MONOTONIC_RAW(benchmark::State& state) {
131   // CLOCK_MONOTONIC_RAW is required supported in vdso
132   timespec t;
133   while (state.KeepRunning()) {
134     clock_getres(CLOCK_MONOTONIC_RAW, &t);
135   }
136 }
137 BIONIC_BENCHMARK(BM_time_clock_getres_MONOTONIC_RAW);
138 
BM_time_clock_getres_REALTIME(benchmark::State & state)139 static void BM_time_clock_getres_REALTIME(benchmark::State& state) {
140   // CLOCK_REALTIME is required supported in vdso
141   timespec t;
142   while (state.KeepRunning()) {
143     clock_getres(CLOCK_REALTIME, &t);
144   }
145 }
146 BIONIC_BENCHMARK(BM_time_clock_getres_REALTIME);
147 
BM_time_clock_getres_REALTIME_COARSE(benchmark::State & state)148 static void BM_time_clock_getres_REALTIME_COARSE(benchmark::State& state) {
149   // CLOCK_REALTIME_COARSE is required supported in vdso
150   timespec t;
151   while (state.KeepRunning()) {
152     clock_getres(CLOCK_REALTIME_COARSE, &t);
153   }
154 }
155 BIONIC_BENCHMARK(BM_time_clock_getres_REALTIME_COARSE);
156 
BM_time_clock_getres_BOOTTIME(benchmark::State & state)157 static void BM_time_clock_getres_BOOTTIME(benchmark::State& state) {
158   // CLOCK_BOOTTIME is optionally supported in vdso
159   timespec t;
160   while (state.KeepRunning()) {
161     clock_getres(CLOCK_BOOTTIME, &t);
162   }
163 }
164 BIONIC_BENCHMARK(BM_time_clock_getres_BOOTTIME);
165 
BM_time_gettimeofday(benchmark::State & state)166 static void BM_time_gettimeofday(benchmark::State& state) {
167   timeval tv;
168   while (state.KeepRunning()) {
169     gettimeofday(&tv, nullptr);
170   }
171 }
172 BIONIC_BENCHMARK(BM_time_gettimeofday);
173 
BM_time_gettimeofday_syscall(benchmark::State & state)174 void BM_time_gettimeofday_syscall(benchmark::State& state) {
175   timeval tv;
176   while (state.KeepRunning()) {
177     syscall(__NR_gettimeofday, &tv, nullptr);
178   }
179 }
180 BIONIC_BENCHMARK(BM_time_gettimeofday_syscall);
181 
BM_time_time(benchmark::State & state)182 void BM_time_time(benchmark::State& state) {
183   while (state.KeepRunning()) {
184     time(nullptr);
185   }
186 }
187 BIONIC_BENCHMARK(BM_time_time);
188 
BM_time_localtime(benchmark::State & state)189 void BM_time_localtime(benchmark::State& state) {
190   time_t t = time(nullptr);
191   while (state.KeepRunning()) {
192     localtime(&t);
193   }
194 }
195 BIONIC_BENCHMARK(BM_time_localtime);
196 
BM_time_localtime_r(benchmark::State & state)197 void BM_time_localtime_r(benchmark::State& state) {
198   time_t t = time(nullptr);
199   while (state.KeepRunning()) {
200     struct tm tm;
201     localtime_r(&t, &tm);
202   }
203 }
204 BIONIC_BENCHMARK(BM_time_localtime_r);
205 
BM_time_strftime(benchmark::State & state)206 void BM_time_strftime(benchmark::State& state) {
207   char buf[128];
208   time_t t = 0;
209   struct tm* tm = gmtime(&t);
210   while (state.KeepRunning()) {
211     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
212   }
213 }
214 BIONIC_BENCHMARK(BM_time_strftime);
215