// To clear the entire buffer is secure/safe, but this contributes to 1.68% // overhead under logging load. We are safe because we check counts. // memset(buffer, 0, sizeof(buffer)); ssize_t n = recvmsg(socket, &hdr, 0); if (n <= (ssize_t)(sizeof(android_log_header_t))) { returnfalse; }
if (cred->uid == AID_LOGD) { // ignore log messages we send to ourself. // Such log messages are often generated by libraries we depend on // which use standard Android logging. returnfalse; }
// assumes mLogElementsLock held, owns elem, will look after garbage collection void LogBuffer::log(LogBufferElement* elem) { // cap on how far back we will sort in-place, otherwise append staticuint32_t too_far_back = 5; // five seconds // Insert elements in time sorted order if possible // NB: if end is region locked, place element at end of list LogBufferElementCollection::iterator it = mLogElements.end(); LogBufferElementCollection::iterator last = it; // 让 it 指向列表的最后一个元素 if (__predict_true(it != mLogElements.begin())) --it; if (__predict_false(it == mLogElements.begin()) || __predict_true((*it)->getRealTime() <= elem->getRealTime()) || __predict_false((((*it)->getRealTime().tv_sec - too_far_back) > elem->getRealTime().tv_sec) && (elem->getLogId() != LOG_ID_KERNEL) && ((*it)->getLogId() != LOG_ID_KERNEL))) { mLogElements.push_back(elem); } else { log_time end = log_time::EPOCH; bool end_set = false; bool end_always = false;
LogTimeEntry::lock();
LastLogTimes::iterator times = mTimes.begin(); while (times != mTimes.end()) { LogTimeEntry* entry = (*times); if (entry->owned_Locked()) { if (!entry->mNonBlock) { end_always = true; break; } // it passing mEnd is blocked by the following checks. if (!end_set || (end <= entry->mEnd)) { end = entry->mEnd; end_set = true; } } times++; }
if (end_always || (end_set && (end > (*it)->getRealTime()))) { mLogElements.push_back(elem); } else { // should be short as timestamps are localized near end() do { last = it; if (__predict_false(it == mLogElements.begin())) { break; } --it; } while (((*it)->getRealTime() > elem->getRealTime()) && (!end_set || (end <= (*it)->getRealTime()))); mLogElements.insert(last, elem); } LogTimeEntry::unlock(); }
stats.add(elem); maybePrune(elem->getLogId()); }
__predict_true 和 __predict_false 用来提示编译器对应的判断很可能是 true/false,类似于 Linux 内核的 likely/unlikely。如果判断正确,可以得到很大的性能提升。