linux_process_info.cpp
Go to the documentation of this file.
1 // Provides process information on linux systems
2 // Author: Max Schwarz <max.schwarz@uni-bonn.de>
3 
4 #include "linux_process_info.h"
5 
6 #include <unistd.h>
7 #include <cstdio>
8 #include <cstring>
9 
10 #include <fmt/format.h>
11 
12 namespace rosmon
13 {
14 namespace monitor
15 {
16 namespace process_info
17 {
18 
19 static jiffies_t g_kernel_hz = -1;
20 static std::size_t g_page_size = -1;
21 
23 {
24  if(g_kernel_hz == (jiffies_t)-1)
25  {
26  g_kernel_hz = sysconf(_SC_CLK_TCK);
27  if(g_kernel_hz == (jiffies_t)-1)
28  {
29  fmt::print(stderr, "Warning: Could not obtain value of USER_HZ."
30  "CPU load measurements might be inaccurate.\n"
31  );
32  g_kernel_hz = 100;
33  }
34  }
35 
36  return g_kernel_hz;
37 }
38 
39 std::size_t page_size()
40 {
41  if(g_page_size == (std::size_t)-1)
42  {
43  g_page_size = sysconf(_SC_PAGESIZE);
44  if(g_page_size == (std::size_t)-1)
45  {
46  fmt::print(stderr, "Warning: Could not obtain page size.");
47  g_page_size = 4096;
48  }
49  }
50 
51  return g_page_size;
52 }
53 
54 bool readStatFile(const char* filename, ProcessStat* stat)
55 {
56  FILE* f = fopen(filename, "r");
57  if(!f)
58  return false;
59 
60  char buf[1024];
61  int ret = fread(buf, 1, sizeof(buf)-1, f);
62  fclose(f);
63 
64  if(ret <= 0)
65  return false;
66 
67  buf[ret] = 0;
68 
69  unsigned long pid = 0;
70  if(sscanf(buf, "%lu", &pid) != 1)
71  return false;
72 
73  // from procps: skip "(filename)"
74  char* start = strrchr(buf, ')');
75 
76  if(start - buf > (int)strlen(buf) - 4)
77  return false;
78 
79  // Skip ")"
80  start += 2;
81 
82  unsigned long pgrp = 0;
83  long long unsigned int user_jiffies = 0;
84  long long unsigned int kernel_jiffies = 0;
85  long long unsigned int rss_pages = 0;
86 
87  // Parse interesting fields
88  ret = sscanf(start,
89  "%*c " // state
90  "%*u " // ppid
91  "%lu " // pgrp
92  "%*u " // sid
93  "%*u " // tty_nr
94  "%*u " // tty_pgrp
95  "%*u " // flags
96  "%*u " // number of minor faults
97  "%*u " // number of minor faults with child's
98  "%*u " // number of major faults
99  "%*u " // number of major faults with child's
100  "%llu " // user mode jiffies
101  "%llu " // kernel mode jiffies
102  "%*u " // user mode jiffies with child's
103  "%*u " // kernel mode jiffies with child's
104  "%*u " // priority level
105  "%*u " // nice level
106  "%*u " // num_threads
107  "%*u " // it_real_value (obsolete, always 0)
108  "%*u " // time the process started after system boot
109  "%*u " // virtual memory size
110  "%llu " // resident memory size
111  , // many more fields follow
112  &pgrp,
113  &user_jiffies,
114  &kernel_jiffies,
115  &rss_pages
116  );
117 
118  if(ret != 4)
119  return false;
120 
121  stat->pid = pid;
122  stat->pgrp = pgrp;
123  stat->utime = user_jiffies;
124  stat->stime = kernel_jiffies;
125  stat->mem_rss = rss_pages * page_size();
126 
127  return true;
128 }
129 
130 
131 }
132 }
133 }
jiffies_t stime
Total time spent in kernel space.
ROSCPP_DECL void start()
float f(float t)
Definition: husl.c:142
bool readStatFile(const char *filename, ProcessStat *stat)
std::size_t page_size()
Kernel page size.
unsigned long jiffies_t
A time value counted in kernel jiffies.
jiffies_t utime
Total time spent in userspace.
jiffies_t kernel_hz()
Number of kernel jiffies per second.
std::size_t mem_rss
Resident memory size in bytes.
unsigned long pgrp
Process group ID.


rosmon_core
Author(s): Max Schwarz
autogenerated on Wed Jul 10 2019 03:10:12