Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f29cd20d authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge changes Ia7953e3c,Id1f29f4d,I38623130

* changes:
  logd: use a std::list<> of values not pointers
  logd: refactor chatty deduplication logging
  logd: use RAII locks and thread annotations
parents eb3be2e2 1322472a
Loading
Loading
Loading
Loading
+167 −254

File changed.

Preview size limit exceeded, changes collapsed.

+22 −19
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <optional>
#include <string>

#include <android-base/thread_annotations.h>
#include <android/log.h>
#include <private/android_filesystem_config.h>
#include <sysutils/SocketClient.h>
@@ -34,25 +35,21 @@
#include "LogTags.h"
#include "LogWhiteBlackList.h"
#include "LogWriter.h"
#include "rwlock.h"

typedef std::list<LogBufferElement*> LogBufferElementCollection;
typedef std::list<LogBufferElement> LogBufferElementCollection;

class ChattyLogBuffer : public LogBuffer {
    LogBufferElementCollection mLogElements;
    pthread_rwlock_t mLogElementsLock;
    LogBufferElementCollection mLogElements GUARDED_BY(lock_);

    // watermark of any worst/chatty uid processing
    typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap;
    LogBufferIteratorMap mLastWorst[LOG_ID_MAX];
    LogBufferIteratorMap mLastWorst[LOG_ID_MAX] GUARDED_BY(lock_);
    // watermark of any worst/chatty pid of system processing
    typedef std::unordered_map<pid_t, LogBufferElementCollection::iterator> LogBufferPidIteratorMap;
    LogBufferPidIteratorMap mLastWorstPidOfSystem[LOG_ID_MAX];
    LogBufferPidIteratorMap mLastWorstPidOfSystem[LOG_ID_MAX] GUARDED_BY(lock_);

    unsigned long mMaxSize[LOG_ID_MAX];

    LogBufferElement* lastLoggedElements[LOG_ID_MAX];
    LogBufferElement* droppedElements[LOG_ID_MAX];
    void log(LogBufferElement* elem);
    unsigned long mMaxSize[LOG_ID_MAX] GUARDED_BY(lock_);

  public:
    ChattyLogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune,
@@ -71,20 +68,18 @@ class ChattyLogBuffer : public LogBuffer {
    int SetSize(log_id_t id, unsigned long size) override;

  private:
    void wrlock() { pthread_rwlock_wrlock(&mLogElementsLock); }
    void rdlock() { pthread_rwlock_rdlock(&mLogElementsLock); }
    void unlock() { pthread_rwlock_unlock(&mLogElementsLock); }

    void maybePrune(log_id_t id);
    void kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows);
    void maybePrune(log_id_t id) REQUIRES(lock_);
    void kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows) REQUIRES_SHARED(lock_);

    bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
    bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT) REQUIRES(lock_);
    LogBufferElementCollection::iterator erase(LogBufferElementCollection::iterator it,
                                               bool coalesce = false);
                                               bool coalesce = false) REQUIRES(lock_);
    bool ShouldLog(log_id_t log_id, const char* msg, uint16_t len);
    void Log(LogBufferElement&& elem) REQUIRES(lock_);

    // 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);
    LogBufferElementCollection::iterator GetOldest(log_id_t log_id) REQUIRES(lock_);

    LogReaderList* reader_list_;
    LogTags* tags_;
@@ -94,4 +89,12 @@ class ChattyLogBuffer : public LogBuffer {
    // 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> oldest_[LOG_ID_MAX];

    RwLock lock_;

    // This always contains a copy of the last message logged, for deduplication.
    std::optional<LogBufferElement> last_logged_elements_[LOG_ID_MAX] GUARDED_BY(lock_);
    // This contains an element if duplicate messages are seen.
    // Its `dropped` count is `duplicates seen - 1`.
    std::optional<LogBufferElement> duplicate_elements_[LOG_ID_MAX] GUARDED_BY(lock_);
};
+17 −0
Original line number Diff line number Diff line
@@ -63,6 +63,23 @@ LogBufferElement::LogBufferElement(const LogBufferElement& elem)
    }
}

LogBufferElement::LogBufferElement(LogBufferElement&& elem)
    : mUid(elem.mUid),
      mPid(elem.mPid),
      mTid(elem.mTid),
      mSequence(elem.mSequence),
      mRealTime(elem.mRealTime),
      mMsgLen(elem.mMsgLen),
      mLogId(elem.mLogId),
      mDropped(elem.mDropped) {
    if (mDropped) {
        mTag = elem.getTag();
    } else {
        mMsg = elem.mMsg;
        elem.mMsg = nullptr;
    }
}

LogBufferElement::~LogBufferElement() {
    if (!mDropped) {
        delete[] mMsg;
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ class __attribute__((packed)) LogBufferElement {
    LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
                     pid_t tid, const char* msg, uint16_t len);
    LogBufferElement(const LogBufferElement& elem);
    LogBufferElement(LogBufferElement&& elem);
    ~LogBufferElement();

    bool isBinary(void) const {
+1 −4
Original line number Diff line number Diff line
@@ -79,12 +79,9 @@ char* pidToName(pid_t pid) {
}
}

void LogStatistics::AddTotal(LogBufferElement* element) {
void LogStatistics::AddTotal(log_id_t log_id, uint16_t size) {
    auto lock = std::lock_guard{lock_};
    if (element->getDropped()) return;

    log_id_t log_id = element->getLogId();
    uint16_t size = element->getMsgLen();
    mSizesTotal[log_id] += size;
    SizesTotal += size;
    ++mElementsTotal[log_id];
Loading