diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 2b6c27688..fbd04ef8c 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -374,15 +375,9 @@ void LogBuffer::log(LogBufferElement* elem) { // NB: if end is region locked, place element at end of list LogBufferElementCollection::iterator it = mLogElements.end(); LogBufferElementCollection::iterator last = it; - while (last != mLogElements.begin()) { - --it; - if ((*it)->getRealTime() <= elem->getRealTime()) { - break; - } - last = it; - } - - if (last == mLogElements.end()) { + if (__predict_true(it != mLogElements.begin())) --it; + if (__predict_false(it == mLogElements.begin()) || + __predict_true((*it)->getRealTime() <= elem->getRealTime())) { mLogElements.push_back(elem); } else { uint64_t end = 1; @@ -399,6 +394,7 @@ void LogBuffer::log(LogBufferElement* elem) { 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; @@ -407,12 +403,23 @@ void LogBuffer::log(LogBufferElement* elem) { times++; } - if (end_always || (end_set && (end >= (*last)->getSequence()))) { + if (end_always || (end_set && (end > (*it)->getSequence()))) { mLogElements.push_back(elem); } else { + // should be short as timestamps are localized near end() + do { + last = it; + if (__predict_false(it == mLogElements.begin())) { + break; + } + + std::swap((*it)->mSequence, elem->mSequence); + + --it; + } while (((*it)->getRealTime() > elem->getRealTime()) && + (!end_set || (end <= (*it)->getSequence()))); mLogElements.insert(last, elem); } - LogTimeEntry::unlock(); } diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h index 43990e835..90756dd4b 100644 --- a/logd/LogBufferElement.h +++ b/logd/LogBufferElement.h @@ -40,7 +40,7 @@ class LogBufferElement { const uint32_t mUid; const uint32_t mPid; const uint32_t mTid; - const uint64_t mSequence; + uint64_t mSequence; log_time mRealTime; char* mMsg; union {