PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/GaudiAud/src/ProcStats.cpp

https://bitbucket.org/binet/gaudi
C++ | 354 lines | 157 code | 23 blank | 174 comment | 7 complexity | 5b16e994b6d08c89277351b0635781bf MD5 | raw file
  1. // Class: ProcStats
  2. // Purpose: To keep statistics on memory use
  3. // Warning: Only Linux implementation at the present time...
  4. #ifdef __ICC
  5. // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
  6. // meant
  7. #pragma warning(disable:2259)
  8. #endif
  9. #include "ProcStats.h"
  10. #ifdef __linux
  11. #include <unistd.h>
  12. #include <iostream>
  13. #include <sstream>
  14. #include <fcntl.h>
  15. #include <sys/types.h>
  16. #include <sys/signal.h>
  17. #include <sys/syscall.h>
  18. #include <sys/procfs.h>
  19. #include <cstdio>
  20. using std::cerr;
  21. using std::cout;
  22. using std::endl;
  23. /* Format of the Linux proc/stat (man 5 proc, kernel 2.6.35):
  24. pid %d The process ID.
  25. comm %s The filename of the executable, in parentheses. This is visible
  26. whether or not the executable is swapped out.
  27. state %c One character from the string "RSDZTW" where R is running, S is
  28. sleeping in an interruptible wait, D is waiting in uninterruptible
  29. disk sleep, Z is zombie, T is traced or stopped (on a signal), and
  30. W is paging.
  31. ppid %d The PID of the parent.
  32. pgrp %d The process group ID of the process.
  33. session %d The session ID of the process.
  34. tty_nr %d The controlling terminal of the process. (The minor device number
  35. is contained in the combination of bits 31 to 20 and 7 to 0; the
  36. major device number is in bits 15 t0 8.)
  37. tpgid %d The ID of the foreground process group of the controlling terminal
  38. of the process.
  39. flags %u (%lu before Linux 2.6.22)
  40. The kernel flags word of the process. For bit meanings, see the
  41. PF_* defines in <linux/sched.h>. Details depend on the kernel
  42. version.
  43. minflt %lu The number of minor faults the process has made which have not
  44. required loading a memory page from disk.
  45. cminflt %lu The number of minor faults that the process's waited-for children
  46. have made.
  47. majflt %lu The number of major faults the process has made which have
  48. required loading a memory page from disk.
  49. cmajflt %lu The number of major faults that the process's waited-for children
  50. have made.
  51. utime %lu Amount of time that this process has been scheduled in user mode,
  52. measured in clock ticks (divide by sysconf(_SC_CLK_TCK). This
  53. includes guest time, guest_time (time spent running a virtual CPU,
  54. see below), so that applications that are not aware of the guest
  55. time field do not lose that time from their calculations.
  56. stime %lu Amount of time that this process has been scheduled in kernel
  57. mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK).
  58. cutime %ld Amount of time that this process's waited-for children have been
  59. scheduled in user mode, measured in clock ticks (divide by
  60. sysconf(_SC_CLK_TCK). (See also times(2).) This includes guest
  61. time, cguest_time (time spent running a virtual CPU, see below).
  62. cstime %ld Amount of time that this process's waited-for children have been
  63. scheduled in kernel mode, measured in clock ticks (divide by
  64. sysconf(_SC_CLK_TCK).
  65. priority %ld
  66. (Explanation for Linux 2.6) For processes running a real-time
  67. scheduling policy (policy below; see sched_setscheduler(2)), this
  68. is the negated scheduling priority, minus one; that is, a number
  69. in the range -2 to -100, corresponding to real-time priorities 1
  70. to 99. For processes running under a non-real-time scheduling
  71. policy, this is the raw nice value (setpriority(2)) as represented
  72. in the kernel. The kernel stores nice values as numbers in the
  73. range 0 (high) to 39 (low), corresponding to the user-visible nice
  74. range of -20 to 19.
  75. Before Linux 2.6, this was a scaled value based on the scheduler
  76. weighting given to this process.
  77. nice %ld The nice value (see setpriority(2)), a value in the range 19 (low
  78. priority) to -20 (high priority).
  79. num_threads %ld
  80. Number of threads in this process (since Linux 2.6). Before ker‐
  81. nel 2.6, this field was hard coded to 0 as a placeholder for an
  82. earlier removed field.
  83. itrealvalue %ld
  84. The time in jiffies before the next SIGALRM is sent to the process
  85. due to an interval timer. Since kernel 2.6.17, this field is no
  86. longer maintained, and is hard coded as 0.
  87. starttime %llu (was %lu before Linux 2.6)
  88. The time in jiffies the process started after system boot.
  89. vsize %lu Virtual memory size in bytes.
  90. rss %ld Resident Set Size: number of pages the process has in real memory.
  91. This is just the pages which count towards text, data, or stack
  92. space. This does not include pages which have not been demand-
  93. loaded in, or which are swapped out.
  94. rsslim %lu Current soft limit in bytes on the rss of the process; see the
  95. description of RLIMIT_RSS in getpriority(2).
  96. startcode %lu
  97. The address above which program text can run.
  98. endcode %lu The address below which program text can run.
  99. startstack %lu
  100. The address of the start (i.e., bottom) of the stack.
  101. kstkesp %lu The current value of ESP (stack pointer), as found in the kernel
  102. stack page for the process.
  103. kstkeip %lu The current EIP (instruction pointer).
  104. signal %lu The bitmap of pending signals, displayed as a decimal number.
  105. Obsolete, because it does not provide information on real-time
  106. signals; use /proc/[pid]/status instead.
  107. blocked %lu The bitmap of blocked signals, displayed as a decimal number.
  108. Obsolete, because it does not provide information on real-time
  109. signals; use /proc/[pid]/status instead.
  110. sigignore %lu
  111. The bitmap of ignored signals, displayed as a decimal number.
  112. Obsolete, because it does not provide information on real-time
  113. signals; use /proc/[pid]/status instead.
  114. sigcatch %lu
  115. The bitmap of caught signals, displayed as a decimal number.
  116. Obsolete, because it does not provide information on real-time
  117. signals; use /proc/[pid]/status instead.
  118. wchan %lu This is the "channel" in which the process is waiting. It is the
  119. address of a system call, and can be looked up in a namelist if
  120. you need a textual name. (If you have an up-to-date
  121. /etc/psdatabase, then try ps -l to see the WCHAN field in action.)
  122. nswap %lu Number of pages swapped (not maintained).
  123. cnswap %lu Cumulative nswap for child processes (not maintained).
  124. exit_signal %d (since Linux 2.1.22)
  125. Signal to be sent to parent when we die.
  126. processor %d (since Linux 2.2.8)
  127. CPU number last executed on.
  128. rt_priority %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
  129. Real-time scheduling priority, a number in the range 1 to 99 for
  130. processes scheduled under a real-time policy, or 0, for non-real-
  131. time processes (see sched_setscheduler(2)).
  132. policy %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
  133. Scheduling policy (see sched_setscheduler(2)). Decode using the
  134. SCHED_* constants in linux/sched.h.
  135. delayacct_blkio_ticks %llu (since Linux 2.6.18)
  136. Aggregated block I/O delays, measured in clock ticks (centisec‐
  137. onds).
  138. guest_time %lu (since Linux 2.6.24)
  139. Guest time of the process (time spent running a virtual CPU for a
  140. guest operating system), measured in clock ticks (divide by
  141. sysconf(_SC_CLK_TCK).
  142. cguest_time %ld (since Linux 2.6.24)
  143. Guest time of the process's children, measured in clock ticks
  144. (divide by sysconf(_SC_CLK_TCK).
  145. */
  146. struct linux_proc {
  147. int pid;
  148. char comm[400];
  149. char state;
  150. int ppid;
  151. int pgrp;
  152. int session;
  153. int tty;
  154. int tpgid;
  155. unsigned long flags;
  156. unsigned long minflt;
  157. unsigned long cminflt;
  158. unsigned long majflt;
  159. unsigned long cmajflt;
  160. unsigned long utime;
  161. unsigned long stime;
  162. long cutime;
  163. long cstime;
  164. long priority;
  165. long nice;
  166. long num_threads;
  167. long itrealvalue;
  168. unsigned long long starttime;
  169. unsigned long vsize;
  170. long rss;
  171. unsigned long rlim;
  172. unsigned long startcode;
  173. unsigned long endcode;
  174. unsigned long startstack;
  175. unsigned long kstkesp;
  176. unsigned long kstkeip;
  177. unsigned long signal;
  178. unsigned long blocked;
  179. unsigned long sigignore;
  180. unsigned long sigcatch;
  181. unsigned long wchan;
  182. };
  183. #endif // __linux
  184. ProcStats::cleanup::~cleanup() {
  185. if(ProcStats::inst!=0) {
  186. delete ProcStats::inst;
  187. ProcStats::inst=0;
  188. }
  189. }
  190. ProcStats* ProcStats::instance() {
  191. static cleanup c;
  192. if(inst==0)
  193. inst = new ProcStats;
  194. return inst;
  195. }
  196. ProcStats* ProcStats::inst = 0;
  197. ProcStats::ProcStats():valid(false)
  198. {
  199. #ifdef __linux
  200. pg_size = sysconf(_SC_PAGESIZE); // getpagesize();
  201. std::ostringstream ost;
  202. ost << "/proc/" << getpid() << "/stat";
  203. fname = ost.str();
  204. if((fd=open(fname.c_str(),O_RDONLY))<0)
  205. {
  206. cerr << "Failed to open " << ost.str() << endl;
  207. return;
  208. }
  209. #endif
  210. valid=true;
  211. }
  212. ProcStats::~ProcStats()
  213. {
  214. #ifdef __linux
  215. close(fd);
  216. #endif
  217. }
  218. bool ProcStats::fetch(procInfo& f)
  219. {
  220. if( valid == false ) return false;
  221. #ifdef __linux
  222. double pr_size, pr_rssize;
  223. linux_proc pinfo;
  224. int cnt;
  225. lseek(fd,0,SEEK_SET);
  226. if((cnt=read(fd,buf,sizeof(buf)))<0)
  227. {
  228. cout << "LINUX Read of Proc file failed:" << endl;
  229. return false;
  230. }
  231. if(cnt>0)
  232. {
  233. buf[cnt]='\0';
  234. sscanf(buf,
  235. //1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 20 1 2 3 4 5 6 7 8 9 30 1 2 3 4 5
  236. "%d %s %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",
  237. &pinfo.pid,
  238. pinfo.comm,
  239. &pinfo.state,
  240. &pinfo.ppid,
  241. &pinfo.pgrp,
  242. &pinfo.session,
  243. &pinfo.tty,
  244. &pinfo.tpgid,
  245. &pinfo.flags,
  246. &pinfo.minflt,
  247. &pinfo.cminflt,
  248. &pinfo.majflt,
  249. &pinfo.cmajflt,
  250. &pinfo.utime,
  251. &pinfo.stime,
  252. &pinfo.cutime,
  253. &pinfo.cstime,
  254. &pinfo.priority,
  255. &pinfo.nice,
  256. &pinfo.num_threads,
  257. &pinfo.itrealvalue,
  258. &pinfo.starttime,
  259. &pinfo.vsize,
  260. &pinfo.rss,
  261. &pinfo.rlim,
  262. &pinfo.startcode,
  263. &pinfo.endcode,
  264. &pinfo.startstack,
  265. &pinfo.kstkesp,
  266. &pinfo.kstkeip,
  267. &pinfo.signal,
  268. &pinfo.blocked,
  269. &pinfo.sigignore,
  270. &pinfo.sigcatch,
  271. &pinfo.wchan
  272. );
  273. // resident set size in pages
  274. pr_size = (double)pinfo.vsize;
  275. pr_rssize = (double)pinfo.rss;
  276. f.vsize = pr_size / (1024*1024);
  277. f.rss = pr_rssize * pg_size / (1024*1024);
  278. }
  279. #else
  280. f.vsize = 0;
  281. f.rss = 0;
  282. #endif
  283. bool rc = (curr==f)?false:true;
  284. curr.rss=f.rss;
  285. curr.vsize=f.vsize;
  286. return rc;
  287. }