Loading logd/LogBuffer.cpp +70 −18 Original line number Original line Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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) { Loading @@ -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 Loading Loading
logd/LogBuffer.cpp +70 −18 Original line number Original line Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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) { Loading @@ -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 Loading