// This function is deprecated and replaced with android_lookupEventTag_len // since it will cause the map to change from Shared and backed by a file, // to Private Dirty and backed up by swap, albeit highly compressible. By // deprecating this function everywhere, we save 100s of MB of memory space. LIBLOG_ABI_PUBLIC const char* android_lookupEventTag(const EventTagMap* map, unsigned int tag) { size_t len; const char* tagStr = android_lookupEventTag_len(map, &len, tag); if (!tagStr) return tagStr; char* cp = const_cast<char*>(tagStr); cp += len; if (*cp) *cp = '\0'; // Trigger copy on write :-( and why deprecated. return tagStr; }
/* * Measure the time it takes for android_lookupEventTag_len */ static void BM_lookupEventTag(benchmark::State& state) { prechargeEventMap(); std::unordered_set<uint32_t>::const_iterator it = set.begin(); while (state.KeepRunning()) { size_t len; android_lookupEventTag_len(map, &len, (*it)); ++it; if (it == set.end()) it = set.begin(); } }
static void BM_lookupEventTag_NOT(benchmark::State& state) { prechargeEventMap(); while (set.find(notTag) != set.end()) { ++notTag; if (notTag >= USHRT_MAX) notTag = 1; } while (state.KeepRunning()) { size_t len; android_lookupEventTag_len(map, &len, notTag); } ++notTag; if (notTag >= USHRT_MAX) notTag = 1; }
static bool prechargeEventMap() { if (map) return true; fprintf(stderr, "Precharge: start\n"); map = android_openEventTagMap(NULL); for (uint32_t tag = 1; tag < USHRT_MAX; ++tag) { size_t len; if (android_lookupEventTag_len(map, &len, tag) == NULL) continue; set.insert(tag); } fprintf(stderr, "Precharge: stop %zu\n", set.size()); return true; }
/* * Measure the time it takes for android_lookupEventTagNum plus above */ static void BM_lookupEventTagNum(benchmark::State& state) { prechargeEventMap(); std::unordered_set<uint32_t>::const_iterator it = set.begin(); while (state.KeepRunning()) { size_t len; const char* name = android_lookupEventTag_len(map, &len, (*it)); std::string Name(name, len); const char* format = android_lookupEventFormat_len(map, &len, (*it)); std::string Format(format, len); state.ResumeTiming(); android_lookupEventTagNum(map, Name.c_str(), Format.c_str(), ANDROID_LOG_UNKNOWN); state.PauseTiming(); ++it; if (it == set.end()) it = set.begin(); } }
static void BM_lookupEventTagNum_logd_existing(benchmark::State& state) { prechargeEventMap(); std::unordered_set<uint32_t>::const_iterator it = set.begin(); while (state.KeepRunning()) { size_t len; const char* name = android_lookupEventTag_len(map, &len, (*it)); std::string Name(name, len); const char* format = android_lookupEventFormat_len(map, &len, (*it)); std::string Format(format, len); char buffer[256]; snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"%s\"", Name.c_str(), Format.c_str()); state.ResumeTiming(); send_to_control(buffer, sizeof(buffer)); state.PauseTiming(); ++it; if (it == set.end()) it = set.begin(); } }
/** * Convert a binary log entry to ASCII form. * * For convenience we mimic the processLogBuffer API. There is no * pre-defined output length for the binary data, since we're free to format * it however we choose, which means we can't really use a fixed-size buffer * here. */ LIBLOG_ABI_PUBLIC int android_log_processBinaryLogBuffer( struct logger_entry *buf, AndroidLogEntry *entry, const EventTagMap *map, char *messageBuf, int messageBufLen) { size_t inCount; unsigned int tagIndex; const unsigned char* eventData; entry->tv_sec = buf->sec; entry->tv_nsec = buf->nsec; entry->priority = ANDROID_LOG_INFO; entry->uid = -1; entry->pid = buf->pid; entry->tid = buf->tid; /* * Pull the tag out, fill in some additional details based on incoming * buffer version (v3 adds lid, v4 adds uid). */ eventData = (const unsigned char*) buf->msg; struct logger_entry_v2 *buf2 = (struct logger_entry_v2 *)buf; if (buf2->hdr_size) { if ((buf2->hdr_size < sizeof(((struct log_msg *)NULL)->entry_v1)) || (buf2->hdr_size > sizeof(((struct log_msg *)NULL)->entry))) { fprintf(stderr, "+++ LOG: entry illegal hdr_size\n"); return -1; } eventData = ((unsigned char *)buf2) + buf2->hdr_size; if ((buf2->hdr_size >= sizeof(struct logger_entry_v3)) && (((struct logger_entry_v3 *)buf)->lid == LOG_ID_SECURITY)) { entry->priority = ANDROID_LOG_WARN; } if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) { entry->uid = ((struct logger_entry_v4 *)buf)->uid; } } inCount = buf->len; if (inCount < 4) return -1; tagIndex = get4LE(eventData); eventData += 4; inCount -= 4; entry->tagLen = 0; if (map != NULL) { entry->tag = android_lookupEventTag_len(map, &entry->tagLen, tagIndex); } else { entry->tag = NULL; } /* * If we don't have a map, or didn't find the tag number in the map, * stuff a generated tag value into the start of the output buffer and * shift the buffer pointers down. */ if (entry->tag == NULL) { size_t tagLen; tagLen = snprintf(messageBuf, messageBufLen, "[%d]", tagIndex); if (tagLen >= (size_t)messageBufLen) { tagLen = messageBufLen - 1; } entry->tag = messageBuf; entry->tagLen = tagLen; messageBuf += tagLen + 1; messageBufLen -= tagLen + 1; } /* * Format the event log data into the buffer. */ char* outBuf = messageBuf; size_t outRemaining = messageBufLen-1; /* leave one for nul byte */ int result; result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, &outRemaining); if (result < 0) { fprintf(stderr, "Binary log entry conversion failed\n"); return -1; } else if (result == 1) { if (outBuf > messageBuf) { /* leave an indicator */ *(outBuf-1) = '!'; } else { /* no room to output anything at all */ *outBuf++ = '!'; outRemaining--; } /* pretend we ate all the data */ inCount = 0; } /* eat the silly terminating '\n' */ if (inCount == 1 && *eventData == '\n') { eventData++; inCount--; } if (inCount != 0) { fprintf(stderr, "Warning: leftover binary log data (%zu bytes)\n", inCount); } /* * Terminate the buffer. The NUL byte does not count as part of * entry->messageLen. */ *outBuf = '\0'; entry->messageLen = outBuf - messageBuf; assert(entry->messageLen == (messageBufLen-1) - outRemaining); entry->message = messageBuf; return 0; }