Merge "logd: refactor mLast setting into a GetOldest function"

This commit is contained in:
Tom Cherry 2020-04-30 19:53:17 +00:00 committed by Gerrit Code Review
commit 1a342a12f3
2 changed files with 35 additions and 43 deletions

View file

@ -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);
}
@ -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,
@ -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))
@ -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().
}
}
}
@ -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) {
@ -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;
@ -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);
@ -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
@ -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();
@ -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
@ -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;
@ -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);
@ -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;
@ -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);

View file

@ -20,6 +20,7 @@
#include <sys/types.h>
#include <list>
#include <optional>
#include <string>
#include <android/log.h>
@ -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;
@ -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__