am 76ed92c3: Merge "logd: better drop message merging"

* commit '76ed92c3c6882af801f8454a1dd9bf8e3a908ba2':
  logd: better drop message merging
This commit is contained in:
Mark Salyzyn 2015-04-20 21:20:40 +00:00 committed by Android Git Automerger
commit cb7f4fd50e

View file

@ -226,6 +226,68 @@ LogBufferElementCollection::iterator LogBuffer::erase(LogBufferElementCollection
return it; return it;
} }
// Define a temporary mechanism to report the last LogBufferElement pointer
// for the specified uid, pid and tid. Used below to help merge-sort when
// pruning for worst UID.
class LogBufferElementKey {
const union {
struct {
uint16_t uid;
uint16_t pid;
uint16_t tid;
uint16_t padding;
} __packed;
uint64_t value;
} __packed;
public:
LogBufferElementKey(uid_t u, pid_t p, pid_t t):uid(u),pid(p),tid(t),padding(0) { }
LogBufferElementKey(uint64_t k):value(k) { }
uint64_t getKey() { return value; }
};
struct LogBufferElementEntry {
const uint64_t key;
LogBufferElement *last;
public:
LogBufferElementEntry(const uint64_t &k, LogBufferElement *e):key(k),last(e) { }
const uint64_t&getKey() const { return key; }
LogBufferElement *getLast() { return last; }
};
struct LogBufferElementLast : public android::BasicHashtable<uint64_t, LogBufferElementEntry> {
bool merge(LogBufferElement *e, unsigned short dropped) {
LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
android::hash_t hash = android::hash_type(key.getKey());
ssize_t index = find(-1, hash, key.getKey());
if (index != -1) {
LogBufferElementEntry &entry = editEntryAt(index);
LogBufferElement *l = entry.getLast();
unsigned short d = l->getDropped();
if ((dropped + d) > USHRT_MAX) {
removeAt(index);
} else {
l->setDropped(dropped + d);
return true;
}
}
return false;
}
size_t add(LogBufferElement *e) {
LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
android::hash_t hash = android::hash_type(key.getKey());
return android::BasicHashtable<uint64_t, LogBufferElementEntry>::
add(hash, LogBufferElementEntry(key.getKey(), e));
}
};
// prune "pruneRows" of type "id" from the buffer. // prune "pruneRows" of type "id" from the buffer.
// //
// mLogElementsLock must be held when this function is called. // mLogElementsLock must be held when this function is called.
@ -301,7 +363,7 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
bool kick = false; bool kick = false;
bool leading = true; bool leading = true;
LogBufferElement *last = NULL; LogBufferElementLast last;
for(it = mLogElements.begin(); it != mLogElements.end();) { for(it = mLogElements.begin(); it != mLogElements.end();) {
LogBufferElement *e = *it; LogBufferElement *e = *it;
@ -322,24 +384,18 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
continue; continue;
} }
pid_t pid = e->getPid();
// merge any drops // merge any drops
if (last && dropped if (dropped && last.merge(e, dropped)) {
&& ((dropped + last->getDropped()) < USHRT_MAX)
&& (last->getPid() == pid)
&& (last->getTid() == e->getTid())) {
it = mLogElements.erase(it); it = mLogElements.erase(it);
stats.erase(e); stats.erase(e);
delete e; delete e;
last->setDropped(dropped + last->getDropped());
continue; continue;
} }
leading = false; leading = false;
if (hasBlacklist && mPrune.naughty(e)) { if (hasBlacklist && mPrune.naughty(e)) {
last = NULL; last.clear();
it = erase(it); it = erase(it);
if (dropped) { if (dropped) {
continue; continue;
@ -361,13 +417,13 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
} }
if (dropped) { if (dropped) {
last = e; last.add(e);
++it; ++it;
continue; continue;
} }
if (e->getUid() != worst) { if (e->getUid() != worst) {
last = NULL; last.clear();
++it; ++it;
continue; continue;
} }
@ -382,17 +438,12 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
unsigned short len = e->getMsgLen(); unsigned short len = e->getMsgLen();
stats.drop(e); stats.drop(e);
e->setDropped(1); e->setDropped(1);
// merge any drops if (last.merge(e, 1)) {
if (last
&& (last->getDropped() < (USHRT_MAX - 1))
&& (last->getPid() == pid)
&& (last->getTid() == e->getTid())) {
it = mLogElements.erase(it); it = mLogElements.erase(it);
stats.erase(e); stats.erase(e);
delete e; delete e;
last->setDropped(last->getDropped() + 1);
} else { } else {
last = e; last.add(e);
++it; ++it;
} }
if (worst_sizes < second_worst_sizes) { if (worst_sizes < second_worst_sizes) {
@ -400,6 +451,7 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
} }
worst_sizes -= len; worst_sizes -= len;
} }
last.clear();
if (!kick || !mPrune.worstUidEnabled()) { if (!kick || !mPrune.worstUidEnabled()) {
break; // the following loop will ask bad clients to skip/drop break; // the following loop will ask bad clients to skip/drop