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