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

Commit aaf9c1b3 authored by Mark Salyzyn's avatar Mark Salyzyn Committed by Gerrit Code Review
Browse files

Merge "logd: class hierarcy for Uid and Pid statistics."

parents 8b9170b8 81b3eabc
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@
#include <log/log.h>
#include <log/log_read.h>

// Hijack this header as a common include file used by most all sources
// to report some utilities defined here and there.

namespace android {

// Furnished in main.cpp. Caller must own and free returned value
+12 −113
Original line number Diff line number Diff line
@@ -70,21 +70,7 @@ void LogStatistics::add(LogBufferElement *e) {
    mSizes[log_id] += size;
    ++mElements[log_id];

    uid_t uid = e->getUid();
    unsigned short dropped = e->getDropped();
    android::hash_t hash = android::hash_type(uid);
    uidTable_t &table = uidTable[log_id];
    ssize_t index = table.find(-1, hash, uid);
    if (index == -1) {
        UidEntry initEntry(uid);
        initEntry.add(size);
        initEntry.add_dropped(dropped);
        table.add(hash, initEntry);
    } else {
        UidEntry &entry = table.editEntryAt(index);
        entry.add(size);
        entry.add_dropped(dropped);
    }
    uidTable[log_id].add(e->getUid(), e);

    mSizesTotal[log_id] += size;
    ++mElementsTotal[log_id];
@@ -93,28 +79,7 @@ void LogStatistics::add(LogBufferElement *e) {
        return;
    }

    pid_t pid = e->getPid();
    hash = android::hash_type(pid);
    index = pidTable.find(-1, hash, pid);
    if (index == -1) {
        PidEntry initEntry(pid, uid, android::pidToName(pid));
        initEntry.add(size);
        initEntry.add_dropped(dropped);
        pidTable.add(hash, initEntry);
    } else {
        PidEntry &entry = pidTable.editEntryAt(index);
        if (entry.getUid() != uid) {
            entry.setUid(uid);
            entry.setName(android::pidToName(pid));
        } else if (!entry.getName()) {
            char *name = android::pidToName(pid);
            if (name) {
                entry.setName(name);
            }
        }
        entry.add(size);
        entry.add_dropped(dropped);
    }
    pidTable.add(e->getPid(), e);
}

void LogStatistics::subtract(LogBufferElement *e) {
@@ -123,31 +88,13 @@ void LogStatistics::subtract(LogBufferElement *e) {
    mSizes[log_id] -= size;
    --mElements[log_id];

    uid_t uid = e->getUid();
    unsigned short dropped = e->getDropped();
    android::hash_t hash = android::hash_type(uid);
    uidTable_t &table = uidTable[log_id];
    ssize_t index = table.find(-1, hash, uid);
    if (index != -1) {
        UidEntry &entry = table.editEntryAt(index);
        if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
            table.removeAt(index);
        }
    }
    uidTable[log_id].subtract(e->getUid(), e);

    if (!enable) {
        return;
    }

    pid_t pid = e->getPid();
    hash = android::hash_type(pid);
    index = pidTable.find(-1, hash, pid);
    if (index != -1) {
        PidEntry &entry = pidTable.editEntryAt(index);
        if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
            pidTable.removeAt(index);
        }
    }
    pidTable.subtract(e->getPid(), e);
}

// Atomically set an entry to drop
@@ -157,28 +104,13 @@ void LogStatistics::drop(LogBufferElement *e) {
    unsigned short size = e->getMsgLen();
    mSizes[log_id] -= size;

    uid_t uid = e->getUid();
    android::hash_t hash = android::hash_type(uid);
    typeof uidTable[0] &table = uidTable[log_id];
    ssize_t index = table.find(-1, hash, uid);
    if (index != -1) {
        UidEntry &entry = table.editEntryAt(index);
        entry.subtract(size);
        entry.add_dropped(1);
    }
    uidTable[log_id].drop(e->getUid(), e);

    if (!enable) {
        return;
    }

    pid_t pid = e->getPid();
    hash = android::hash_type(pid);
    index = pidTable.find(-1, hash, pid);
    if (index != -1) {
        PidEntry &entry = pidTable.editEntryAt(index);
        entry.subtract(size);
        entry.add_dropped(1);
    }
    pidTable.drop(e->getPid(), e);
}

