Expose thread list to users and track kthreads

This sets us up to use Top for configuring kthreads

Change-Id: I439bd21cf340457b85de8c4cbe1044fb8848e078
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/aos/util/top.cc b/aos/util/top.cc
index 79ee2db..05e44f6 100644
--- a/aos/util/top.cc
+++ b/aos/util/top.cc
@@ -10,6 +10,8 @@
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_split.h"
 
+#define PF_KTHREAD 0x00200000
+
 namespace aos::util {
 namespace {
 std::optional<std::string> ReadShortFile(std::string_view file_name) {
@@ -186,13 +188,16 @@
         ProcessStartTime(*proc_stat);
     auto reading_iter = readings_.find(pid);
     if (reading_iter == readings_.end()) {
-      reading_iter = readings_
-                         .insert(std::make_pair(
-                             pid, ProcessReadings{.name = proc_stat->name,
-                                                  .start_time = start_time,
-                                                  .cpu_percent = 0.0,
-                                                  .readings = {}}))
-                         .first;
+      reading_iter =
+          readings_
+              .insert(std::make_pair(
+                  pid, ProcessReadings{.name = proc_stat->name,
+                                       .start_time = start_time,
+                                       .cpu_percent = 0.0,
+                                       .kthread = !!(proc_stat->kernel_flags &
+                                                     PF_KTHREAD),
+                                       .readings = {}}))
+              .first;
     }
     ProcessReadings &process = reading_iter->second;
     // The process associated with the PID has changed; reset the state.
diff --git a/aos/util/top.h b/aos/util/top.h
index 32ff65d..8698bc1 100644
--- a/aos/util/top.h
+++ b/aos/util/top.h
@@ -95,6 +95,26 @@
 // extremely short-lived loads, this may do a poor job of capturing information.
 class Top {
  public:
+  // A snapshot of the resource usage of a process.
+  struct Reading {
+    aos::monotonic_clock::time_point reading_time;
+    std::chrono::nanoseconds total_run_time;
+    // Memory usage in bytes.
+    uint64_t memory_usage;
+  };
+
+  // All the information we have about a process.
+  struct ProcessReadings {
+    std::string name;
+    aos::monotonic_clock::time_point start_time;
+    // CPU usage is based on the past two readings.
+    double cpu_percent;
+    // True if this is a kernel thread, false if this is a userspace thread.
+    bool kthread;
+    // Last 2 readings
+    aos::RingBuffer<Reading, 2> readings;
+  };
+
   Top(aos::EventLoop *event_loop);
 
   // Set whether to track all the top processes (this will result in us having
@@ -116,24 +136,12 @@
   flatbuffers::Offset<TopProcessesFbs> TopProcesses(
       flatbuffers::FlatBufferBuilder *fbb, int n);
 
+  const std::map<pid_t, ProcessReadings> &readings() const { return readings_; }
+
  private:
   // Rate at which to sample /proc/[pid]/stat.
   static constexpr std::chrono::seconds kSamplePeriod{1};
 
-  struct Reading {
-    aos::monotonic_clock::time_point reading_time;
-    std::chrono::nanoseconds total_run_time;
-    uint64_t memory_usage;
-  };
-
-  struct ProcessReadings {
-    std::string name;
-    aos::monotonic_clock::time_point start_time;
-    // CPU usage is based on the past two readings.
-    double cpu_percent;
-    aos::RingBuffer<Reading, 2> readings;
-  };
-
   std::chrono::nanoseconds TotalProcessTime(const ProcStat &proc_stat);
   aos::monotonic_clock::time_point ProcessStartTime(const ProcStat &proc_stat);
   uint64_t RealMemoryUsage(const ProcStat &proc_stat);