xref: /aosp_15_r20/system/logging/liblog/tests/liblog_benchmark.cpp (revision 598139dc91b21518d67c408eaea2644226490971)
1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker  * Copyright (C) 2013-2014 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker  *
4*598139dcSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker  *
8*598139dcSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker  *
10*598139dcSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker  * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker  */
16*598139dcSAndroid Build Coastguard Worker 
17*598139dcSAndroid Build Coastguard Worker #include <fcntl.h>
18*598139dcSAndroid Build Coastguard Worker #include <inttypes.h>
19*598139dcSAndroid Build Coastguard Worker #include <poll.h>
20*598139dcSAndroid Build Coastguard Worker #include <sched.h>
21*598139dcSAndroid Build Coastguard Worker #include <signal.h>
22*598139dcSAndroid Build Coastguard Worker #include <sys/socket.h>
23*598139dcSAndroid Build Coastguard Worker #include <sys/syscall.h>
24*598139dcSAndroid Build Coastguard Worker #include <sys/types.h>
25*598139dcSAndroid Build Coastguard Worker #include <sys/uio.h>
26*598139dcSAndroid Build Coastguard Worker #include <unistd.h>
27*598139dcSAndroid Build Coastguard Worker 
28*598139dcSAndroid Build Coastguard Worker #include <unordered_set>
29*598139dcSAndroid Build Coastguard Worker 
30*598139dcSAndroid Build Coastguard Worker #include <android-base/file.h>
31*598139dcSAndroid Build Coastguard Worker #include <android-base/properties.h>
32*598139dcSAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
33*598139dcSAndroid Build Coastguard Worker #include <cutils/sockets.h>
34*598139dcSAndroid Build Coastguard Worker #include <log/event_tag_map.h>
35*598139dcSAndroid Build Coastguard Worker #include <log/log_read.h>
36*598139dcSAndroid Build Coastguard Worker #include <private/android_logger.h>
37*598139dcSAndroid Build Coastguard Worker 
38*598139dcSAndroid Build Coastguard Worker #include "test_utils.h"
39*598139dcSAndroid Build Coastguard Worker 
40*598139dcSAndroid Build Coastguard Worker size_t convertPrintable(char*, const char*, size_t);
41*598139dcSAndroid Build Coastguard Worker 
42*598139dcSAndroid Build Coastguard Worker BENCHMARK_MAIN();
43*598139dcSAndroid Build Coastguard Worker 
44*598139dcSAndroid Build Coastguard Worker // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
45*598139dcSAndroid Build Coastguard Worker // non-syscall libs. Since we are benchmarking, or using this in the emergency
46*598139dcSAndroid Build Coastguard Worker // signal to stuff a terminating code, we do NOT want to introduce
47*598139dcSAndroid Build Coastguard Worker // a syscall or usleep on EAGAIN retry.
48*598139dcSAndroid Build Coastguard Worker #define LOG_FAILURE_RETRY(exp)                                           \
49*598139dcSAndroid Build Coastguard Worker   ({                                                                     \
50*598139dcSAndroid Build Coastguard Worker     typeof(exp) _rc;                                                     \
51*598139dcSAndroid Build Coastguard Worker     do {                                                                 \
52*598139dcSAndroid Build Coastguard Worker       _rc = (exp);                                                       \
53*598139dcSAndroid Build Coastguard Worker     } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \
54*598139dcSAndroid Build Coastguard Worker              (_rc == -EINTR) || (_rc == -EAGAIN));                       \
55*598139dcSAndroid Build Coastguard Worker     _rc;                                                                 \
56*598139dcSAndroid Build Coastguard Worker   })
57*598139dcSAndroid Build Coastguard Worker 
58*598139dcSAndroid Build Coastguard Worker /*
59*598139dcSAndroid Build Coastguard Worker  *	Measure the fastest rate we can reliabley stuff print messages into
60*598139dcSAndroid Build Coastguard Worker  * the log at high pressure. Expect this to be less than double the process
61*598139dcSAndroid Build Coastguard Worker  * wakeup time (2ms?)
62*598139dcSAndroid Build Coastguard Worker  */
BM_log_maximum_retry(benchmark::State & state)63*598139dcSAndroid Build Coastguard Worker static void BM_log_maximum_retry(benchmark::State& state) {
64*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
65*598139dcSAndroid Build Coastguard Worker     LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_INFO, "BM_log_maximum_retry", "%" PRIu64,
66*598139dcSAndroid Build Coastguard Worker                                           state.iterations()));
67*598139dcSAndroid Build Coastguard Worker   }
68*598139dcSAndroid Build Coastguard Worker }
69*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_maximum_retry);
70*598139dcSAndroid Build Coastguard Worker 
71*598139dcSAndroid Build Coastguard Worker /*
72*598139dcSAndroid Build Coastguard Worker  *	Measure the fastest rate we can stuff print messages into the log
73*598139dcSAndroid Build Coastguard Worker  * at high pressure. Expect this to be less than double the process wakeup
74*598139dcSAndroid Build Coastguard Worker  * time (2ms?)
75*598139dcSAndroid Build Coastguard Worker  */
BM_log_maximum(benchmark::State & state)76*598139dcSAndroid Build Coastguard Worker static void BM_log_maximum(benchmark::State& state) {
77*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
78*598139dcSAndroid Build Coastguard Worker     __android_log_print(ANDROID_LOG_INFO, "BM_log_maximum", "%" PRIu64, state.iterations());
79*598139dcSAndroid Build Coastguard Worker   }
80*598139dcSAndroid Build Coastguard Worker }
81*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_maximum);
82*598139dcSAndroid Build Coastguard Worker 
83*598139dcSAndroid Build Coastguard Worker /*
84*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes to collect the time using
85*598139dcSAndroid Build Coastguard Worker  * discrete acquisition (state.PauseTiming() to state.ResumeTiming())
86*598139dcSAndroid Build Coastguard Worker  * under light load. Expect this to be a syscall period (2us) or
87*598139dcSAndroid Build Coastguard Worker  * data read time if zero-syscall.
88*598139dcSAndroid Build Coastguard Worker  *
89*598139dcSAndroid Build Coastguard Worker  * vdso support in the kernel and the library can allow
90*598139dcSAndroid Build Coastguard Worker  * clock_gettime to be zero-syscall, but there there does remain some
91*598139dcSAndroid Build Coastguard Worker  * benchmarking overhead to pause and resume; assumptions are both are
92*598139dcSAndroid Build Coastguard Worker  * covered.
93*598139dcSAndroid Build Coastguard Worker  */
BM_clock_overhead(benchmark::State & state)94*598139dcSAndroid Build Coastguard Worker static void BM_clock_overhead(benchmark::State& state) {
95*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
96*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
97*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
98*598139dcSAndroid Build Coastguard Worker   }
99*598139dcSAndroid Build Coastguard Worker }
100*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_clock_overhead);
101*598139dcSAndroid Build Coastguard Worker 
do_clock_overhead(benchmark::State & state,clockid_t clk_id)102*598139dcSAndroid Build Coastguard Worker static void do_clock_overhead(benchmark::State& state, clockid_t clk_id) {
103*598139dcSAndroid Build Coastguard Worker   timespec t;
104*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
105*598139dcSAndroid Build Coastguard Worker     clock_gettime(clk_id, &t);
106*598139dcSAndroid Build Coastguard Worker   }
107*598139dcSAndroid Build Coastguard Worker }
108*598139dcSAndroid Build Coastguard Worker 
BM_time_clock_gettime_REALTIME(benchmark::State & state)109*598139dcSAndroid Build Coastguard Worker static void BM_time_clock_gettime_REALTIME(benchmark::State& state) {
110*598139dcSAndroid Build Coastguard Worker   do_clock_overhead(state, CLOCK_REALTIME);
111*598139dcSAndroid Build Coastguard Worker }
112*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_clock_gettime_REALTIME);
113*598139dcSAndroid Build Coastguard Worker 
BM_time_clock_gettime_MONOTONIC(benchmark::State & state)114*598139dcSAndroid Build Coastguard Worker static void BM_time_clock_gettime_MONOTONIC(benchmark::State& state) {
115*598139dcSAndroid Build Coastguard Worker   do_clock_overhead(state, CLOCK_MONOTONIC);
116*598139dcSAndroid Build Coastguard Worker }
117*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_clock_gettime_MONOTONIC);
118*598139dcSAndroid Build Coastguard Worker 
BM_time_clock_gettime_MONOTONIC_syscall(benchmark::State & state)119*598139dcSAndroid Build Coastguard Worker static void BM_time_clock_gettime_MONOTONIC_syscall(benchmark::State& state) {
120*598139dcSAndroid Build Coastguard Worker   timespec t;
121*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
122*598139dcSAndroid Build Coastguard Worker     syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &t);
123*598139dcSAndroid Build Coastguard Worker   }
124*598139dcSAndroid Build Coastguard Worker }
125*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_clock_gettime_MONOTONIC_syscall);
126*598139dcSAndroid Build Coastguard Worker 
BM_time_clock_gettime_MONOTONIC_RAW(benchmark::State & state)127*598139dcSAndroid Build Coastguard Worker static void BM_time_clock_gettime_MONOTONIC_RAW(benchmark::State& state) {
128*598139dcSAndroid Build Coastguard Worker   do_clock_overhead(state, CLOCK_MONOTONIC_RAW);
129*598139dcSAndroid Build Coastguard Worker }
130*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_clock_gettime_MONOTONIC_RAW);
131*598139dcSAndroid Build Coastguard Worker 
BM_time_clock_gettime_BOOTTIME(benchmark::State & state)132*598139dcSAndroid Build Coastguard Worker static void BM_time_clock_gettime_BOOTTIME(benchmark::State& state) {
133*598139dcSAndroid Build Coastguard Worker   do_clock_overhead(state, CLOCK_BOOTTIME);
134*598139dcSAndroid Build Coastguard Worker }
135*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_clock_gettime_BOOTTIME);
136*598139dcSAndroid Build Coastguard Worker 
BM_time_clock_getres_MONOTONIC(benchmark::State & state)137*598139dcSAndroid Build Coastguard Worker static void BM_time_clock_getres_MONOTONIC(benchmark::State& state) {
138*598139dcSAndroid Build Coastguard Worker   timespec t;
139*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
140*598139dcSAndroid Build Coastguard Worker     clock_getres(CLOCK_MONOTONIC, &t);
141*598139dcSAndroid Build Coastguard Worker   }
142*598139dcSAndroid Build Coastguard Worker }
143*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_clock_getres_MONOTONIC);
144*598139dcSAndroid Build Coastguard Worker 
BM_time_clock_getres_MONOTONIC_syscall(benchmark::State & state)145*598139dcSAndroid Build Coastguard Worker static void BM_time_clock_getres_MONOTONIC_syscall(benchmark::State& state) {
146*598139dcSAndroid Build Coastguard Worker   timespec t;
147*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
148*598139dcSAndroid Build Coastguard Worker     syscall(__NR_clock_getres, CLOCK_MONOTONIC, &t);
149*598139dcSAndroid Build Coastguard Worker   }
150*598139dcSAndroid Build Coastguard Worker }
151*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_clock_getres_MONOTONIC_syscall);
152*598139dcSAndroid Build Coastguard Worker 
BM_time_time(benchmark::State & state)153*598139dcSAndroid Build Coastguard Worker static void BM_time_time(benchmark::State& state) {
154*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
155*598139dcSAndroid Build Coastguard Worker     time_t now;
156*598139dcSAndroid Build Coastguard Worker     now = time(&now);
157*598139dcSAndroid Build Coastguard Worker   }
158*598139dcSAndroid Build Coastguard Worker }
159*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_time_time);
160*598139dcSAndroid Build Coastguard Worker 
161*598139dcSAndroid Build Coastguard Worker /*
162*598139dcSAndroid Build Coastguard Worker  * Measure the time it takes to submit the android logging data to pstore
163*598139dcSAndroid Build Coastguard Worker  */
BM_pmsg_short(benchmark::State & state)164*598139dcSAndroid Build Coastguard Worker static void BM_pmsg_short(benchmark::State& state) {
165*598139dcSAndroid Build Coastguard Worker   int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
166*598139dcSAndroid Build Coastguard Worker   if (pstore_fd < 0) {
167*598139dcSAndroid Build Coastguard Worker     state.SkipWithError("/dev/pmsg0");
168*598139dcSAndroid Build Coastguard Worker     return;
169*598139dcSAndroid Build Coastguard Worker   }
170*598139dcSAndroid Build Coastguard Worker 
171*598139dcSAndroid Build Coastguard Worker   /*
172*598139dcSAndroid Build Coastguard Worker    *  struct {
173*598139dcSAndroid Build Coastguard Worker    *      // what we provide to pstore
174*598139dcSAndroid Build Coastguard Worker    *      android_pmsg_log_header_t pmsg_header;
175*598139dcSAndroid Build Coastguard Worker    *      // what we provide to socket
176*598139dcSAndroid Build Coastguard Worker    *      android_log_header_t header;
177*598139dcSAndroid Build Coastguard Worker    *      // caller provides
178*598139dcSAndroid Build Coastguard Worker    *      union {
179*598139dcSAndroid Build Coastguard Worker    *          struct {
180*598139dcSAndroid Build Coastguard Worker    *              char     prio;
181*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
182*598139dcSAndroid Build Coastguard Worker    *          } string;
183*598139dcSAndroid Build Coastguard Worker    *          struct {
184*598139dcSAndroid Build Coastguard Worker    *              uint32_t tag
185*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
186*598139dcSAndroid Build Coastguard Worker    *          } binary;
187*598139dcSAndroid Build Coastguard Worker    *      };
188*598139dcSAndroid Build Coastguard Worker    *  };
189*598139dcSAndroid Build Coastguard Worker    */
190*598139dcSAndroid Build Coastguard Worker 
191*598139dcSAndroid Build Coastguard Worker   struct timespec ts;
192*598139dcSAndroid Build Coastguard Worker   clock_gettime(CLOCK_REALTIME, &ts);
193*598139dcSAndroid Build Coastguard Worker 
194*598139dcSAndroid Build Coastguard Worker   android_pmsg_log_header_t pmsg_header;
195*598139dcSAndroid Build Coastguard Worker   pmsg_header.magic = LOGGER_MAGIC;
196*598139dcSAndroid Build Coastguard Worker   pmsg_header.len =
197*598139dcSAndroid Build Coastguard Worker       sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
198*598139dcSAndroid Build Coastguard Worker   pmsg_header.uid = getuid();
199*598139dcSAndroid Build Coastguard Worker   pmsg_header.pid = getpid();
200*598139dcSAndroid Build Coastguard Worker 
201*598139dcSAndroid Build Coastguard Worker   android_log_header_t header;
202*598139dcSAndroid Build Coastguard Worker   header.tid = 0;
203*598139dcSAndroid Build Coastguard Worker   header.realtime.tv_sec = ts.tv_sec;
204*598139dcSAndroid Build Coastguard Worker   header.realtime.tv_nsec = ts.tv_nsec;
205*598139dcSAndroid Build Coastguard Worker 
206*598139dcSAndroid Build Coastguard Worker   static const unsigned nr = 1;
207*598139dcSAndroid Build Coastguard Worker   static const unsigned header_length = 2;
208*598139dcSAndroid Build Coastguard Worker   struct iovec newVec[nr + header_length];
209*598139dcSAndroid Build Coastguard Worker 
210*598139dcSAndroid Build Coastguard Worker   newVec[0].iov_base = (unsigned char*)&pmsg_header;
211*598139dcSAndroid Build Coastguard Worker   newVec[0].iov_len = sizeof(pmsg_header);
212*598139dcSAndroid Build Coastguard Worker   newVec[1].iov_base = (unsigned char*)&header;
213*598139dcSAndroid Build Coastguard Worker   newVec[1].iov_len = sizeof(header);
214*598139dcSAndroid Build Coastguard Worker 
215*598139dcSAndroid Build Coastguard Worker   android_log_event_int_t buffer;
216*598139dcSAndroid Build Coastguard Worker 
217*598139dcSAndroid Build Coastguard Worker   header.id = LOG_ID_EVENTS;
218*598139dcSAndroid Build Coastguard Worker   buffer.header.tag = 0;
219*598139dcSAndroid Build Coastguard Worker   buffer.payload.type = EVENT_TYPE_INT;
220*598139dcSAndroid Build Coastguard Worker   uint32_t snapshot = 0;
221*598139dcSAndroid Build Coastguard Worker   buffer.payload.data = snapshot;
222*598139dcSAndroid Build Coastguard Worker 
223*598139dcSAndroid Build Coastguard Worker   newVec[2].iov_base = &buffer;
224*598139dcSAndroid Build Coastguard Worker   newVec[2].iov_len = sizeof(buffer);
225*598139dcSAndroid Build Coastguard Worker 
226*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
227*598139dcSAndroid Build Coastguard Worker     ++snapshot;
228*598139dcSAndroid Build Coastguard Worker     buffer.payload.data = snapshot;
229*598139dcSAndroid Build Coastguard Worker     writev(pstore_fd, newVec, nr);
230*598139dcSAndroid Build Coastguard Worker   }
231*598139dcSAndroid Build Coastguard Worker   state.PauseTiming();
232*598139dcSAndroid Build Coastguard Worker   close(pstore_fd);
233*598139dcSAndroid Build Coastguard Worker }
234*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_pmsg_short);
235*598139dcSAndroid Build Coastguard Worker 
236*598139dcSAndroid Build Coastguard Worker /*
237*598139dcSAndroid Build Coastguard Worker  * Measure the time it takes to submit the android logging data to pstore
238*598139dcSAndroid Build Coastguard Worker  * best case aligned single block.
239*598139dcSAndroid Build Coastguard Worker  */
BM_pmsg_short_aligned(benchmark::State & state)240*598139dcSAndroid Build Coastguard Worker static void BM_pmsg_short_aligned(benchmark::State& state) {
241*598139dcSAndroid Build Coastguard Worker   int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
242*598139dcSAndroid Build Coastguard Worker   if (pstore_fd < 0) {
243*598139dcSAndroid Build Coastguard Worker     state.SkipWithError("/dev/pmsg0");
244*598139dcSAndroid Build Coastguard Worker     return;
245*598139dcSAndroid Build Coastguard Worker   }
246*598139dcSAndroid Build Coastguard Worker 
247*598139dcSAndroid Build Coastguard Worker   /*
248*598139dcSAndroid Build Coastguard Worker    *  struct {
249*598139dcSAndroid Build Coastguard Worker    *      // what we provide to pstore
250*598139dcSAndroid Build Coastguard Worker    *      android_pmsg_log_header_t pmsg_header;
251*598139dcSAndroid Build Coastguard Worker    *      // what we provide to socket
252*598139dcSAndroid Build Coastguard Worker    *      android_log_header_t header;
253*598139dcSAndroid Build Coastguard Worker    *      // caller provides
254*598139dcSAndroid Build Coastguard Worker    *      union {
255*598139dcSAndroid Build Coastguard Worker    *          struct {
256*598139dcSAndroid Build Coastguard Worker    *              char     prio;
257*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
258*598139dcSAndroid Build Coastguard Worker    *          } string;
259*598139dcSAndroid Build Coastguard Worker    *          struct {
260*598139dcSAndroid Build Coastguard Worker    *              uint32_t tag
261*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
262*598139dcSAndroid Build Coastguard Worker    *          } binary;
263*598139dcSAndroid Build Coastguard Worker    *      };
264*598139dcSAndroid Build Coastguard Worker    *  };
265*598139dcSAndroid Build Coastguard Worker    */
266*598139dcSAndroid Build Coastguard Worker 
267*598139dcSAndroid Build Coastguard Worker   struct timespec ts;
268*598139dcSAndroid Build Coastguard Worker   clock_gettime(CLOCK_REALTIME, &ts);
269*598139dcSAndroid Build Coastguard Worker 
270*598139dcSAndroid Build Coastguard Worker   struct packet {
271*598139dcSAndroid Build Coastguard Worker     android_pmsg_log_header_t pmsg_header;
272*598139dcSAndroid Build Coastguard Worker     android_log_header_t header;
273*598139dcSAndroid Build Coastguard Worker     android_log_event_int_t payload;
274*598139dcSAndroid Build Coastguard Worker   };
275*598139dcSAndroid Build Coastguard Worker   alignas(8) char buf[sizeof(struct packet) + 8] = {};
276*598139dcSAndroid Build Coastguard Worker   struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
277*598139dcSAndroid Build Coastguard Worker   if (((uintptr_t)&buffer->pmsg_header) & 7) {
278*598139dcSAndroid Build Coastguard Worker     fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
279*598139dcSAndroid Build Coastguard Worker             state.iterations());
280*598139dcSAndroid Build Coastguard Worker   }
281*598139dcSAndroid Build Coastguard Worker 
282*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.magic = LOGGER_MAGIC;
283*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.len =
284*598139dcSAndroid Build Coastguard Worker       sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
285*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.uid = getuid();
286*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.pid = getpid();
287*598139dcSAndroid Build Coastguard Worker 
288*598139dcSAndroid Build Coastguard Worker   buffer->header.tid = 0;
289*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_sec = ts.tv_sec;
290*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_nsec = ts.tv_nsec;
291*598139dcSAndroid Build Coastguard Worker 
292*598139dcSAndroid Build Coastguard Worker   buffer->header.id = LOG_ID_EVENTS;
293*598139dcSAndroid Build Coastguard Worker   buffer->payload.header.tag = 0;
294*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.type = EVENT_TYPE_INT;
295*598139dcSAndroid Build Coastguard Worker   uint32_t snapshot = 0;
296*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.data = snapshot;
297*598139dcSAndroid Build Coastguard Worker 
298*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
299*598139dcSAndroid Build Coastguard Worker     ++snapshot;
300*598139dcSAndroid Build Coastguard Worker     buffer->payload.payload.data = snapshot;
301*598139dcSAndroid Build Coastguard Worker     write(pstore_fd, &buffer->pmsg_header,
302*598139dcSAndroid Build Coastguard Worker           sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) +
303*598139dcSAndroid Build Coastguard Worker               sizeof(android_log_event_int_t));
304*598139dcSAndroid Build Coastguard Worker   }
305*598139dcSAndroid Build Coastguard Worker   state.PauseTiming();
306*598139dcSAndroid Build Coastguard Worker   close(pstore_fd);
307*598139dcSAndroid Build Coastguard Worker }
308*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_pmsg_short_aligned);
309*598139dcSAndroid Build Coastguard Worker 
310*598139dcSAndroid Build Coastguard Worker /*
311*598139dcSAndroid Build Coastguard Worker  * Measure the time it takes to submit the android logging data to pstore
312*598139dcSAndroid Build Coastguard Worker  * best case aligned single block.
313*598139dcSAndroid Build Coastguard Worker  */
BM_pmsg_short_unaligned1(benchmark::State & state)314*598139dcSAndroid Build Coastguard Worker static void BM_pmsg_short_unaligned1(benchmark::State& state) {
315*598139dcSAndroid Build Coastguard Worker   int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
316*598139dcSAndroid Build Coastguard Worker   if (pstore_fd < 0) {
317*598139dcSAndroid Build Coastguard Worker     state.SkipWithError("/dev/pmsg0");
318*598139dcSAndroid Build Coastguard Worker     return;
319*598139dcSAndroid Build Coastguard Worker   }
320*598139dcSAndroid Build Coastguard Worker 
321*598139dcSAndroid Build Coastguard Worker   /*
322*598139dcSAndroid Build Coastguard Worker    *  struct {
323*598139dcSAndroid Build Coastguard Worker    *      // what we provide to pstore
324*598139dcSAndroid Build Coastguard Worker    *      android_pmsg_log_header_t pmsg_header;
325*598139dcSAndroid Build Coastguard Worker    *      // what we provide to socket
326*598139dcSAndroid Build Coastguard Worker    *      android_log_header_t header;
327*598139dcSAndroid Build Coastguard Worker    *      // caller provides
328*598139dcSAndroid Build Coastguard Worker    *      union {
329*598139dcSAndroid Build Coastguard Worker    *          struct {
330*598139dcSAndroid Build Coastguard Worker    *              char     prio;
331*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
332*598139dcSAndroid Build Coastguard Worker    *          } string;
333*598139dcSAndroid Build Coastguard Worker    *          struct {
334*598139dcSAndroid Build Coastguard Worker    *              uint32_t tag
335*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
336*598139dcSAndroid Build Coastguard Worker    *          } binary;
337*598139dcSAndroid Build Coastguard Worker    *      };
338*598139dcSAndroid Build Coastguard Worker    *  };
339*598139dcSAndroid Build Coastguard Worker    */
340*598139dcSAndroid Build Coastguard Worker 
341*598139dcSAndroid Build Coastguard Worker   struct timespec ts;
342*598139dcSAndroid Build Coastguard Worker   clock_gettime(CLOCK_REALTIME, &ts);
343*598139dcSAndroid Build Coastguard Worker 
344*598139dcSAndroid Build Coastguard Worker   struct packet {
345*598139dcSAndroid Build Coastguard Worker     android_pmsg_log_header_t pmsg_header;
346*598139dcSAndroid Build Coastguard Worker     android_log_header_t header;
347*598139dcSAndroid Build Coastguard Worker     android_log_event_int_t payload;
348*598139dcSAndroid Build Coastguard Worker   };
349*598139dcSAndroid Build Coastguard Worker   alignas(8) char buf[sizeof(struct packet) + 8] = {};
350*598139dcSAndroid Build Coastguard Worker   struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
351*598139dcSAndroid Build Coastguard Worker   if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
352*598139dcSAndroid Build Coastguard Worker     fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
353*598139dcSAndroid Build Coastguard Worker             state.iterations());
354*598139dcSAndroid Build Coastguard Worker   }
355*598139dcSAndroid Build Coastguard Worker 
356*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.magic = LOGGER_MAGIC;
357*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.len =
358*598139dcSAndroid Build Coastguard Worker       sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
359*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.uid = getuid();
360*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.pid = getpid();
361*598139dcSAndroid Build Coastguard Worker 
362*598139dcSAndroid Build Coastguard Worker   buffer->header.tid = 0;
363*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_sec = ts.tv_sec;
364*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_nsec = ts.tv_nsec;
365*598139dcSAndroid Build Coastguard Worker 
366*598139dcSAndroid Build Coastguard Worker   buffer->header.id = LOG_ID_EVENTS;
367*598139dcSAndroid Build Coastguard Worker   buffer->payload.header.tag = 0;
368*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.type = EVENT_TYPE_INT;
369*598139dcSAndroid Build Coastguard Worker   uint32_t snapshot = 0;
370*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.data = snapshot;
371*598139dcSAndroid Build Coastguard Worker 
372*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
373*598139dcSAndroid Build Coastguard Worker     ++snapshot;
374*598139dcSAndroid Build Coastguard Worker     buffer->payload.payload.data = snapshot;
375*598139dcSAndroid Build Coastguard Worker     write(pstore_fd, &buffer->pmsg_header,
376*598139dcSAndroid Build Coastguard Worker           sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) +
377*598139dcSAndroid Build Coastguard Worker               sizeof(android_log_event_int_t));
378*598139dcSAndroid Build Coastguard Worker   }
379*598139dcSAndroid Build Coastguard Worker   state.PauseTiming();
380*598139dcSAndroid Build Coastguard Worker   close(pstore_fd);
381*598139dcSAndroid Build Coastguard Worker }
382*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_pmsg_short_unaligned1);
383*598139dcSAndroid Build Coastguard Worker 
384*598139dcSAndroid Build Coastguard Worker /*
385*598139dcSAndroid Build Coastguard Worker  * Measure the time it takes to submit the android logging data to pstore
386*598139dcSAndroid Build Coastguard Worker  * best case aligned single block.
387*598139dcSAndroid Build Coastguard Worker  */
BM_pmsg_long_aligned(benchmark::State & state)388*598139dcSAndroid Build Coastguard Worker static void BM_pmsg_long_aligned(benchmark::State& state) {
389*598139dcSAndroid Build Coastguard Worker   int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
390*598139dcSAndroid Build Coastguard Worker   if (pstore_fd < 0) {
391*598139dcSAndroid Build Coastguard Worker     state.SkipWithError("/dev/pmsg0");
392*598139dcSAndroid Build Coastguard Worker     return;
393*598139dcSAndroid Build Coastguard Worker   }
394*598139dcSAndroid Build Coastguard Worker 
395*598139dcSAndroid Build Coastguard Worker   /*
396*598139dcSAndroid Build Coastguard Worker    *  struct {
397*598139dcSAndroid Build Coastguard Worker    *      // what we provide to pstore
398*598139dcSAndroid Build Coastguard Worker    *      android_pmsg_log_header_t pmsg_header;
399*598139dcSAndroid Build Coastguard Worker    *      // what we provide to socket
400*598139dcSAndroid Build Coastguard Worker    *      android_log_header_t header;
401*598139dcSAndroid Build Coastguard Worker    *      // caller provides
402*598139dcSAndroid Build Coastguard Worker    *      union {
403*598139dcSAndroid Build Coastguard Worker    *          struct {
404*598139dcSAndroid Build Coastguard Worker    *              char     prio;
405*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
406*598139dcSAndroid Build Coastguard Worker    *          } string;
407*598139dcSAndroid Build Coastguard Worker    *          struct {
408*598139dcSAndroid Build Coastguard Worker    *              uint32_t tag
409*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
410*598139dcSAndroid Build Coastguard Worker    *          } binary;
411*598139dcSAndroid Build Coastguard Worker    *      };
412*598139dcSAndroid Build Coastguard Worker    *  };
413*598139dcSAndroid Build Coastguard Worker    */
414*598139dcSAndroid Build Coastguard Worker 
415*598139dcSAndroid Build Coastguard Worker   struct timespec ts;
416*598139dcSAndroid Build Coastguard Worker   clock_gettime(CLOCK_REALTIME, &ts);
417*598139dcSAndroid Build Coastguard Worker 
418*598139dcSAndroid Build Coastguard Worker   struct packet {
419*598139dcSAndroid Build Coastguard Worker     android_pmsg_log_header_t pmsg_header;
420*598139dcSAndroid Build Coastguard Worker     android_log_header_t header;
421*598139dcSAndroid Build Coastguard Worker     android_log_event_int_t payload;
422*598139dcSAndroid Build Coastguard Worker   };
423*598139dcSAndroid Build Coastguard Worker   alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD] = {};
424*598139dcSAndroid Build Coastguard Worker   struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
425*598139dcSAndroid Build Coastguard Worker   if (((uintptr_t)&buffer->pmsg_header) & 7) {
426*598139dcSAndroid Build Coastguard Worker     fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
427*598139dcSAndroid Build Coastguard Worker             state.iterations());
428*598139dcSAndroid Build Coastguard Worker   }
429*598139dcSAndroid Build Coastguard Worker 
430*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.magic = LOGGER_MAGIC;
431*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.len =
432*598139dcSAndroid Build Coastguard Worker       sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
433*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.uid = getuid();
434*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.pid = getpid();
435*598139dcSAndroid Build Coastguard Worker 
436*598139dcSAndroid Build Coastguard Worker   buffer->header.tid = 0;
437*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_sec = ts.tv_sec;
438*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_nsec = ts.tv_nsec;
439*598139dcSAndroid Build Coastguard Worker 
440*598139dcSAndroid Build Coastguard Worker   buffer->header.id = LOG_ID_EVENTS;
441*598139dcSAndroid Build Coastguard Worker   buffer->payload.header.tag = 0;
442*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.type = EVENT_TYPE_INT;
443*598139dcSAndroid Build Coastguard Worker   uint32_t snapshot = 0;
444*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.data = snapshot;
445*598139dcSAndroid Build Coastguard Worker 
446*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
447*598139dcSAndroid Build Coastguard Worker     ++snapshot;
448*598139dcSAndroid Build Coastguard Worker     buffer->payload.payload.data = snapshot;
449*598139dcSAndroid Build Coastguard Worker     write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD);
450*598139dcSAndroid Build Coastguard Worker   }
451*598139dcSAndroid Build Coastguard Worker   state.PauseTiming();
452*598139dcSAndroid Build Coastguard Worker   close(pstore_fd);
453*598139dcSAndroid Build Coastguard Worker }
454*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_pmsg_long_aligned);
455*598139dcSAndroid Build Coastguard Worker 
456*598139dcSAndroid Build Coastguard Worker /*
457*598139dcSAndroid Build Coastguard Worker  * Measure the time it takes to submit the android logging data to pstore
458*598139dcSAndroid Build Coastguard Worker  * best case aligned single block.
459*598139dcSAndroid Build Coastguard Worker  */
BM_pmsg_long_unaligned1(benchmark::State & state)460*598139dcSAndroid Build Coastguard Worker static void BM_pmsg_long_unaligned1(benchmark::State& state) {
461*598139dcSAndroid Build Coastguard Worker   int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
462*598139dcSAndroid Build Coastguard Worker   if (pstore_fd < 0) {
463*598139dcSAndroid Build Coastguard Worker     state.SkipWithError("/dev/pmsg0");
464*598139dcSAndroid Build Coastguard Worker     return;
465*598139dcSAndroid Build Coastguard Worker   }
466*598139dcSAndroid Build Coastguard Worker 
467*598139dcSAndroid Build Coastguard Worker   /*
468*598139dcSAndroid Build Coastguard Worker    *  struct {
469*598139dcSAndroid Build Coastguard Worker    *      // what we provide to pstore
470*598139dcSAndroid Build Coastguard Worker    *      android_pmsg_log_header_t pmsg_header;
471*598139dcSAndroid Build Coastguard Worker    *      // what we provide to socket
472*598139dcSAndroid Build Coastguard Worker    *      android_log_header_t header;
473*598139dcSAndroid Build Coastguard Worker    *      // caller provides
474*598139dcSAndroid Build Coastguard Worker    *      union {
475*598139dcSAndroid Build Coastguard Worker    *          struct {
476*598139dcSAndroid Build Coastguard Worker    *              char     prio;
477*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
478*598139dcSAndroid Build Coastguard Worker    *          } string;
479*598139dcSAndroid Build Coastguard Worker    *          struct {
480*598139dcSAndroid Build Coastguard Worker    *              uint32_t tag
481*598139dcSAndroid Build Coastguard Worker    *              char     payload[];
482*598139dcSAndroid Build Coastguard Worker    *          } binary;
483*598139dcSAndroid Build Coastguard Worker    *      };
484*598139dcSAndroid Build Coastguard Worker    *  };
485*598139dcSAndroid Build Coastguard Worker    */
486*598139dcSAndroid Build Coastguard Worker 
487*598139dcSAndroid Build Coastguard Worker   struct timespec ts;
488*598139dcSAndroid Build Coastguard Worker   clock_gettime(CLOCK_REALTIME, &ts);
489*598139dcSAndroid Build Coastguard Worker 
490*598139dcSAndroid Build Coastguard Worker   struct packet {
491*598139dcSAndroid Build Coastguard Worker     android_pmsg_log_header_t pmsg_header;
492*598139dcSAndroid Build Coastguard Worker     android_log_header_t header;
493*598139dcSAndroid Build Coastguard Worker     android_log_event_int_t payload;
494*598139dcSAndroid Build Coastguard Worker   };
495*598139dcSAndroid Build Coastguard Worker   alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD] = {};
496*598139dcSAndroid Build Coastguard Worker   struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
497*598139dcSAndroid Build Coastguard Worker   if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
498*598139dcSAndroid Build Coastguard Worker     fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header,
499*598139dcSAndroid Build Coastguard Worker             state.iterations());
500*598139dcSAndroid Build Coastguard Worker   }
501*598139dcSAndroid Build Coastguard Worker 
502*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.magic = LOGGER_MAGIC;
503*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.len =
504*598139dcSAndroid Build Coastguard Worker       sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t);
505*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.uid = getuid();
506*598139dcSAndroid Build Coastguard Worker   buffer->pmsg_header.pid = getpid();
507*598139dcSAndroid Build Coastguard Worker 
508*598139dcSAndroid Build Coastguard Worker   buffer->header.tid = 0;
509*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_sec = ts.tv_sec;
510*598139dcSAndroid Build Coastguard Worker   buffer->header.realtime.tv_nsec = ts.tv_nsec;
511*598139dcSAndroid Build Coastguard Worker 
512*598139dcSAndroid Build Coastguard Worker   buffer->header.id = LOG_ID_EVENTS;
513*598139dcSAndroid Build Coastguard Worker   buffer->payload.header.tag = 0;
514*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.type = EVENT_TYPE_INT;
515*598139dcSAndroid Build Coastguard Worker   uint32_t snapshot = 0;
516*598139dcSAndroid Build Coastguard Worker   buffer->payload.payload.data = snapshot;
517*598139dcSAndroid Build Coastguard Worker 
518*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
519*598139dcSAndroid Build Coastguard Worker     ++snapshot;
520*598139dcSAndroid Build Coastguard Worker     buffer->payload.payload.data = snapshot;
521*598139dcSAndroid Build Coastguard Worker     write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD);
522*598139dcSAndroid Build Coastguard Worker   }
523*598139dcSAndroid Build Coastguard Worker   state.PauseTiming();
524*598139dcSAndroid Build Coastguard Worker   close(pstore_fd);
525*598139dcSAndroid Build Coastguard Worker }
526*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_pmsg_long_unaligned1);
527*598139dcSAndroid Build Coastguard Worker 
528*598139dcSAndroid Build Coastguard Worker /*
529*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes to form sprintf plus time using
530*598139dcSAndroid Build Coastguard Worker  * discrete acquisition under light load. Expect this to be a syscall period
531*598139dcSAndroid Build Coastguard Worker  * (2us) or sprintf time if zero-syscall time.
532*598139dcSAndroid Build Coastguard Worker  */
533*598139dcSAndroid Build Coastguard Worker /* helper function */
test_print(const char * fmt,...)534*598139dcSAndroid Build Coastguard Worker static void test_print(const char* fmt, ...) {
535*598139dcSAndroid Build Coastguard Worker   va_list ap;
536*598139dcSAndroid Build Coastguard Worker   char buf[1024];
537*598139dcSAndroid Build Coastguard Worker 
538*598139dcSAndroid Build Coastguard Worker   va_start(ap, fmt);
539*598139dcSAndroid Build Coastguard Worker   vsnprintf(buf, sizeof(buf), fmt, ap);
540*598139dcSAndroid Build Coastguard Worker   va_end(ap);
541*598139dcSAndroid Build Coastguard Worker }
542*598139dcSAndroid Build Coastguard Worker 
543*598139dcSAndroid Build Coastguard Worker #define logd_yield() sched_yield()  // allow logd to catch up
544*598139dcSAndroid Build Coastguard Worker #define logd_sleep() usleep(50)     // really allow logd to catch up
545*598139dcSAndroid Build Coastguard Worker 
546*598139dcSAndroid Build Coastguard Worker /* performance test */
BM_sprintf_overhead(benchmark::State & state)547*598139dcSAndroid Build Coastguard Worker static void BM_sprintf_overhead(benchmark::State& state) {
548*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
549*598139dcSAndroid Build Coastguard Worker     test_print("BM_sprintf_overhead:%" PRIu64, state.iterations());
550*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
551*598139dcSAndroid Build Coastguard Worker     logd_yield();
552*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
553*598139dcSAndroid Build Coastguard Worker   }
554*598139dcSAndroid Build Coastguard Worker }
555*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_sprintf_overhead);
556*598139dcSAndroid Build Coastguard Worker 
557*598139dcSAndroid Build Coastguard Worker /*
558*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes to submit the android printing logging call
559*598139dcSAndroid Build Coastguard Worker  * using discrete acquisition discrete acquisition under light load. Expect
560*598139dcSAndroid Build Coastguard Worker  * this to be a dozen or so syscall periods (40us) plus time to run *printf
561*598139dcSAndroid Build Coastguard Worker  */
BM_log_print_overhead(benchmark::State & state)562*598139dcSAndroid Build Coastguard Worker static void BM_log_print_overhead(benchmark::State& state) {
563*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
564*598139dcSAndroid Build Coastguard Worker     __android_log_print(ANDROID_LOG_INFO, "BM_log_overhead", "%" PRIu64, state.iterations());
565*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
566*598139dcSAndroid Build Coastguard Worker     logd_yield();
567*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
568*598139dcSAndroid Build Coastguard Worker   }
569*598139dcSAndroid Build Coastguard Worker }
570*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_print_overhead);
571*598139dcSAndroid Build Coastguard Worker 
572*598139dcSAndroid Build Coastguard Worker /*
573*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes to submit the android event logging call
574*598139dcSAndroid Build Coastguard Worker  * using discrete acquisition under light load. Expect this to be a long path
575*598139dcSAndroid Build Coastguard Worker  * to logger to convert the unknown tag (0) into a tagname (less than 200us).
576*598139dcSAndroid Build Coastguard Worker  */
BM_log_event_overhead(benchmark::State & state)577*598139dcSAndroid Build Coastguard Worker static void BM_log_event_overhead(benchmark::State& state) {
578*598139dcSAndroid Build Coastguard Worker   for (int64_t i = 0; state.KeepRunning(); ++i) {
579*598139dcSAndroid Build Coastguard Worker     // log tag number 0 is not known, nor shall it ever be known
580*598139dcSAndroid Build Coastguard Worker     __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i));
581*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
582*598139dcSAndroid Build Coastguard Worker     logd_yield();
583*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
584*598139dcSAndroid Build Coastguard Worker   }
585*598139dcSAndroid Build Coastguard Worker }
586*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_event_overhead);
587*598139dcSAndroid Build Coastguard Worker 
588*598139dcSAndroid Build Coastguard Worker /*
589*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes to submit the android event logging call
590*598139dcSAndroid Build Coastguard Worker  * using discrete acquisition under light load with a known logtag.  Expect
591*598139dcSAndroid Build Coastguard Worker  * this to be a dozen or so syscall periods (less than 40us)
592*598139dcSAndroid Build Coastguard Worker  */
BM_log_event_overhead_42(benchmark::State & state)593*598139dcSAndroid Build Coastguard Worker static void BM_log_event_overhead_42(benchmark::State& state) {
594*598139dcSAndroid Build Coastguard Worker   for (int64_t i = 0; state.KeepRunning(); ++i) {
595*598139dcSAndroid Build Coastguard Worker     // In system/core/logcat/event.logtags:
596*598139dcSAndroid Build Coastguard Worker     // # These are used for testing, do not modify without updating
597*598139dcSAndroid Build Coastguard Worker     // # tests/framework-tests/src/android/util/EventLogFunctionalTest.java.
598*598139dcSAndroid Build Coastguard Worker     // # system/logging/liblog/tests/liblog_benchmark.cpp
599*598139dcSAndroid Build Coastguard Worker     // # system/logging/liblog/tests/liblog_test.cpp
600*598139dcSAndroid Build Coastguard Worker     // 42    answer (to life the universe etc|3)
601*598139dcSAndroid Build Coastguard Worker     __android_log_btwrite(42, EVENT_TYPE_LONG, &i, sizeof(i));
602*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
603*598139dcSAndroid Build Coastguard Worker     logd_yield();
604*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
605*598139dcSAndroid Build Coastguard Worker   }
606*598139dcSAndroid Build Coastguard Worker }
607*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_event_overhead_42);
608*598139dcSAndroid Build Coastguard Worker 
609*598139dcSAndroid Build Coastguard Worker /*
610*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes to submit the android event logging call
611*598139dcSAndroid Build Coastguard Worker  * using discrete acquisition under very-light load (<1% CPU utilization).
612*598139dcSAndroid Build Coastguard Worker  */
BM_log_light_overhead(benchmark::State & state)613*598139dcSAndroid Build Coastguard Worker static void BM_log_light_overhead(benchmark::State& state) {
614*598139dcSAndroid Build Coastguard Worker   for (int64_t i = 0; state.KeepRunning(); ++i) {
615*598139dcSAndroid Build Coastguard Worker     __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i));
616*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
617*598139dcSAndroid Build Coastguard Worker     usleep(10000);
618*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
619*598139dcSAndroid Build Coastguard Worker   }
620*598139dcSAndroid Build Coastguard Worker }
621*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_light_overhead);
622*598139dcSAndroid Build Coastguard Worker 
caught_latency(int)623*598139dcSAndroid Build Coastguard Worker static void caught_latency(int /*signum*/) {
624*598139dcSAndroid Build Coastguard Worker   unsigned long long v = 0xDEADBEEFA55A5AA5ULL;
625*598139dcSAndroid Build Coastguard Worker 
626*598139dcSAndroid Build Coastguard Worker   LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
627*598139dcSAndroid Build Coastguard Worker }
628*598139dcSAndroid Build Coastguard Worker 
caught_convert(char * cp)629*598139dcSAndroid Build Coastguard Worker static unsigned long long caught_convert(char* cp) {
630*598139dcSAndroid Build Coastguard Worker   unsigned long long l = cp[0] & 0xFF;
631*598139dcSAndroid Build Coastguard Worker   l |= (unsigned long long)(cp[1] & 0xFF) << 8;
632*598139dcSAndroid Build Coastguard Worker   l |= (unsigned long long)(cp[2] & 0xFF) << 16;
633*598139dcSAndroid Build Coastguard Worker   l |= (unsigned long long)(cp[3] & 0xFF) << 24;
634*598139dcSAndroid Build Coastguard Worker   l |= (unsigned long long)(cp[4] & 0xFF) << 32;
635*598139dcSAndroid Build Coastguard Worker   l |= (unsigned long long)(cp[5] & 0xFF) << 40;
636*598139dcSAndroid Build Coastguard Worker   l |= (unsigned long long)(cp[6] & 0xFF) << 48;
637*598139dcSAndroid Build Coastguard Worker   l |= (unsigned long long)(cp[7] & 0xFF) << 56;
638*598139dcSAndroid Build Coastguard Worker   return l;
639*598139dcSAndroid Build Coastguard Worker }
640*598139dcSAndroid Build Coastguard Worker 
641*598139dcSAndroid Build Coastguard Worker static const int alarm_time = getAlarmSeconds(3);
642*598139dcSAndroid Build Coastguard Worker 
643*598139dcSAndroid Build Coastguard Worker /*
644*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes for the logd posting call to acquire the
645*598139dcSAndroid Build Coastguard Worker  * timestamp to place into the internal record.  Expect this to be less than
646*598139dcSAndroid Build Coastguard Worker  * 4 syscalls (3us).  This test uses manual injection of timing because it is
647*598139dcSAndroid Build Coastguard Worker  * comparing the timestamp at send, and then picking up the corresponding log
648*598139dcSAndroid Build Coastguard Worker  * end-to-end long path from logd to see what actual timestamp was submitted.
649*598139dcSAndroid Build Coastguard Worker  */
BM_log_latency(benchmark::State & state)650*598139dcSAndroid Build Coastguard Worker static void BM_log_latency(benchmark::State& state) {
651*598139dcSAndroid Build Coastguard Worker   pid_t pid = getpid();
652*598139dcSAndroid Build Coastguard Worker 
653*598139dcSAndroid Build Coastguard Worker   struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid);
654*598139dcSAndroid Build Coastguard Worker 
655*598139dcSAndroid Build Coastguard Worker   if (!logger_list) {
656*598139dcSAndroid Build Coastguard Worker     fprintf(stderr, "Unable to open events log: %s\n", strerror(errno));
657*598139dcSAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
658*598139dcSAndroid Build Coastguard Worker   }
659*598139dcSAndroid Build Coastguard Worker 
660*598139dcSAndroid Build Coastguard Worker   signal(SIGALRM, caught_latency);
661*598139dcSAndroid Build Coastguard Worker   alarm(alarm_time);
662*598139dcSAndroid Build Coastguard Worker 
663*598139dcSAndroid Build Coastguard Worker   for (int64_t j = 0; state.KeepRunning() && j < 10 * state.iterations(); ++j) {
664*598139dcSAndroid Build Coastguard Worker   retry:  // We allow transitory errors (logd overloaded) to be retried.
665*598139dcSAndroid Build Coastguard Worker     log_time ts;
666*598139dcSAndroid Build Coastguard Worker     LOG_FAILURE_RETRY((ts = log_time(CLOCK_REALTIME),
667*598139dcSAndroid Build Coastguard Worker                        android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts))));
668*598139dcSAndroid Build Coastguard Worker 
669*598139dcSAndroid Build Coastguard Worker     for (;;) {
670*598139dcSAndroid Build Coastguard Worker       log_msg log_msg;
671*598139dcSAndroid Build Coastguard Worker       int ret = android_logger_list_read(logger_list, &log_msg);
672*598139dcSAndroid Build Coastguard Worker       alarm(alarm_time);
673*598139dcSAndroid Build Coastguard Worker 
674*598139dcSAndroid Build Coastguard Worker       if (ret <= 0) {
675*598139dcSAndroid Build Coastguard Worker         state.SkipWithError("android_logger_list_read");
676*598139dcSAndroid Build Coastguard Worker         break;
677*598139dcSAndroid Build Coastguard Worker       }
678*598139dcSAndroid Build Coastguard Worker       if ((log_msg.entry.len != (4 + 1 + 8)) ||
679*598139dcSAndroid Build Coastguard Worker           (log_msg.id() != LOG_ID_EVENTS)) {
680*598139dcSAndroid Build Coastguard Worker         continue;
681*598139dcSAndroid Build Coastguard Worker       }
682*598139dcSAndroid Build Coastguard Worker 
683*598139dcSAndroid Build Coastguard Worker       char* eventData = log_msg.msg();
684*598139dcSAndroid Build Coastguard Worker 
685*598139dcSAndroid Build Coastguard Worker       if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
686*598139dcSAndroid Build Coastguard Worker         continue;
687*598139dcSAndroid Build Coastguard Worker       }
688*598139dcSAndroid Build Coastguard Worker       log_time* tx = reinterpret_cast<log_time*>(eventData + 4 + 1);
689*598139dcSAndroid Build Coastguard Worker       if (ts != *tx) {
690*598139dcSAndroid Build Coastguard Worker         if (0xDEADBEEFA55A5AA5ULL == caught_convert(eventData + 4 + 1)) {
691*598139dcSAndroid Build Coastguard Worker           state.SkipWithError("signal");
692*598139dcSAndroid Build Coastguard Worker           break;
693*598139dcSAndroid Build Coastguard Worker         }
694*598139dcSAndroid Build Coastguard Worker         continue;
695*598139dcSAndroid Build Coastguard Worker       }
696*598139dcSAndroid Build Coastguard Worker 
697*598139dcSAndroid Build Coastguard Worker       uint64_t start = ts.nsec();
698*598139dcSAndroid Build Coastguard Worker       uint64_t end = log_msg.nsec();
699*598139dcSAndroid Build Coastguard Worker       if (end < start) goto retry;
700*598139dcSAndroid Build Coastguard Worker       state.SetIterationTime((end - start) / (double)NS_PER_SEC);
701*598139dcSAndroid Build Coastguard Worker       break;
702*598139dcSAndroid Build Coastguard Worker     }
703*598139dcSAndroid Build Coastguard Worker   }
704*598139dcSAndroid Build Coastguard Worker 
705*598139dcSAndroid Build Coastguard Worker   signal(SIGALRM, SIG_DFL);
706*598139dcSAndroid Build Coastguard Worker   alarm(0);
707*598139dcSAndroid Build Coastguard Worker 
708*598139dcSAndroid Build Coastguard Worker   android_logger_list_free(logger_list);
709*598139dcSAndroid Build Coastguard Worker }
710*598139dcSAndroid Build Coastguard Worker // Default gets out of hand for this test, so we set a reasonable number of
711*598139dcSAndroid Build Coastguard Worker // iterations for a timely result.
712*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_latency)->UseManualTime()->Iterations(200);
713*598139dcSAndroid Build Coastguard Worker 
caught_delay(int)714*598139dcSAndroid Build Coastguard Worker static void caught_delay(int /*signum*/) {
715*598139dcSAndroid Build Coastguard Worker   unsigned long long v = 0xDEADBEEFA55A5AA6ULL;
716*598139dcSAndroid Build Coastguard Worker 
717*598139dcSAndroid Build Coastguard Worker   LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
718*598139dcSAndroid Build Coastguard Worker }
719*598139dcSAndroid Build Coastguard Worker 
720*598139dcSAndroid Build Coastguard Worker /*
721*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes for the logd posting call to make it into
722*598139dcSAndroid Build Coastguard Worker  * the logs. Expect this to be less than double the process wakeup time (2ms).
723*598139dcSAndroid Build Coastguard Worker  */
BM_log_delay(benchmark::State & state)724*598139dcSAndroid Build Coastguard Worker static void BM_log_delay(benchmark::State& state) {
725*598139dcSAndroid Build Coastguard Worker   pid_t pid = getpid();
726*598139dcSAndroid Build Coastguard Worker 
727*598139dcSAndroid Build Coastguard Worker   struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid);
728*598139dcSAndroid Build Coastguard Worker 
729*598139dcSAndroid Build Coastguard Worker   if (!logger_list) {
730*598139dcSAndroid Build Coastguard Worker     fprintf(stderr, "Unable to open events log: %s\n", strerror(errno));
731*598139dcSAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
732*598139dcSAndroid Build Coastguard Worker   }
733*598139dcSAndroid Build Coastguard Worker 
734*598139dcSAndroid Build Coastguard Worker   signal(SIGALRM, caught_delay);
735*598139dcSAndroid Build Coastguard Worker   alarm(alarm_time);
736*598139dcSAndroid Build Coastguard Worker 
737*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
738*598139dcSAndroid Build Coastguard Worker     log_time ts(CLOCK_REALTIME);
739*598139dcSAndroid Build Coastguard Worker 
740*598139dcSAndroid Build Coastguard Worker     LOG_FAILURE_RETRY(android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
741*598139dcSAndroid Build Coastguard Worker 
742*598139dcSAndroid Build Coastguard Worker     for (;;) {
743*598139dcSAndroid Build Coastguard Worker       log_msg log_msg;
744*598139dcSAndroid Build Coastguard Worker       int ret = android_logger_list_read(logger_list, &log_msg);
745*598139dcSAndroid Build Coastguard Worker       alarm(alarm_time);
746*598139dcSAndroid Build Coastguard Worker 
747*598139dcSAndroid Build Coastguard Worker       if (ret <= 0) {
748*598139dcSAndroid Build Coastguard Worker         state.SkipWithError("android_logger_list_read");
749*598139dcSAndroid Build Coastguard Worker         break;
750*598139dcSAndroid Build Coastguard Worker       }
751*598139dcSAndroid Build Coastguard Worker       if ((log_msg.entry.len != (4 + 1 + 8)) ||
752*598139dcSAndroid Build Coastguard Worker           (log_msg.id() != LOG_ID_EVENTS)) {
753*598139dcSAndroid Build Coastguard Worker         continue;
754*598139dcSAndroid Build Coastguard Worker       }
755*598139dcSAndroid Build Coastguard Worker 
756*598139dcSAndroid Build Coastguard Worker       char* eventData = log_msg.msg();
757*598139dcSAndroid Build Coastguard Worker 
758*598139dcSAndroid Build Coastguard Worker       if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
759*598139dcSAndroid Build Coastguard Worker         continue;
760*598139dcSAndroid Build Coastguard Worker       }
761*598139dcSAndroid Build Coastguard Worker       log_time* tx = reinterpret_cast<log_time*>(eventData + 4 + 1);
762*598139dcSAndroid Build Coastguard Worker       if (ts != *tx) {
763*598139dcSAndroid Build Coastguard Worker         if (0xDEADBEEFA55A5AA6ULL == caught_convert(eventData + 4 + 1)) {
764*598139dcSAndroid Build Coastguard Worker           state.SkipWithError("signal");
765*598139dcSAndroid Build Coastguard Worker           break;
766*598139dcSAndroid Build Coastguard Worker         }
767*598139dcSAndroid Build Coastguard Worker         continue;
768*598139dcSAndroid Build Coastguard Worker       }
769*598139dcSAndroid Build Coastguard Worker 
770*598139dcSAndroid Build Coastguard Worker       break;
771*598139dcSAndroid Build Coastguard Worker     }
772*598139dcSAndroid Build Coastguard Worker   }
773*598139dcSAndroid Build Coastguard Worker   state.PauseTiming();
774*598139dcSAndroid Build Coastguard Worker 
775*598139dcSAndroid Build Coastguard Worker   signal(SIGALRM, SIG_DFL);
776*598139dcSAndroid Build Coastguard Worker   alarm(0);
777*598139dcSAndroid Build Coastguard Worker 
778*598139dcSAndroid Build Coastguard Worker   android_logger_list_free(logger_list);
779*598139dcSAndroid Build Coastguard Worker }
780*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_delay);
781*598139dcSAndroid Build Coastguard Worker 
782*598139dcSAndroid Build Coastguard Worker /*
783*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes for __android_log_is_loggable.
784*598139dcSAndroid Build Coastguard Worker  */
BM_is_loggable(benchmark::State & state)785*598139dcSAndroid Build Coastguard Worker static void BM_is_loggable(benchmark::State& state) {
786*598139dcSAndroid Build Coastguard Worker   static const char logd[] = "logd";
787*598139dcSAndroid Build Coastguard Worker 
788*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
789*598139dcSAndroid Build Coastguard Worker     __android_log_is_loggable_len(ANDROID_LOG_WARN, logd, strlen(logd),
790*598139dcSAndroid Build Coastguard Worker                                   ANDROID_LOG_VERBOSE);
791*598139dcSAndroid Build Coastguard Worker   }
792*598139dcSAndroid Build Coastguard Worker }
793*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_is_loggable);
794*598139dcSAndroid Build Coastguard Worker 
BM_security(benchmark::State & state)795*598139dcSAndroid Build Coastguard Worker static void BM_security(benchmark::State& state) {
796*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
797*598139dcSAndroid Build Coastguard Worker     __android_log_security();
798*598139dcSAndroid Build Coastguard Worker   }
799*598139dcSAndroid Build Coastguard Worker }
800*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_security);
801*598139dcSAndroid Build Coastguard Worker 
802*598139dcSAndroid Build Coastguard Worker // Keep maps around for multiple iterations
803*598139dcSAndroid Build Coastguard Worker static std::unordered_set<uint32_t> set;
804*598139dcSAndroid Build Coastguard Worker static EventTagMap* map;
805*598139dcSAndroid Build Coastguard Worker 
prechargeEventMap()806*598139dcSAndroid Build Coastguard Worker static bool prechargeEventMap() {
807*598139dcSAndroid Build Coastguard Worker   if (map) return true;
808*598139dcSAndroid Build Coastguard Worker 
809*598139dcSAndroid Build Coastguard Worker   fprintf(stderr, "Precharge: start\n");
810*598139dcSAndroid Build Coastguard Worker 
811*598139dcSAndroid Build Coastguard Worker   map = android_openEventTagMap(NULL);
812*598139dcSAndroid Build Coastguard Worker   for (uint32_t tag = 1; tag < USHRT_MAX; ++tag) {
813*598139dcSAndroid Build Coastguard Worker     size_t len;
814*598139dcSAndroid Build Coastguard Worker     if (android_lookupEventTag_len(map, &len, tag) == NULL) continue;
815*598139dcSAndroid Build Coastguard Worker     set.insert(tag);
816*598139dcSAndroid Build Coastguard Worker   }
817*598139dcSAndroid Build Coastguard Worker 
818*598139dcSAndroid Build Coastguard Worker   fprintf(stderr, "Precharge: stop %zu\n", set.size());
819*598139dcSAndroid Build Coastguard Worker 
820*598139dcSAndroid Build Coastguard Worker   return true;
821*598139dcSAndroid Build Coastguard Worker }
822*598139dcSAndroid Build Coastguard Worker 
823*598139dcSAndroid Build Coastguard Worker /*
824*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes for android_lookupEventTag_len
825*598139dcSAndroid Build Coastguard Worker  */
BM_lookupEventTag(benchmark::State & state)826*598139dcSAndroid Build Coastguard Worker static void BM_lookupEventTag(benchmark::State& state) {
827*598139dcSAndroid Build Coastguard Worker   prechargeEventMap();
828*598139dcSAndroid Build Coastguard Worker 
829*598139dcSAndroid Build Coastguard Worker   std::unordered_set<uint32_t>::const_iterator it = set.begin();
830*598139dcSAndroid Build Coastguard Worker 
831*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
832*598139dcSAndroid Build Coastguard Worker     size_t len;
833*598139dcSAndroid Build Coastguard Worker     android_lookupEventTag_len(map, &len, (*it));
834*598139dcSAndroid Build Coastguard Worker     ++it;
835*598139dcSAndroid Build Coastguard Worker     if (it == set.end()) it = set.begin();
836*598139dcSAndroid Build Coastguard Worker   }
837*598139dcSAndroid Build Coastguard Worker }
838*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_lookupEventTag);
839*598139dcSAndroid Build Coastguard Worker 
840*598139dcSAndroid Build Coastguard Worker /*
841*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes for android_lookupEventTag_len
842*598139dcSAndroid Build Coastguard Worker  */
843*598139dcSAndroid Build Coastguard Worker static uint32_t notTag = 1;
844*598139dcSAndroid Build Coastguard Worker 
BM_lookupEventTag_NOT(benchmark::State & state)845*598139dcSAndroid Build Coastguard Worker static void BM_lookupEventTag_NOT(benchmark::State& state) {
846*598139dcSAndroid Build Coastguard Worker   prechargeEventMap();
847*598139dcSAndroid Build Coastguard Worker 
848*598139dcSAndroid Build Coastguard Worker   while (set.contains(notTag)) {
849*598139dcSAndroid Build Coastguard Worker     ++notTag;
850*598139dcSAndroid Build Coastguard Worker     if (notTag >= USHRT_MAX) notTag = 1;
851*598139dcSAndroid Build Coastguard Worker   }
852*598139dcSAndroid Build Coastguard Worker 
853*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
854*598139dcSAndroid Build Coastguard Worker     size_t len;
855*598139dcSAndroid Build Coastguard Worker     android_lookupEventTag_len(map, &len, notTag);
856*598139dcSAndroid Build Coastguard Worker   }
857*598139dcSAndroid Build Coastguard Worker 
858*598139dcSAndroid Build Coastguard Worker   ++notTag;
859*598139dcSAndroid Build Coastguard Worker   if (notTag >= USHRT_MAX) notTag = 1;
860*598139dcSAndroid Build Coastguard Worker }
861*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_lookupEventTag_NOT);
862*598139dcSAndroid Build Coastguard Worker 
863*598139dcSAndroid Build Coastguard Worker /*
864*598139dcSAndroid Build Coastguard Worker  *	Measure the time it takes for android_lookupEventFormat_len
865*598139dcSAndroid Build Coastguard Worker  */
BM_lookupEventFormat(benchmark::State & state)866*598139dcSAndroid Build Coastguard Worker static void BM_lookupEventFormat(benchmark::State& state) {
867*598139dcSAndroid Build Coastguard Worker   prechargeEventMap();
868*598139dcSAndroid Build Coastguard Worker 
869*598139dcSAndroid Build Coastguard Worker   std::unordered_set<uint32_t>::const_iterator it = set.begin();
870*598139dcSAndroid Build Coastguard Worker 
871*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
872*598139dcSAndroid Build Coastguard Worker     size_t len;
873*598139dcSAndroid Build Coastguard Worker     android_lookupEventFormat_len(map, &len, (*it));
874*598139dcSAndroid Build Coastguard Worker     ++it;
875*598139dcSAndroid Build Coastguard Worker     if (it == set.end()) it = set.begin();
876*598139dcSAndroid Build Coastguard Worker   }
877*598139dcSAndroid Build Coastguard Worker }
878*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_lookupEventFormat);
879*598139dcSAndroid Build Coastguard Worker 
880*598139dcSAndroid Build Coastguard Worker // Must be functionally identical to liblog internal SendLogdControlMessage()
send_to_control(char * buf,size_t len)881*598139dcSAndroid Build Coastguard Worker static void send_to_control(char* buf, size_t len) {
882*598139dcSAndroid Build Coastguard Worker   int sock =
883*598139dcSAndroid Build Coastguard Worker       socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM | SOCK_CLOEXEC);
884*598139dcSAndroid Build Coastguard Worker   if (sock < 0) return;
885*598139dcSAndroid Build Coastguard Worker   size_t writeLen = strlen(buf) + 1;
886*598139dcSAndroid Build Coastguard Worker 
887*598139dcSAndroid Build Coastguard Worker   ssize_t ret = TEMP_FAILURE_RETRY(write(sock, buf, writeLen));
888*598139dcSAndroid Build Coastguard Worker   if (ret <= 0) {
889*598139dcSAndroid Build Coastguard Worker     close(sock);
890*598139dcSAndroid Build Coastguard Worker     return;
891*598139dcSAndroid Build Coastguard Worker   }
892*598139dcSAndroid Build Coastguard Worker   while ((ret = read(sock, buf, len)) > 0) {
893*598139dcSAndroid Build Coastguard Worker     if ((size_t)ret == len) {
894*598139dcSAndroid Build Coastguard Worker       break;
895*598139dcSAndroid Build Coastguard Worker     }
896*598139dcSAndroid Build Coastguard Worker     len -= ret;
897*598139dcSAndroid Build Coastguard Worker     buf += ret;
898*598139dcSAndroid Build Coastguard Worker 
899*598139dcSAndroid Build Coastguard Worker     struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 };
900*598139dcSAndroid Build Coastguard Worker 
901*598139dcSAndroid Build Coastguard Worker     ret = poll(&p, 1, 20);
902*598139dcSAndroid Build Coastguard Worker     if ((ret <= 0) || !(p.revents & POLLIN)) {
903*598139dcSAndroid Build Coastguard Worker       break;
904*598139dcSAndroid Build Coastguard Worker     }
905*598139dcSAndroid Build Coastguard Worker   }
906*598139dcSAndroid Build Coastguard Worker   close(sock);
907*598139dcSAndroid Build Coastguard Worker }
908*598139dcSAndroid Build Coastguard Worker 
BM_lookupEventTagNum_logd_new(benchmark::State & state)909*598139dcSAndroid Build Coastguard Worker static void BM_lookupEventTagNum_logd_new(benchmark::State& state) {
910*598139dcSAndroid Build Coastguard Worker   fprintf(stderr,
911*598139dcSAndroid Build Coastguard Worker           "WARNING: "
912*598139dcSAndroid Build Coastguard Worker           "This test can cause logd to grow in size and hit DOS limiter\n");
913*598139dcSAndroid Build Coastguard Worker   // Make copies
914*598139dcSAndroid Build Coastguard Worker   static const char empty_event_log_tags[] = "# content owned by logd\n";
915*598139dcSAndroid Build Coastguard Worker   static const char dev_event_log_tags_path[] = "/dev/event-log-tags";
916*598139dcSAndroid Build Coastguard Worker   std::string dev_event_log_tags;
917*598139dcSAndroid Build Coastguard Worker   if (android::base::ReadFileToString(dev_event_log_tags_path,
918*598139dcSAndroid Build Coastguard Worker                                       &dev_event_log_tags) &&
919*598139dcSAndroid Build Coastguard Worker       (dev_event_log_tags.length() == 0)) {
920*598139dcSAndroid Build Coastguard Worker     dev_event_log_tags = empty_event_log_tags;
921*598139dcSAndroid Build Coastguard Worker   }
922*598139dcSAndroid Build Coastguard Worker   static const char data_event_log_tags_path[] =
923*598139dcSAndroid Build Coastguard Worker       "/data/misc/logd/event-log-tags";
924*598139dcSAndroid Build Coastguard Worker   std::string data_event_log_tags;
925*598139dcSAndroid Build Coastguard Worker   if (android::base::ReadFileToString(data_event_log_tags_path,
926*598139dcSAndroid Build Coastguard Worker                                       &data_event_log_tags) &&
927*598139dcSAndroid Build Coastguard Worker       (data_event_log_tags.length() == 0)) {
928*598139dcSAndroid Build Coastguard Worker     data_event_log_tags = empty_event_log_tags;
929*598139dcSAndroid Build Coastguard Worker   }
930*598139dcSAndroid Build Coastguard Worker 
931*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
932*598139dcSAndroid Build Coastguard Worker     char buffer[256] = {};
933*598139dcSAndroid Build Coastguard Worker     log_time now(CLOCK_MONOTONIC);
934*598139dcSAndroid Build Coastguard Worker     char name[64];
935*598139dcSAndroid Build Coastguard Worker     snprintf(name, sizeof(name), "a%" PRIu64, now.nsec());
936*598139dcSAndroid Build Coastguard Worker     snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"",
937*598139dcSAndroid Build Coastguard Worker              name);
938*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
939*598139dcSAndroid Build Coastguard Worker     send_to_control(buffer, sizeof(buffer));
940*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
941*598139dcSAndroid Build Coastguard Worker   }
942*598139dcSAndroid Build Coastguard Worker 
943*598139dcSAndroid Build Coastguard Worker   // Restore copies (logd still know about them, until crash or reboot)
944*598139dcSAndroid Build Coastguard Worker   if (dev_event_log_tags.length() &&
945*598139dcSAndroid Build Coastguard Worker       !android::base::WriteStringToFile(dev_event_log_tags,
946*598139dcSAndroid Build Coastguard Worker                                         dev_event_log_tags_path)) {
947*598139dcSAndroid Build Coastguard Worker     fprintf(stderr,
948*598139dcSAndroid Build Coastguard Worker             "WARNING: "
949*598139dcSAndroid Build Coastguard Worker             "failed to restore %s\n",
950*598139dcSAndroid Build Coastguard Worker             dev_event_log_tags_path);
951*598139dcSAndroid Build Coastguard Worker   }
952*598139dcSAndroid Build Coastguard Worker   if (data_event_log_tags.length() &&
953*598139dcSAndroid Build Coastguard Worker       !android::base::WriteStringToFile(data_event_log_tags,
954*598139dcSAndroid Build Coastguard Worker                                         data_event_log_tags_path)) {
955*598139dcSAndroid Build Coastguard Worker     fprintf(stderr,
956*598139dcSAndroid Build Coastguard Worker             "WARNING: "
957*598139dcSAndroid Build Coastguard Worker             "failed to restore %s\n",
958*598139dcSAndroid Build Coastguard Worker             data_event_log_tags_path);
959*598139dcSAndroid Build Coastguard Worker   }
960*598139dcSAndroid Build Coastguard Worker   fprintf(stderr,
961*598139dcSAndroid Build Coastguard Worker           "WARNING: "
962*598139dcSAndroid Build Coastguard Worker           "Restarting logd to make it forget what we just did\n");
963*598139dcSAndroid Build Coastguard Worker   system("stop logd ; start logd");
964*598139dcSAndroid Build Coastguard Worker }
965*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_lookupEventTagNum_logd_new);
966*598139dcSAndroid Build Coastguard Worker 
BM_lookupEventTagNum_logd_existing(benchmark::State & state)967*598139dcSAndroid Build Coastguard Worker static void BM_lookupEventTagNum_logd_existing(benchmark::State& state) {
968*598139dcSAndroid Build Coastguard Worker   prechargeEventMap();
969*598139dcSAndroid Build Coastguard Worker 
970*598139dcSAndroid Build Coastguard Worker   std::unordered_set<uint32_t>::const_iterator it = set.begin();
971*598139dcSAndroid Build Coastguard Worker 
972*598139dcSAndroid Build Coastguard Worker   while (state.KeepRunning()) {
973*598139dcSAndroid Build Coastguard Worker     size_t len;
974*598139dcSAndroid Build Coastguard Worker     const char* name = android_lookupEventTag_len(map, &len, (*it));
975*598139dcSAndroid Build Coastguard Worker     std::string Name(name, len);
976*598139dcSAndroid Build Coastguard Worker     const char* format = android_lookupEventFormat_len(map, &len, (*it));
977*598139dcSAndroid Build Coastguard Worker     std::string Format(format, len);
978*598139dcSAndroid Build Coastguard Worker 
979*598139dcSAndroid Build Coastguard Worker     char buffer[256];
980*598139dcSAndroid Build Coastguard Worker     snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"%s\"",
981*598139dcSAndroid Build Coastguard Worker              Name.c_str(), Format.c_str());
982*598139dcSAndroid Build Coastguard Worker 
983*598139dcSAndroid Build Coastguard Worker     state.ResumeTiming();
984*598139dcSAndroid Build Coastguard Worker     send_to_control(buffer, sizeof(buffer));
985*598139dcSAndroid Build Coastguard Worker     state.PauseTiming();
986*598139dcSAndroid Build Coastguard Worker     ++it;
987*598139dcSAndroid Build Coastguard Worker     if (it == set.end()) it = set.begin();
988*598139dcSAndroid Build Coastguard Worker   }
989*598139dcSAndroid Build Coastguard Worker }
990*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_lookupEventTagNum_logd_existing);
991*598139dcSAndroid Build Coastguard Worker 
BM_log_verbose_overhead(benchmark::State & state)992*598139dcSAndroid Build Coastguard Worker static void BM_log_verbose_overhead(benchmark::State& state) {
993*598139dcSAndroid Build Coastguard Worker   std::string test_log_tag = "liblog_verbose_tag";
994*598139dcSAndroid Build Coastguard Worker   android::base::SetProperty("log.tag." + test_log_tag, "I");
995*598139dcSAndroid Build Coastguard Worker   for (auto _ : state) {
996*598139dcSAndroid Build Coastguard Worker     __android_log_print(ANDROID_LOG_VERBOSE, test_log_tag.c_str(), "%s test log message %d %d",
997*598139dcSAndroid Build Coastguard Worker                         "test test", 123, 456);
998*598139dcSAndroid Build Coastguard Worker   }
999*598139dcSAndroid Build Coastguard Worker   android::base::SetProperty("log.tag." + test_log_tag, "");
1000*598139dcSAndroid Build Coastguard Worker }
1001*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_verbose_overhead);
1002*598139dcSAndroid Build Coastguard Worker 
BM_log_convertPrintable_ascii(benchmark::State & state)1003*598139dcSAndroid Build Coastguard Worker static void BM_log_convertPrintable_ascii(benchmark::State& state) {
1004*598139dcSAndroid Build Coastguard Worker   char buf[BUFSIZ];
1005*598139dcSAndroid Build Coastguard Worker   const char* s = "hello, world! this is a plain ASCII string 1234.";
1006*598139dcSAndroid Build Coastguard Worker   size_t n = strlen(s);
1007*598139dcSAndroid Build Coastguard Worker   for (auto _ : state) {
1008*598139dcSAndroid Build Coastguard Worker     convertPrintable(buf, s, n);
1009*598139dcSAndroid Build Coastguard Worker   }
1010*598139dcSAndroid Build Coastguard Worker }
1011*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_convertPrintable_ascii);
1012*598139dcSAndroid Build Coastguard Worker 
BM_log_convertPrintable_non_printable(benchmark::State & state)1013*598139dcSAndroid Build Coastguard Worker static void BM_log_convertPrintable_non_printable(benchmark::State& state) {
1014*598139dcSAndroid Build Coastguard Worker   char buf[BUFSIZ];
1015*598139dcSAndroid Build Coastguard Worker   const char* s = "hello,\x01world!\x02this is a plain ASCII string 1234\x7f";
1016*598139dcSAndroid Build Coastguard Worker   size_t n = strlen(s);
1017*598139dcSAndroid Build Coastguard Worker   for (auto _ : state) {
1018*598139dcSAndroid Build Coastguard Worker     convertPrintable(buf, s, n);
1019*598139dcSAndroid Build Coastguard Worker   }
1020*598139dcSAndroid Build Coastguard Worker }
1021*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_convertPrintable_non_printable);
1022*598139dcSAndroid Build Coastguard Worker 
BM_log_convertPrintable_non_ascii(benchmark::State & state)1023*598139dcSAndroid Build Coastguard Worker static void BM_log_convertPrintable_non_ascii(benchmark::State& state) {
1024*598139dcSAndroid Build Coastguard Worker   char buf[BUFSIZ];
1025*598139dcSAndroid Build Coastguard Worker   const char* s = "동해 물과 백두산이 마르고 닳도록, 하느님이 보우하사 우리나라 만세.";
1026*598139dcSAndroid Build Coastguard Worker   size_t n = strlen(s);
1027*598139dcSAndroid Build Coastguard Worker   for (auto _ : state) {
1028*598139dcSAndroid Build Coastguard Worker     convertPrintable(buf, s, n);
1029*598139dcSAndroid Build Coastguard Worker   }
1030*598139dcSAndroid Build Coastguard Worker }
1031*598139dcSAndroid Build Coastguard Worker BENCHMARK(BM_log_convertPrintable_non_ascii);
1032