Add ThreadInfo to process_info.fbs
Add `per_thread_info` argument for the aos Top constructor.
When enabled, this will cause Top to include cpu usage per
per thread for all processes it reports on.
The process_info.fbs file has been updated to include this new
optional field.
Change-Id: I394a2ccb09f714b0edf0249fdab4332742bf3d3e
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/util/top.h b/aos/util/top.h
index a71873a..c24d56c 100644
--- a/aos/util/top.h
+++ b/aos/util/top.h
@@ -78,11 +78,13 @@
int64_t exit_code;
};
-// Retrieves the stats for a particular process (note that there also exists a
-// /proc/[pid]/task/[tid]/stat with the same format for per-thread information;
-// we currently do not read that).
-// Returns nullopt if unable to read/parse the file.
-std::optional<ProcStat> ReadProcStat(int pid);
+// Retrieves the statistics for a particular process or thread. If only a pid is
+// provided, it reads the process's stat file at /proc/[pid]/stat. If both pid
+// and tid are provided, it reads the thread's stat file at
+// /proc/[pid]/task/[tid]/stat. Returns nullopt if unable to read or parse the
+// file.
+std::optional<ProcStat> ReadProcStat(pid_t pid,
+ std::optional<pid_t> tid = std::nullopt);
// This class provides a basic utility for retrieving general performance
// information on running processes (named after the top utility). It can either
@@ -95,6 +97,10 @@
// extremely short-lived loads, this may do a poor job of capturing information.
class Top {
public:
+ // Set the ring buffer size to 2 so we can keep track of a current reading and
+ // previous reading.
+ static constexpr int kRingBufferSize = 2;
+
// A snapshot of the resource usage of a process.
struct Reading {
aos::monotonic_clock::time_point reading_time;
@@ -103,6 +109,19 @@
uint64_t memory_usage;
};
+ struct ThreadReading {
+ aos::monotonic_clock::time_point reading_time;
+ std::chrono::nanoseconds total_run_time;
+ };
+
+ struct ThreadReadings {
+ aos::RingBuffer<ThreadReading, kRingBufferSize> readings;
+ double cpu_percent;
+ std::string name; // Name of the thread
+ aos::monotonic_clock::time_point start_time;
+ ThreadState state;
+ };
+
// All the information we have about a process.
struct ProcessReadings {
std::string name;
@@ -112,10 +131,28 @@
// True if this is a kernel thread, false if this is a userspace thread.
bool kthread;
// Last 2 readings
- aos::RingBuffer<Reading, 2> readings;
+ aos::RingBuffer<Reading, kRingBufferSize> readings;
+ std::map<pid_t, ThreadReadings> thread_readings;
};
- Top(aos::EventLoop *event_loop, bool track_threads = false);
+ // An enum for track_threads with enabled and disabled
+ enum class TrackThreadsMode {
+ kDisabled,
+ kEnabled // Track the thread ids for each process.
+ };
+
+ // An enum for track_per_thread_info with enabled and disabled
+ enum class TrackPerThreadInfoMode {
+ kDisabled,
+ kEnabled // Track statistics for each thread.
+ };
+
+ // Constructs a new Top object.
+ // event_loop: The event loop object to be used.
+ // track_threads: Set to true to track the thread IDs for each process.
+ // track_per_thread_info: Set to true to track statistics for each thread.
+ Top(aos::EventLoop *event_loop, TrackThreadsMode track_threads,
+ TrackPerThreadInfoMode track_per_thread_info_mode);
// Set whether to track all the top processes (this will result in us having
// to track every single process on the system, so that we can sort them).
@@ -150,6 +187,7 @@
aos::monotonic_clock::time_point ProcessStartTime(const ProcStat &proc_stat);
uint64_t RealMemoryUsage(const ProcStat &proc_stat);
void UpdateReadings();
+ void UpdateThreadReadings(pid_t pid, ProcessReadings &process);
// Adds thread ids for the given pid to the pids set,
// if we are tracking threads.
void MaybeAddThreadIds(pid_t pid, std::set<pid_t> *pids);
@@ -164,7 +202,10 @@
std::set<pid_t> pids_to_track_;
bool track_all_ = false;
- bool track_threads_;
+ TrackThreadsMode track_threads_;
+
+ // Whether to include per-thread information in the top processes.
+ TrackPerThreadInfoMode track_per_thread_info_;
std::map<pid_t, ProcessReadings> readings_;