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