// caller must own and free character string
@@ -379,6 +311,7 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
    }

    if (enable) {
        // Pid table
        bool headerPrinted = false;
        std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
        ssize_t index = -1;
@@ -460,48 +393,14 @@ uid_t pidToUid(pid_t pid) {
}

uid_t LogStatistics::pidToUid(pid_t pid) {
    uid_t uid;
    android::hash_t hash = android::hash_type(pid);
    ssize_t index = pidTable.find(-1, hash, pid);
    if (index == -1) {
        uid = android::pidToUid(pid);
        PidEntry initEntry(pid, uid, android::pidToName(pid));
        pidTable.add(hash, initEntry);
    } else {
        PidEntry &entry = pidTable.editEntryAt(index);
        if (!entry.getName()) {
            char *name = android::pidToName(pid);
            if (name) {
                entry.setName(name);
            }
        }
        uid = entry.getUid();
    }
    return uid;
    return pidTable.entryAt(pidTable.add(pid)).getUid();
}

// caller must free character string
char *LogStatistics::pidToName(pid_t pid) {
    char *name;

    android::hash_t hash = android::hash_type(pid);
    ssize_t index = pidTable.find(-1, hash, pid);
    if (index == -1) {
        name = android::pidToName(pid);
        PidEntry initEntry(pid, android::pidToUid(pid), name ? strdup(name) : NULL);
        pidTable.add(hash, initEntry);
    } else {
        PidEntry &entry = pidTable.editEntryAt(index);
        const char *n = entry.getName();
        if (n) {
            name = strdup(n);
        } else {
            name = android::pidToName(pid);
            if (name) {
                entry.setName(strdup(name));
            }
        }
    const char *name = pidTable.entryAt(pidTable.add(pid)).getName();
    if (!name) {
        return NULL;
    }

    return name;
    return strdup(name);
}
+111 −24
Original line number Diff line number Diff line
@@ -73,52 +73,139 @@ public:
    ssize_t next(ssize_t index) {
        return android::BasicHashtable<TKey, TEntry>::next(index);
    }

    size_t add(TKey key, LogBufferElement *e) {
        android::hash_t hash = android::hash_type(key);
        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
        if (index == -1) {
            return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(e));
        }
        android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(e);
        return index;
    }

    inline size_t add(TKey key) {
        android::hash_t hash = android::hash_type(key);
        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
        if (index == -1) {
            return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(key));
        }
        android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(key);
        return index;
    }

    void subtract(TKey key, LogBufferElement *e) {
        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
        if ((index != -1)
         && android::BasicHashtable<TKey, TEntry>::editEntryAt(index).subtract(e)) {
            android::BasicHashtable<TKey, TEntry>::removeAt(index);
        }
    }

    inline void drop(TKey key, LogBufferElement *e) {
        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
        if (index != -1) {
            android::BasicHashtable<TKey, TEntry>::editEntryAt(index).drop(e);
        }
    }

};

struct UidEntry {
    const uid_t uid;
struct EntryBase {
    size_t size;
    size_t dropped;

    UidEntry(uid_t uid):uid(uid),size(0),dropped(0) { }
    EntryBase():size(0) { }
    EntryBase(LogBufferElement *e):size(e->getMsgLen()) { }

    inline const uid_t&getKey() const { return uid; }
    size_t getSizes() const { return size; }

    inline void add(LogBufferElement *e) { size += e->getMsgLen(); }
    inline bool subtract(LogBufferElement *e) { size -= e->getMsgLen(); return !size; }
};

struct EntryBaseDropped : public EntryBase {
    size_t dropped;

    EntryBaseDropped():dropped(0) { }
    EntryBaseDropped(LogBufferElement *e):EntryBase(e),dropped(e->getDropped()){ }

    size_t getDropped() const { return dropped; }

    inline void add(size_t s) { size += s; }
    inline void add_dropped(size_t d) { dropped += d; }
    inline bool subtract(size_t s) { size -= s; return !dropped && !size; }
    inline bool subtract_dropped(size_t d) { dropped -= d; return !dropped && !size; }
    inline void add(LogBufferElement *e) {
        dropped += e->getDropped();
        EntryBase::add(e);
    }
    inline bool subtract(LogBufferElement *e) {
        dropped -= e->getDropped();
        return EntryBase::subtract(e) && !dropped;
    }
    inline void drop(LogBufferElement *e) {
        dropped += 1;
        EntryBase::subtract(e);
    }
};

struct UidEntry : public EntryBaseDropped {
    const uid_t uid;

    UidEntry(LogBufferElement *e):EntryBaseDropped(e),uid(e->getUid()) { }

    inline const uid_t&getKey() const { return uid; }
};

struct PidEntry {
namespace android {
// caller must own and free character string
char *pidToName(pid_t pid);
uid_t pidToUid(pid_t pid);
}

struct PidEntry : public EntryBaseDropped {
    const pid_t pid;
    uid_t uid;
    char *name;
    size_t size;
    size_t dropped;

    PidEntry(pid_t p, uid_t u, char *n):pid(p),uid(u),name(n),size(0),dropped(0) { }
    PidEntry(pid_t p):
        EntryBaseDropped(),
        pid(p),
        uid(android::pidToUid(p)),
        name(android::pidToName(pid)) { }
    PidEntry(LogBufferElement *e):
        EntryBaseDropped(e),
        pid(e->getPid()),
        uid(e->getUid()),
        name(android::pidToName(e->getPid())) { }
    PidEntry(const PidEntry &c):
        EntryBaseDropped(c),
        pid(c.pid),
        uid(c.uid),
        name(c.name ? strdup(c.name) : NULL),
        size(c.size),
        dropped(c.dropped) { }
        name(c.name ? strdup(c.name) : NULL) { }
    ~PidEntry() { free(name); }

    const pid_t&getKey() const { return pid; }
    const uid_t&getUid() const { return uid; }
    uid_t&setUid(uid_t u) { return uid = u; }
    const char*getName() const { return name; }
    char *setName(char *n) { free(name); return name = n; }
    size_t getSizes() const { return size; }
    size_t getDropped() const { return dropped; }
    inline void add(size_t s) { size += s; }
    inline void add_dropped(size_t d) { dropped += d; }
    inline bool subtract(size_t s) { size -= s; return !dropped && !size; }
    inline bool subtract_dropped(size_t d) { dropped -= d; return !dropped && !size; }

    inline void add(pid_t p) {
        if (!name) {
            char *n = android::pidToName(p);
            if (n) {
                name = n;
            }
        }
    }

    inline void add(LogBufferElement *e) {
        uid_t u = e->getUid();
        if (getUid() != u) {
            uid = u;
            free(name);
            name = android::pidToName(e->getPid());
        } else {
            add(e->getPid());
        }
        EntryBaseDropped::add(e);
    }

};

// Log Statistics