[beast: 6/20] SFI: add TaskStatus from Rapicorn
- From: Tim Janik <timj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [beast: 6/20] SFI: add TaskStatus from Rapicorn
- Date: Sun, 24 Sep 2017 00:20:08 +0000 (UTC)
commit cbb2a315283924a53cd25e737832eb175b3685b3
Author: Tim Janik <timj gnu org>
Date: Sun Sep 17 02:18:48 2017 +0200
SFI: add TaskStatus from Rapicorn
Import is based on Rapicorn commit id:
bf228016cba3f6d252ee2cc38e1ed32607f37bf0
Signed-off-by: Tim Janik <timj gnu org>
sfi/bcore.hh | 1 -
sfi/platform.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
sfi/platform.hh | 23 ++++++++++++-
3 files changed, 124 insertions(+), 2 deletions(-)
---
diff --git a/sfi/bcore.hh b/sfi/bcore.hh
index 6bfa8ff..3265a82 100644
--- a/sfi/bcore.hh
+++ b/sfi/bcore.hh
@@ -33,7 +33,6 @@ using Rapicorn::DataListContainer;
using Rapicorn::void_t;
using Rapicorn::Blob;
using Rapicorn::Res;
-using Rapicorn::TaskStatus;
using Rapicorn::ThreadInfo;
using Rapicorn::cpu_info;
using Rapicorn::AsyncBlockingQueue;
diff --git a/sfi/platform.cc b/sfi/platform.cc
index 901086c..8a73179 100644
--- a/sfi/platform.cc
+++ b/sfi/platform.cc
@@ -218,6 +218,108 @@ program_cwd ()
return cached_program_cwd;
}
+// == TaskStatus ==
+TaskStatus::TaskStatus (int pid, int tid) :
+ process_id (pid), task_id (tid >= 0 ? tid : pid), state (UNKNOWN), processor (-1), priority (0),
+ utime (0), stime (0), cutime (0), cstime (0),
+ ac_stamp (0), ac_utime (0), ac_stime (0), ac_cutime (0), ac_cstime (0)
+{}
+
+static bool
+update_task_status (TaskStatus &self)
+{
+ static long clk_tck = 0;
+ if (!clk_tck)
+ {
+ clk_tck = sysconf (_SC_CLK_TCK);
+ if (clk_tck <= 0)
+ clk_tck = 100;
+ }
+ int pid = -1, ppid = -1, pgrp = -1, session = -1, tty_nr = -1, tpgid = -1;
+ int exit_signal = 0, processor = 0;
+ long cutime = 0, cstime = 0, priority = 0, nice = 0, dummyld = 0;
+ long itrealvalue = 0, rss = 0;
+ unsigned long flags = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
+ unsigned long utime = 0, stime = 0, vsize = 0, rlim = 0, startcode = 0;
+ unsigned long endcode = 0, startstack = 0, kstkesp = 0, kstkeip = 0;
+ unsigned long signal = 0, blocked = 0, sigignore = 0, sigcatch = 0;
+ unsigned long wchan = 0, nswap = 0, cnswap = 0, rt_priority = 0, policy = 0;
+ unsigned long long starttime = 0;
+ char state = 0, command[8192 + 1] = { 0 };
+ String filename = string_format ("/proc/%u/task/%u/stat", self.process_id, self.task_id);
+ FILE *file = fopen (filename.c_str(), "r");
+ if (!file)
+ return false;
+ int n = fscanf (file,
+ "%d %8192s %c "
+ "%d %d %d %d %d "
+ "%lu %lu %lu %lu %lu %lu %lu "
+ "%ld %ld %ld %ld %ld %ld "
+ "%llu %lu %ld "
+ "%lu %lu %lu %lu %lu "
+ "%lu %lu %lu %lu %lu "
+ "%lu %lu %lu %d %d "
+ "%lu %lu",
+ &pid, command, &state, // n=3
+ &ppid, &pgrp, &session, &tty_nr, &tpgid, // n=8
+ &flags, &minflt, &cminflt, &majflt, &cmajflt, &utime, &stime, // n=15
+ &cutime, &cstime, &priority, &nice, &dummyld, &itrealvalue, // n=21
+ &starttime, &vsize, &rss, // n=24
+ &rlim, &startcode, &endcode, &startstack, &kstkesp, // n=29
+ &kstkeip, &signal, &blocked, &sigignore, &sigcatch, // n=34
+ &wchan, &nswap, &cnswap, &exit_signal, &processor, // n=39
+ &rt_priority, &policy // n=41
+ );
+ fclose (file);
+ const double jiffies_to_usecs = 1000000.0 / clk_tck;
+ if (n >= 3)
+ self.state = TaskStatus::State (state);
+ if (n >= 15)
+ {
+ self.ac_utime = utime * jiffies_to_usecs;
+ self.ac_stime = stime * jiffies_to_usecs;
+ }
+ if (n >= 17)
+ {
+ self.ac_cutime = cutime * jiffies_to_usecs;
+ self.ac_cstime = cstime * jiffies_to_usecs;
+ }
+ if (n >= 18)
+ self.priority = priority;
+ if (n >= 39)
+ self.processor = 1 + processor;
+ return true;
+}
+
+#define ACCOUNTING_MSECS 50
+
+bool
+TaskStatus::update ()
+{
+ const TaskStatus old (*this);
+ const uint64 now = timestamp_realtime(); // usecs
+ if (ac_stamp + ACCOUNTING_MSECS * 1000 >= now)
+ return false; // limit accounting to a few times per second
+ if (!update_task_status (*this))
+ return false;
+ const double delta = 1000000.0 / MAX (1, now - ac_stamp);
+ utime = uint64 (MAX (ac_utime - old.ac_utime, 0) * delta);
+ stime = uint64 (MAX (ac_stime - old.ac_stime, 0) * delta);
+ cutime = uint64 (MAX (ac_cutime - old.ac_cutime, 0) * delta);
+ cstime = uint64 (MAX (ac_cstime - old.ac_cstime, 0) * delta);
+ ac_stamp = now;
+ return true;
+}
+
+String
+TaskStatus::string ()
+{
+ return
+ string_format ("pid=%d task=%d state=%c processor=%d priority=%d perc=%.2f%% utime=%.3fms stime=%.3fms
cutime=%.3f cstime=%.3f",
+ process_id, task_id, state, processor, priority, (utime + stime) * 0.0001,
+ utime * 0.001, stime * 0.001, cutime * 0.001, cstime * 0.001);
+}
+
// == Early Startup ctors ==
namespace {
struct EarlyStartup {
diff --git a/sfi/platform.hh b/sfi/platform.hh
index 245e945..a43f399 100644
--- a/sfi/platform.hh
+++ b/sfi/platform.hh
@@ -14,7 +14,7 @@ uint64 timestamp_resolution (); // nseconds
String timestamp_format (uint64 stamp, uint maxlength = 8);
uint64 monotonic_counter ();
-// == process info ==
+// == process names ==
String program_alias (); ///< Retrieve the program name as used for logging
or debug messages.
void program_alias_init (String customname); ///< Set program_alias to a non-localized alias
other than program_argv0 if desired.
String application_name (); ///< Retrieve the localized program name intended
for user display.
@@ -23,6 +23,27 @@ String program_cwd (); ///< The current working
std::string executable_name (); ///< Retrieve the name part of executable_path().
std::string executable_path (); ///< Retrieve the path to the currently running
executable.
+// == thread info ==
+/// Acquire information about a task (process or thread) at runtime.
+struct TaskStatus {
+ enum State { UNKNOWN = '?', RUNNING = 'R', SLEEPING = 'S', DISKWAIT = 'D', STOPPED = 'T', PAGING = 'W',
ZOMBIE = 'Z', DEBUG = 'X', };
+ int process_id; ///< Process ID.
+ int task_id; ///< Process ID or thread ID.
+ String name; ///< Thread name (set by user).
+ State state; ///< Thread state.
+ int processor; ///< Rrunning processor number.
+ int priority; ///< Priority or nice value.
+ uint64 utime; ///< Userspace time.
+ uint64 stime; ///< System time.
+ uint64 cutime; ///< Userspace time of dead children.
+ uint64 cstime; ///< System time of dead children.
+ uint64 ac_stamp; ///< Accounting stamp.
+ uint64 ac_utime, ac_stime, ac_cutime, ac_cstime;
+ explicit TaskStatus (int pid, int tid = -1); ///< Construct from process ID and optionally thread ID.
+ bool update (); ///< Update status information, might return false if called too frequently.
+ String string (); ///< Retrieve string representation of the status information.
+};
+
// == Debugging Aids ==
extern inline void breakpoint () BSE_ALWAYS_INLINE; ///< Cause a debugging breakpoint,
for development only.
extern int (*backtrace_pointers) (void **buffer, int size); ///< Capture stack frames for a
backtrace (on __GLIBC__).
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]