Loading logd/LogBuffer.cpp +27 −40 Original line number Diff line number Diff line Loading @@ -46,9 +46,6 @@ void LogBuffer::init() { log_id_for_each(i) { mLastSet[i] = false; mLast[i] = mLogElements.begin(); if (setSize(i, __android_logger_get_buffer_size(i))) { setSize(i, LOG_BUFFER_MIN_SIZE); } Loading Loading @@ -131,6 +128,20 @@ LogBuffer::~LogBuffer() { } } LogBufferElementCollection::iterator LogBuffer::GetOldest(log_id_t log_id) { auto it = mLogElements.begin(); if (mOldest[log_id]) { it = *mOldest[log_id]; } while (it != mLogElements.end() && (*it)->getLogId() != log_id) { it++; } if (it != mLogElements.end()) { mOldest[log_id] = it; } return it; } enum match_type { DIFFERENT, SAME, SAME_LIBLOG }; static enum match_type identical(LogBufferElement* elem, Loading Loading @@ -450,9 +461,7 @@ LogBufferElementCollection::iterator LogBuffer::erase( bool setLast[LOG_ID_MAX]; bool doSetLast = false; log_id_for_each(i) { doSetLast |= setLast[i] = mLastSet[i] && (it == mLast[i]); } log_id_for_each(i) { doSetLast |= setLast[i] = mOldest[i] && it == *mOldest[i]; } #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES LogBufferElementCollection::iterator bad = it; int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) Loading @@ -463,11 +472,11 @@ LogBufferElementCollection::iterator LogBuffer::erase( if (doSetLast) { log_id_for_each(i) { if (setLast[i]) { if (__predict_false(it == mLogElements.end())) { // impossible mLastSet[i] = false; mLast[i] = mLogElements.begin(); if (__predict_false(it == mLogElements.end())) { mOldest[i] = std::nullopt; } else { mLast[i] = it; // push down the road as next-best-watermark mOldest[i] = it; // Store the next iterator even if it does not correspond to // the same log_id, as a starting point for GetOldest(). } } } Loading @@ -486,11 +495,6 @@ LogBufferElementCollection::iterator LogBuffer::erase( b.first); } } if (mLastSet[i] && (bad == mLast[i])) { android::prdebug("stale mLast[%d]\n", i); mLastSet[i] = false; mLast[i] = mLogElements.begin(); } } #endif if (coalesce) { Loading Loading @@ -668,7 +672,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { if (__predict_false(caller_uid != AID_ROOT)) { // unlikely // Only here if clear all request from non system source, so chatty // filter logistics is not required. it = mLastSet[id] ? mLast[id] : mLogElements.begin(); it = GetOldest(id); while (it != mLogElements.end()) { LogBufferElement* element = *it; Loading @@ -678,11 +682,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } if (!mLastSet[id] || ((*mLast[id])->getLogId() != id)) { mLast[id] = it; mLastSet[id] = true; } if (oldest && oldest->mStart <= element->getSequence()) { busy = true; kickMe(oldest, id, pruneRows); Loading Loading @@ -734,8 +733,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } bool kick = false; bool leading = true; it = mLastSet[id] ? mLast[id] : mLogElements.begin(); bool leading = true; // true if starting from the oldest log entry, false if starting from // a specific chatty entry. // Perform at least one mandatory garbage collection cycle in following // - clear leading chatty tags // - coalesce chatty tags Loading Loading @@ -763,6 +762,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } } } if (leading) { it = GetOldest(id); } static const timespec too_old = { EXPIRE_HOUR_THRESHOLD * 60 * 60, 0 }; LogBufferElementCollection::iterator lastt; lastt = mLogElements.end(); Loading @@ -783,11 +785,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } // below this point element->getLogId() == id if (leading && (!mLastSet[id] || ((*mLast[id])->getLogId() != id))) { mLast[id] = it; mLastSet[id] = true; } uint16_t dropped = element->getDropped(); // remove any leading drops Loading Loading @@ -909,7 +906,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { bool whitelist = false; bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll; it = mLastSet[id] ? mLast[id] : mLogElements.begin(); it = GetOldest(id); while ((pruneRows > 0) && (it != mLogElements.end())) { LogBufferElement* element = *it; Loading @@ -918,11 +915,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } if (!mLastSet[id] || ((*mLast[id])->getLogId() != id)) { mLast[id] = it; mLastSet[id] = true; } if (oldest && oldest->mStart <= element->getSequence()) { busy = true; if (!whitelist) kickMe(oldest, id, pruneRows); Loading @@ -942,7 +934,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { // Do not save the whitelist if we are reader range limited if (whitelist && (pruneRows > 0)) { it = mLastSet[id] ? mLast[id] : mLogElements.begin(); it = GetOldest(id); while ((it != mLogElements.end()) && (pruneRows > 0)) { LogBufferElement* element = *it; Loading @@ -951,11 +943,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } if (!mLastSet[id] || ((*mLast[id])->getLogId() != id)) { mLast[id] = it; mLastSet[id] = true; } if (oldest && oldest->mStart <= element->getSequence()) { busy = true; kickMe(oldest, id, pruneRows); Loading logd/LogBuffer.h +8 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <sys/types.h> #include <list> #include <optional> #include <string> #include <android/log.h> Loading Loading @@ -81,9 +82,9 @@ class LogBuffer { LogStatistics stats; PruneList mPrune; // watermark for last per log id LogBufferElementCollection::iterator mLast[LOG_ID_MAX]; bool mLastSet[LOG_ID_MAX]; // Keeps track of the iterator to the oldest log message of a given log type, as an // optimization when pruning logs. Use GetOldest() to retrieve. std::optional<LogBufferElementCollection::iterator> mOldest[LOG_ID_MAX]; // watermark of any worst/chatty uid processing typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap; Loading Loading @@ -181,6 +182,10 @@ class LogBuffer { bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT); LogBufferElementCollection::iterator erase( LogBufferElementCollection::iterator it, bool coalesce = false); // Returns an iterator to the oldest element for a given log type, or mLogElements.end() if // there are no logs for the given log type. Requires mLogElementsLock to be held. LogBufferElementCollection::iterator GetOldest(log_id_t log_id); }; #endif // _LOGD_LOG_BUFFER_H__ Loading
logd/LogBuffer.cpp +27 −40 Original line number Diff line number Diff line Loading @@ -46,9 +46,6 @@ void LogBuffer::init() { log_id_for_each(i) { mLastSet[i] = false; mLast[i] = mLogElements.begin(); if (setSize(i, __android_logger_get_buffer_size(i))) { setSize(i, LOG_BUFFER_MIN_SIZE); } Loading Loading @@ -131,6 +128,20 @@ LogBuffer::~LogBuffer() { } } LogBufferElementCollection::iterator LogBuffer::GetOldest(log_id_t log_id) { auto it = mLogElements.begin(); if (mOldest[log_id]) { it = *mOldest[log_id]; } while (it != mLogElements.end() && (*it)->getLogId() != log_id) { it++; } if (it != mLogElements.end()) { mOldest[log_id] = it; } return it; } enum match_type { DIFFERENT, SAME, SAME_LIBLOG }; static enum match_type identical(LogBufferElement* elem, Loading Loading @@ -450,9 +461,7 @@ LogBufferElementCollection::iterator LogBuffer::erase( bool setLast[LOG_ID_MAX]; bool doSetLast = false; log_id_for_each(i) { doSetLast |= setLast[i] = mLastSet[i] && (it == mLast[i]); } log_id_for_each(i) { doSetLast |= setLast[i] = mOldest[i] && it == *mOldest[i]; } #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES LogBufferElementCollection::iterator bad = it; int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) Loading @@ -463,11 +472,11 @@ LogBufferElementCollection::iterator LogBuffer::erase( if (doSetLast) { log_id_for_each(i) { if (setLast[i]) { if (__predict_false(it == mLogElements.end())) { // impossible mLastSet[i] = false; mLast[i] = mLogElements.begin(); if (__predict_false(it == mLogElements.end())) { mOldest[i] = std::nullopt; } else { mLast[i] = it; // push down the road as next-best-watermark mOldest[i] = it; // Store the next iterator even if it does not correspond to // the same log_id, as a starting point for GetOldest(). } } } Loading @@ -486,11 +495,6 @@ LogBufferElementCollection::iterator LogBuffer::erase( b.first); } } if (mLastSet[i] && (bad == mLast[i])) { android::prdebug("stale mLast[%d]\n", i); mLastSet[i] = false; mLast[i] = mLogElements.begin(); } } #endif if (coalesce) { Loading Loading @@ -668,7 +672,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { if (__predict_false(caller_uid != AID_ROOT)) { // unlikely // Only here if clear all request from non system source, so chatty // filter logistics is not required. it = mLastSet[id] ? mLast[id] : mLogElements.begin(); it = GetOldest(id); while (it != mLogElements.end()) { LogBufferElement* element = *it; Loading @@ -678,11 +682,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } if (!mLastSet[id] || ((*mLast[id])->getLogId() != id)) { mLast[id] = it; mLastSet[id] = true; } if (oldest && oldest->mStart <= element->getSequence()) { busy = true; kickMe(oldest, id, pruneRows); Loading Loading @@ -734,8 +733,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } bool kick = false; bool leading = true; it = mLastSet[id] ? mLast[id] : mLogElements.begin(); bool leading = true; // true if starting from the oldest log entry, false if starting from // a specific chatty entry. // Perform at least one mandatory garbage collection cycle in following // - clear leading chatty tags // - coalesce chatty tags Loading Loading @@ -763,6 +762,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } } } if (leading) { it = GetOldest(id); } static const timespec too_old = { EXPIRE_HOUR_THRESHOLD * 60 * 60, 0 }; LogBufferElementCollection::iterator lastt; lastt = mLogElements.end(); Loading @@ -783,11 +785,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } // below this point element->getLogId() == id if (leading && (!mLastSet[id] || ((*mLast[id])->getLogId() != id))) { mLast[id] = it; mLastSet[id] = true; } uint16_t dropped = element->getDropped(); // remove any leading drops Loading Loading @@ -909,7 +906,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { bool whitelist = false; bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll; it = mLastSet[id] ? mLast[id] : mLogElements.begin(); it = GetOldest(id); while ((pruneRows > 0) && (it != mLogElements.end())) { LogBufferElement* element = *it; Loading @@ -918,11 +915,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } if (!mLastSet[id] || ((*mLast[id])->getLogId() != id)) { mLast[id] = it; mLastSet[id] = true; } if (oldest && oldest->mStart <= element->getSequence()) { busy = true; if (!whitelist) kickMe(oldest, id, pruneRows); Loading @@ -942,7 +934,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { // Do not save the whitelist if we are reader range limited if (whitelist && (pruneRows > 0)) { it = mLastSet[id] ? mLast[id] : mLogElements.begin(); it = GetOldest(id); while ((it != mLogElements.end()) && (pruneRows > 0)) { LogBufferElement* element = *it; Loading @@ -951,11 +943,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } if (!mLastSet[id] || ((*mLast[id])->getLogId() != id)) { mLast[id] = it; mLastSet[id] = true; } if (oldest && oldest->mStart <= element->getSequence()) { busy = true; kickMe(oldest, id, pruneRows); Loading
logd/LogBuffer.h +8 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <sys/types.h> #include <list> #include <optional> #include <string> #include <android/log.h> Loading Loading @@ -81,9 +82,9 @@ class LogBuffer { LogStatistics stats; PruneList mPrune; // watermark for last per log id LogBufferElementCollection::iterator mLast[LOG_ID_MAX]; bool mLastSet[LOG_ID_MAX]; // Keeps track of the iterator to the oldest log message of a given log type, as an // optimization when pruning logs. Use GetOldest() to retrieve. std::optional<LogBufferElementCollection::iterator> mOldest[LOG_ID_MAX]; // watermark of any worst/chatty uid processing typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap; Loading Loading @@ -181,6 +182,10 @@ class LogBuffer { bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT); LogBufferElementCollection::iterator erase( LogBufferElementCollection::iterator it, bool coalesce = false); // Returns an iterator to the oldest element for a given log type, or mLogElements.end() if // there are no logs for the given log type. Requires mLogElementsLock to be held. LogBufferElementCollection::iterator GetOldest(log_id_t log_id); }; #endif // _LOGD_LOG_BUFFER_H__