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

Commit 4596b78d authored by Tom Cherry's avatar Tom Cherry
Browse files

logd: don't store the map key in its value

The keys are already available when iterating through the maps, so
this only serves to waste memory.

Test: unit tests
Change-Id: Iaf4e389eb0f0990e7113cd78be1773e767a356d4
parent f93b4006
Loading
Loading
Loading
Loading
+29 −26
Original line number Diff line number Diff line
@@ -308,8 +308,9 @@ template <typename TKey, typename TEntry>
void LogStatistics::WorstTwoWithThreshold(const LogHashtable<TKey, TEntry>& table, size_t threshold,
                                          int* worst, size_t* worst_sizes,
                                          size_t* second_worst_sizes) const {
    std::array<const TKey*, 2> max_keys;
    std::array<const TEntry*, 2> max_entries;
    table.MaxEntries(AID_ROOT, 0, &max_entries);
    table.MaxEntries(AID_ROOT, 0, max_keys, max_entries);
    if (max_entries[0] == nullptr || max_entries[1] == nullptr) {
        return;
    }
@@ -317,7 +318,7 @@ void LogStatistics::WorstTwoWithThreshold(const LogHashtable<TKey, TEntry>& tabl
    // b/24782000: Allow time horizon to extend roughly tenfold, assume average entry length is
    // 100 characters.
    if (*worst_sizes > threshold && *worst_sizes > (10 * max_entries[0]->dropped_count())) {
        *worst = max_entries[0]->key();
        *worst = *max_keys[0];
        *second_worst_sizes = max_entries[1]->getSizes();
        if (*second_worst_sizes < threshold) {
            *second_worst_sizes = threshold;
@@ -340,13 +341,14 @@ void LogStatistics::WorstTwoTags(size_t threshold, int* worst, size_t* worst_siz
void LogStatistics::WorstTwoSystemPids(log_id id, size_t worst_uid_sizes, int* worst,
                                       size_t* second_worst_sizes) const {
    auto lock = std::lock_guard{lock_};
    std::array<const pid_t*, 2> max_keys;
    std::array<const PidEntry*, 2> max_entries;
    pidSystemTable[id].MaxEntries(AID_SYSTEM, 0, &max_entries);
    pidSystemTable[id].MaxEntries(AID_SYSTEM, 0, max_keys, max_entries);
    if (max_entries[0] == nullptr || max_entries[1] == nullptr) {
        return;
    }

    *worst = max_entries[0]->key();
    *worst = *max_keys[0];
    *second_worst_sizes = worst_uid_sizes - max_entries[0]->getSizes() + max_entries[1]->getSizes();
}

@@ -412,11 +414,12 @@ void LogStatistics::FormatTmp(const char* nameTmp, uid_t uid, std::string& name,
    }
}

std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUIRES(stat.lock_) {
    std::string name = android::base::StringPrintf("%u", uid_);
std::string UidEntry::format(const LogStatistics& stat, log_id_t id, uid_t uid) const
        REQUIRES(stat.lock_) {
    std::string name = android::base::StringPrintf("%u", uid);
    std::string size = android::base::StringPrintf("%zu", getSizes());

    stat.FormatTmp(nullptr, uid_, name, size, 6);
    stat.FormatTmp(nullptr, uid, name, size, 6);

    std::string pruned = "";
    if (worstUidEnabledForLogid(id)) {
@@ -474,19 +477,20 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI

    std::string output = formatLine(name, size, pruned);

    if (uid_ != AID_SYSTEM) {
    if (uid != AID_SYSTEM) {
        return output;
    }

    static const size_t maximum_sorted_entries = 32;
    std::array<const PidEntry*, maximum_sorted_entries> sorted;
    stat.pidSystemTable[id].MaxEntries(uid_, 0, &sorted);
    std::array<const pid_t*, maximum_sorted_entries> sorted_pids;
    std::array<const PidEntry*, maximum_sorted_entries> sorted_entries;
    stat.pidSystemTable[id].MaxEntries(uid, 0, sorted_pids, sorted_entries);

    std::string byPid;
    size_t index;
    bool hasDropped = false;
    for (index = 0; index < maximum_sorted_entries; ++index) {
        const PidEntry* entry = sorted[index];
        const PidEntry* entry = sorted_entries[index];
        if (!entry) {
            break;
        }
@@ -496,7 +500,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI
        if (entry->dropped_count()) {
            hasDropped = true;
        }
        byPid += entry->format(stat, id);
        byPid += entry->format(stat, id, *sorted_pids[index]);
    }
    if (index > 1) {  // print this only if interesting
        std::string ditto("\" ");
@@ -515,9 +519,9 @@ std::string PidEntry::formatHeader(const std::string& name,
                      std::string("BYTES"), std::string("NUM"));
}

std::string PidEntry::format(const LogStatistics& stat, log_id_t /* id */) const
std::string PidEntry::format(const LogStatistics& stat, log_id_t, pid_t pid) const
        REQUIRES(stat.lock_) {
    std::string name = android::base::StringPrintf("%5u/%u", pid_, uid_);
    std::string name = android::base::StringPrintf("%5u/%u", pid, uid_);
    std::string size = android::base::StringPrintf("%zu", getSizes());

    stat.FormatTmp(name_, uid_, name, size, 12);
@@ -538,9 +542,9 @@ std::string TidEntry::formatHeader(const std::string& name,
                      std::string("NUM"));
}

std::string TidEntry::format(const LogStatistics& stat, log_id_t /* id */) const
std::string TidEntry::format(const LogStatistics& stat, log_id_t, pid_t tid) const
        REQUIRES(stat.lock_) {
    std::string name = android::base::StringPrintf("%5u/%u", tid(), uid_);
    std::string name = android::base::StringPrintf("%5u/%u", tid, uid_);
    std::string size = android::base::StringPrintf("%zu", getSizes());

    stat.FormatTmp(name_, uid_, name, size, 12);
@@ -562,8 +566,7 @@ std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const {
                      std::string("BYTES"), std::string(isprune ? "NUM" : ""));
}

std::string TagEntry::format(const LogStatistics& /* stat */,
                             log_id_t /* id */) const {
std::string TagEntry::format(const LogStatistics&, log_id_t, uint32_t) const {
    std::string name;
    if (uid_ == (uid_t)-1) {
        name = android::base::StringPrintf("%7u", key());
@@ -594,8 +597,7 @@ std::string TagNameEntry::formatHeader(const std::string& name,
                      std::string("BYTES"), std::string(""));
}

std::string TagNameEntry::format(const LogStatistics& /* stat */,
                                 log_id_t /* id */) const {
std::string TagNameEntry::format(const LogStatistics&, log_id_t, const TagNameKey& key_name) const {
    std::string name;
    std::string pidstr;
    if (pid_ != (pid_t)-1) {
@@ -616,7 +618,7 @@ std::string TagNameEntry::format(const LogStatistics& /* stat */,

    std::string size = android::base::StringPrintf("%zu", getSizes());

    const char* nameTmp = this->name();
    const char* nameTmp = key_name.data();
    if (nameTmp) {
        size_t lenSpace = std::max(16 - name.length(), (size_t)1);
        size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() -
@@ -684,15 +686,16 @@ std::string LogStatistics::FormatTable(const LogHashtable<TKey, TEntry>& table,
        REQUIRES(lock_) {
    static const size_t maximum_sorted_entries = 32;
    std::string output;
    std::array<const TEntry*, maximum_sorted_entries> sorted;
    table.MaxEntries(uid, pid, &sorted);
    std::array<const TKey*, maximum_sorted_entries> sorted_keys;
    std::array<const TEntry*, maximum_sorted_entries> sorted_entries;
    table.MaxEntries(uid, pid, sorted_keys, sorted_entries);
    bool header_printed = false;
    for (size_t index = 0; index < maximum_sorted_entries; ++index) {
        const TEntry* entry = sorted[index];
        const TEntry* entry = sorted_entries[index];
        if (!entry) {
            break;
        }
        if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) {
        if (entry->getSizes() <= (sorted_entries[0]->getSizes() / 100)) {
            break;
        }
        if (!header_printed) {
@@ -700,7 +703,7 @@ std::string LogStatistics::FormatTable(const LogHashtable<TKey, TEntry>& table,
            output += entry->formatHeader(name, id);
            header_printed = true;
        }
        output += entry->format(*this, id);
        output += entry->format(*this, id, *sorted_keys[index]);
    }
    return output;
}
+37 −48
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@
    for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t)((i) + 1))

class LogStatistics;
class UidEntry;
class PidEntry;

struct LogStatisticsElement {
    uid_t uid;
@@ -95,31 +97,43 @@ class LogHashtable {
    // Returns a sorted array of up to len highest entries sorted by size.  If fewer than len
    // entries are found, their positions are set to nullptr.
    template <size_t len>
    void MaxEntries(uid_t uid, pid_t pid, std::array<const TEntry*, len>* out) const {
        auto& retval = *out;
        retval.fill(nullptr);
        for (const_iterator it = map.begin(); it != map.end(); ++it) {
            const TEntry& entry = it->second;

            if (uid != AID_ROOT && uid != entry.uid()) {
    void MaxEntries(uid_t uid, pid_t pid, std::array<const TKey*, len>& out_keys,
                    std::array<const TEntry*, len>& out_entries) const {
        out_keys.fill(nullptr);
        out_entries.fill(nullptr);
        for (const auto& [key, entry] : map) {
            uid_t entry_uid = 0;
            if constexpr (std::is_same_v<TEntry, UidEntry>) {
                entry_uid = key;
            } else {
                entry_uid = entry.uid();
            }
            if (uid != AID_ROOT && uid != entry_uid) {
                continue;
            }
            if (pid && entry.pid() && pid != entry.pid()) {
            pid_t entry_pid = 0;
            if constexpr (std::is_same_v<TEntry, PidEntry>) {
                entry_pid = key;
            } else {
                entry_pid = entry.pid();
            }
            if (pid && entry_pid && pid != entry_pid) {
                continue;
            }

            size_t sizes = entry.getSizes();
            ssize_t index = len - 1;
            while ((!retval[index] || (sizes > retval[index]->getSizes())) &&
                   (--index >= 0))
            while ((!out_entries[index] || sizes > out_entries[index]->getSizes()) && --index >= 0)
                ;
            if (++index < (ssize_t)len) {
                size_t num = len - index - 1;
                if (num) {
                    memmove(&retval[index + 1], &retval[index],
                            num * sizeof(retval[0]));
                    memmove(&out_keys[index + 1], &out_keys[index], num * sizeof(out_keys[0]));
                    memmove(&out_entries[index + 1], &out_entries[index],
                            num * sizeof(out_entries[0]));
                }
                retval[index] = &entry;
                out_keys[index] = &key;
                out_entries[index] = &entry;
            }
        }
    }
@@ -229,10 +243,8 @@ class EntryBaseDropped : public EntryBase {
class UidEntry : public EntryBaseDropped {
  public:
    explicit UidEntry(const LogStatisticsElement& element)
        : EntryBaseDropped(element), uid_(element.uid), pid_(element.pid) {}
        : EntryBaseDropped(element), pid_(element.pid) {}

    uid_t key() const { return uid_; }
    uid_t uid() const { return key(); }
    pid_t pid() const { return pid_; }

    void Add(const LogStatisticsElement& element) {
@@ -243,10 +255,9 @@ class UidEntry : public EntryBaseDropped {
    }

    std::string formatHeader(const std::string& name, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id, uid_t uid) const;

  private:
    const uid_t uid_;
    pid_t pid_;
};

@@ -258,23 +269,16 @@ class PidEntry : public EntryBaseDropped {
  public:
    explicit PidEntry(pid_t pid)
        : EntryBaseDropped(),
          pid_(pid),
          uid_(android::pidToUid(pid)),
          name_(android::pidToName(pid)) {}
    explicit PidEntry(const LogStatisticsElement& element)
        : EntryBaseDropped(element),
          pid_(element.pid),
          uid_(element.uid),
          name_(android::pidToName(pid_)) {}
        : EntryBaseDropped(element), uid_(element.uid), name_(android::pidToName(element.pid)) {}
    PidEntry(const PidEntry& element)
        : EntryBaseDropped(element),
          pid_(element.pid_),
          uid_(element.uid_),
          name_(element.name_ ? strdup(element.name_) : nullptr) {}
    ~PidEntry() { free(name_); }

    pid_t key() const { return pid_; }
    pid_t pid() const { return key(); }
    uid_t uid() const { return uid_; }
    const char* name() const { return name_; }

@@ -301,10 +305,9 @@ class PidEntry : public EntryBaseDropped {
    }

    std::string formatHeader(const std::string& name, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id, pid_t pid) const;

  private:
    const pid_t pid_;
    uid_t uid_;
    char* name_;
};
@@ -313,26 +316,21 @@ class TidEntry : public EntryBaseDropped {
  public:
    TidEntry(pid_t tid, pid_t pid)
        : EntryBaseDropped(),
          tid_(tid),
          pid_(pid),
          uid_(android::pidToUid(tid)),
          name_(android::tidToName(tid)) {}
    explicit TidEntry(const LogStatisticsElement& element)
        : EntryBaseDropped(element),
          tid_(element.tid),
          pid_(element.pid),
          uid_(element.uid),
          name_(android::tidToName(tid_)) {}
          name_(android::tidToName(element.tid)) {}
    TidEntry(const TidEntry& element)
        : EntryBaseDropped(element),
          tid_(element.tid_),
          pid_(element.pid_),
          uid_(element.uid_),
          name_(element.name_ ? strdup(element.name_) : nullptr) {}
    ~TidEntry() { free(name_); }

    pid_t key() const { return tid_; }
    pid_t tid() const { return key(); }
    pid_t pid() const { return pid_; }
    uid_t uid() const { return uid_; }
    const char* name() const { return name_; }
@@ -362,10 +360,9 @@ class TidEntry : public EntryBaseDropped {
    }

    std::string formatHeader(const std::string& name, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id, pid_t pid) const;

  private:
    const pid_t tid_;
    pid_t pid_;
    uid_t uid_;
    char* name_;
@@ -392,7 +389,7 @@ class TagEntry : public EntryBaseDropped {
    }

    std::string formatHeader(const std::string& name, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id, uint32_t) const;

  private:
    const uint32_t tag_;
@@ -490,18 +487,11 @@ struct std::hash<TagNameKey>
class TagNameEntry : public EntryBase {
  public:
    explicit TagNameEntry(const LogStatisticsElement& element)
        : EntryBase(element),
          tid_(element.tid),
          pid_(element.pid),
          uid_(element.uid),
          name_(element) {}
        : EntryBase(element), tid_(element.tid), pid_(element.pid), uid_(element.uid) {}

    const TagNameKey& key() const { return name_; }
    pid_t tid() const { return tid_; }
    pid_t pid() const { return pid_; }
    uid_t uid() const { return uid_; }
    const char* name() const { return name_.data(); }
    size_t getNameAllocLength() const { return name_.getAllocLength(); }

    void Add(const LogStatisticsElement& element) {
        if (uid_ != element.uid) {
@@ -517,13 +507,12 @@ class TagNameEntry : public EntryBase {
    }

    std::string formatHeader(const std::string& name, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id) const;
    std::string format(const LogStatistics& stat, log_id_t id, const TagNameKey& key_name) const;

  private:
    pid_t tid_;
    pid_t pid_;
    uid_t uid_;
    TagNameKey name_;
};

// Log Statistics
@@ -584,7 +573,7 @@ class LogStatistics {
            const char* name = it.second.name();
            if (name) size += strlen(name) + 1;
        }
        for (auto it : tagNameTable) size += it.second.getNameAllocLength();
        for (auto it : tagNameTable) size += it.first.getAllocLength();
        log_id_for_each(id) {
            size += uidTable[id].sizeOf();
            size += uidTable[id].size() * sizeof(uidTable_t::iterator);