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