blob: 978f25bff7fabe8049d2473520ed51ee23f09133 [file] [log] [blame]
Hisham Muhammadd6231ba2006-03-04 18:16:49 +00001/*
2htop - Process.c
Hisham Muhammad9b351402011-05-26 16:31:18 +00003(C) 2004-2011 Hisham H. Muhammad
Hisham Muhammadd6231ba2006-03-04 18:16:49 +00004Released under the GNU GPL, see the COPYING file
5in the source distribution for its full text.
6*/
7
Hisham Muhammad84281bd2011-12-26 21:35:57 +00008#include "Process.h"
9
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000010#include "ProcessList.h"
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000011#include "CRT.h"
12#include "String.h"
Hisham Muhammad8fa33dc2008-03-09 02:33:23 +000013#include "RichString.h"
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000014
15#include <stdio.h>
16#include <sys/time.h>
17#include <sys/resource.h>
18#include <sys/param.h>
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000019#include <sys/stat.h>
20#include <unistd.h>
Hisham Muhammad84281bd2011-12-26 21:35:57 +000021#include <stdlib.h>
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000022#include <signal.h>
23#include <string.h>
24#include <stdbool.h>
25#include <pwd.h>
Hisham Muhammada7c2aed2007-11-08 23:23:01 +000026#include <sched.h>
Hisham Muhammaddc262f42010-03-29 18:36:11 +000027#include <time.h>
Hisham Muhammad84281bd2011-12-26 21:35:57 +000028#include <assert.h>
Hisham Muhammad47e881f2012-10-04 23:59:45 +000029#include <sys/syscall.h>
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000030
Hisham Muhammadbc87a8f2011-11-21 02:52:41 +000031#ifdef HAVE_LIBHWLOC
Hisham Muhammadec17b702011-09-24 00:30:47 +000032#include <hwloc/linux.h>
Hisham Muhammad3b950e42009-03-11 13:15:43 +000033#endif
Hisham Muhammad4df76d12008-03-05 09:46:47 +000034
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000035// This works only with glibc 2.1+. On earlier versions
36// the behavior is similar to have a hardcoded page size.
Hisham Muhammad9710a432007-05-17 18:29:30 +000037#ifndef PAGE_SIZE
Hisham Muhammad3b950e42009-03-11 13:15:43 +000038#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
Hisham Muhammad9710a432007-05-17 18:29:30 +000039#endif
Hisham Muhammad3b950e42009-03-11 13:15:43 +000040#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000041
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000042/*{
Hisham Muhammad84281bd2011-12-26 21:35:57 +000043#include "Object.h"
44#include "Affinity.h"
Hisham Muhammad47e881f2012-10-04 23:59:45 +000045#include "IOPriority.h"
Hisham Muhammad84281bd2011-12-26 21:35:57 +000046#include <sys/types.h>
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000047
Hisham Muhammad6cfa9e02013-05-24 22:46:01 +000048#define PROCESS_FLAG_IO 1
49#define PROCESS_FLAG_IOPRIO 2
50#define PROCESS_FLAG_OPENVZ 4
51#define PROCESS_FLAG_VSERVER 8
52#define PROCESS_FLAG_CGROUP 16
53
Hisham Muhammadd8e14802010-11-22 12:40:20 +000054#ifndef Process_isKernelThread
55#define Process_isKernelThread(_process) (_process->pgrp == 0)
56#endif
57
58#ifndef Process_isUserlandThread
59#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
60#endif
61
Hisham Muhammadef318932010-02-22 20:57:25 +000062#ifndef Process_isThread
Hisham Muhammadd8e14802010-11-22 12:40:20 +000063#define Process_isThread(_process) (Process_isUserlandThread(_process) || Process_isKernelThread(_process))
Hisham Muhammadef318932010-02-22 20:57:25 +000064#endif
65
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000066typedef enum ProcessField_ {
67 PID = 1, COMM, STATE, PPID, PGRP, SESSION, TTY_NR, TPGID, FLAGS, MINFLT, CMINFLT, MAJFLT, CMAJFLT, UTIME,
68 STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE,
69 STARTSTACK, KSTKESP, KSTKEIP, SIGNAL, BLOCKED, SSIGIGNORE, SIGCATCH, WCHAN, NSWAP, CNSWAP, EXIT_SIGNAL,
70 PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM,
Hisham Muhammadcf7fdcd2007-12-17 05:57:28 +000071 USER, TIME, NLWP, TGID,
Hisham Muhammad4c51ad02007-08-10 05:07:14 +000072 #ifdef HAVE_OPENVZ
Hisham Muhammadb93e5c02009-03-11 13:05:19 +000073 CTID, VPID,
Hisham Muhammad4c51ad02007-08-10 05:07:14 +000074 #endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +000075 #ifdef HAVE_VSERVER
76 VXID,
77 #endif
Hisham Muhammad12f4f092008-03-09 08:02:22 +000078 #ifdef HAVE_TASKSTATS
Hisham Muhammad2338ad52008-03-14 18:50:49 +000079 RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
Hisham Muhammad12f4f092008-03-09 08:02:22 +000080 #endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +000081 #ifdef HAVE_CGROUP
82 CGROUP,
83 #endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +000084 #ifdef HAVE_OOM
85 OOM,
86 #endif
Hisham Muhammad47e881f2012-10-04 23:59:45 +000087 IO_PRIORITY,
Hisham Muhammad4c51ad02007-08-10 05:07:14 +000088 LAST_PROCESSFIELD
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000089} ProcessField;
90
91struct ProcessList_;
92
93typedef struct Process_ {
94 Object super;
95
96 struct ProcessList_ *pl;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000097
Hisham Muhammad02a30bf2010-02-25 01:43:18 +000098 pid_t pid;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000099 char* comm;
100 int indent;
101 char state;
102 bool tag;
Hisham Muhammad9eb91212010-06-17 19:02:03 +0000103 bool showChildren;
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000104 bool show;
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000105 pid_t ppid;
Hisham Muhammada227b202007-04-05 19:53:23 +0000106 unsigned int pgrp;
107 unsigned int session;
108 unsigned int tty_nr;
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000109 pid_t tgid;
Hisham Muhammada7c2aed2007-11-08 23:23:01 +0000110 int tpgid;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000111 unsigned long int flags;
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300112
113 uid_t st_uid;
114 float percent_cpu;
115 float percent_mem;
116 char* user;
117
Hisham Muhammad219bb9c2011-03-28 19:06:06 +0000118 unsigned long long int utime;
119 unsigned long long int stime;
120 unsigned long long int cutime;
121 unsigned long long int cstime;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000122 long int priority;
123 long int nice;
Hisham Muhammadd357c672007-05-21 19:10:53 +0000124 long int nlwp;
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000125 IOPriority ioPriority;
Hisham Muhammaddc262f42010-03-29 18:36:11 +0000126 char starttime_show[8];
127 time_t starttime_ctime;
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300128
129 #ifdef HAVE_TASKSTATS
130 unsigned long long io_rchar;
131 unsigned long long io_wchar;
132 unsigned long long io_syscr;
133 unsigned long long io_syscw;
134 unsigned long long io_read_bytes;
135 unsigned long long io_write_bytes;
136 unsigned long long io_cancelled_write_bytes;
137 double io_rate_read_bps;
138 unsigned long long io_rate_read_time;
139 double io_rate_write_bps;
140 unsigned long long io_rate_write_time;
141 #endif
142
143 int processor;
Hisham Muhammad127f8472014-04-09 22:32:54 -0300144 long m_size;
145 long m_resident;
146 long m_share;
147 long m_trs;
148 long m_drs;
149 long m_lrs;
150 long m_dt;
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300151
152 #ifdef HAVE_OPENVZ
153 unsigned int ctid;
154 unsigned int vpid;
155 #endif
156 #ifdef HAVE_VSERVER
157 unsigned int vxid;
158 #endif
159
160 #ifdef HAVE_CGROUP
161 char* cgroup;
162 #endif
163 #ifdef HAVE_OOM
164 unsigned int oom;
165 #endif
166
167 int exit_signal;
Hisham Muhammadf2a190b2014-02-27 17:11:23 -0300168 int basenameOffset;
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300169 bool updated;
170
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000171 #ifdef DEBUG
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300172 unsigned long int minflt;
173 unsigned long int cminflt;
174 unsigned long int majflt;
175 unsigned long int cmajflt;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000176 long int itrealvalue;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000177 unsigned long int vsize;
178 long int rss;
179 unsigned long int rlim;
180 unsigned long int startcode;
181 unsigned long int endcode;
182 unsigned long int startstack;
183 unsigned long int kstkesp;
184 unsigned long int kstkeip;
185 unsigned long int signal;
186 unsigned long int blocked;
187 unsigned long int sigignore;
188 unsigned long int sigcatch;
189 unsigned long int wchan;
190 unsigned long int nswap;
191 unsigned long int cnswap;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000192 #endif
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300193
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000194} Process;
195
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000196}*/
197
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000198const char *Process_fieldNames[] = {
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000199 "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION",
200 "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT",
201 "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE",
202 "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK",
203 "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN",
204 "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE",
205 "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM",
206 "USER", "TIME", "NLWP", "TGID",
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000207#ifdef HAVE_OPENVZ
Hisham Muhammadb93e5c02009-03-11 13:05:19 +0000208 "CTID", "VPID",
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000209#endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000210#ifdef HAVE_VSERVER
211 "VXID",
212#endif
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000213#ifdef HAVE_TASKSTATS
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000214 "RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
215 "IO_READ_RATE", "IO_WRITE_RATE", "IO_RATE",
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000216#endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000217#ifdef HAVE_CGROUP
218 "CGROUP",
219#endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000220#ifdef HAVE_OOM
221 "OOM",
222#endif
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000223 "IO_PRIORITY",
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000224"*** report bug! ***"
Hisham Muhammad2f1f82e2006-06-06 20:41:01 +0000225};
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000226
Hisham Muhammad6cfa9e02013-05-24 22:46:01 +0000227const int Process_fieldFlags[] = {
228 0, 0, 0, 0, 0, 0, 0,
229 0, 0, 0, 0, 0, 0, 0,
230 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0,
235 0, 0, 0, 0,
236#ifdef HAVE_OPENVZ
237 PROCESS_FLAG_OPENVZ, PROCESS_FLAG_OPENVZ,
238#endif
239#ifdef HAVE_VSERVER
240 PROCESS_FLAG_VSERVER,
241#endif
242#ifdef HAVE_TASKSTATS
243 PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
244 PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
245#endif
246#ifdef HAVE_CGROUP
247 PROCESS_FLAG_CGROUP,
248#endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000249#ifdef HAVE_OOM
250 0,
251#endif
Hisham Muhammad6cfa9e02013-05-24 22:46:01 +0000252 PROCESS_FLAG_IOPRIO
253};
254
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000255const char *Process_fieldTitles[] = {
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000256 "", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ",
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000257 " TTY ", " TPGID ", "- ", "- ", "- ", "- ", "- ",
Hisham Muhammad3e265ce2011-09-08 04:21:31 +0000258 " UTIME+ ", " STIME+ ", " CUTIME+ ", " CSTIME+ ", "PRI ", " NI ", "- ",
Hisham Muhammaddc262f42010-03-29 18:36:11 +0000259 "START ", "- ", "- ", "- ", "- ", "- ", "- ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000260 "- ", "- ", "- ", "- ", "- ", "- ", "- ",
261 "- ", "- ", "- ", "CPU ", " VIRT ", " RES ", " SHR ",
262 " CODE ", " DATA ", " LIB ", " DIRTY ", " UID ", "CPU% ", "MEM% ",
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000263 "USER ", " TIME+ ", "NLWP ", " TGID ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000264#ifdef HAVE_OPENVZ
Hisham Muhammadb93e5c02009-03-11 13:05:19 +0000265 " CTID ", " VPID ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000266#endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000267#ifdef HAVE_VSERVER
268 " VXID ",
269#endif
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000270#ifdef HAVE_TASKSTATS
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300271 " RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RBYTES ", " IO_WBYTES ", " IO_CANCEL ",
Hisham Muhammadf8685172014-04-24 12:52:26 -0300272 " IORR ", " IOWR ", " IORW ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000273#endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000274#ifdef HAVE_CGROUP
275 " CGROUP ",
276#endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000277#ifdef HAVE_OOM
278 " OOM ",
279#endif
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000280 "IO ",
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000281"*** report bug! ***"
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000282};
283
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000284static int Process_getuid = -1;
285
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000286static char* Process_pidFormat = "%7u ";
287static char* Process_tpgidFormat = "%7u ";
288
289void Process_getMaxPid() {
290 FILE* file = fopen(PROCDIR "/sys/kernel/pid_max", "r");
291 if (!file) return;
292 int maxPid = 4194303;
Hisham Muhammadd1b1cbc2011-10-25 00:05:46 +0000293 fscanf(file, "%32d", &maxPid);
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000294 fclose(file);
295 if (maxPid > 99999) {
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000296 Process_fieldTitles[PID] = " PID ";
297 Process_fieldTitles[PPID] = " PPID ";
298 Process_fieldTitles[TPGID] = " TPGID ";
299 Process_fieldTitles[TGID] = " TGID ";
300 Process_fieldTitles[PGRP] = " PGRP ";
301 Process_fieldTitles[SESSION] = " SESN ";
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000302 #ifdef HAVE_OOM
303 Process_fieldTitles[OOM] = " OOM ";
304 #endif
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000305 Process_pidFormat = "%7u ";
306 Process_tpgidFormat = "%7d ";
307 } else {
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000308 Process_fieldTitles[PID] = " PID ";
309 Process_fieldTitles[PPID] = " PPID ";
310 Process_fieldTitles[TPGID] = "TPGID ";
311 Process_fieldTitles[TGID] = " TGID ";
312 Process_fieldTitles[PGRP] = " PGRP ";
313 Process_fieldTitles[SESSION] = " SESN ";
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000314 #ifdef HAVE_OOM
315 Process_fieldTitles[OOM] = " OOM ";
316 #endif
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000317 Process_pidFormat = "%5u ";
318 Process_tpgidFormat = "%5d ";
319 }
320}
321
Hisham Muhammad5d6ad852014-04-09 22:49:36 -0300322#define ONE_K 1024L
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000323#define ONE_M (ONE_K * ONE_K)
324#define ONE_G (ONE_M * ONE_K)
325
Hisham Muhammad5d6ad852014-04-09 22:49:36 -0300326#define ONE_DECIMAL_K 1000L
zed_0xff7afda7f2014-01-21 11:35:53 +0300327#define ONE_DECIMAL_M (ONE_DECIMAL_K * ONE_DECIMAL_K)
Hisham Muhammad127f8472014-04-09 22:32:54 -0300328#define ONE_DECIMAL_G (ONE_DECIMAL_M * ONE_DECIMAL_K)
zed_0xff7afda7f2014-01-21 11:35:53 +0300329
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300330static void Process_humanNumber(RichString* str, unsigned long number, bool coloring) {
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000331 char buffer[11];
332 int len;
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300333
334 int largeNumberColor = CRT_colors[LARGE_NUMBER];
335 int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES];
336 int processColor = CRT_colors[PROCESS];
337 if (!coloring) {
338 largeNumberColor = CRT_colors[PROCESS];
339 processMegabytesColor = CRT_colors[PROCESS];
340 }
341
zed_0xff7afda7f2014-01-21 11:35:53 +0300342 if(number >= (10 * ONE_DECIMAL_M)) {
Hisham Muhammad127f8472014-04-09 22:32:54 -0300343 #ifdef __LP64__
344 if(number >= (100 * ONE_DECIMAL_G)) {
345 len = snprintf(buffer, 10, "%4ldT ", number / ONE_G);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300346 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300347 return;
Hisham Muhammad5d6ad852014-04-09 22:49:36 -0300348 } else if (number >= (1000 * ONE_DECIMAL_M)) {
Hisham Muhammad1ac517b2014-04-10 13:22:33 -0300349 len = snprintf(buffer, 10, "%4.1lfT ", (double)number / ONE_G);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300350 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300351 return;
352 }
Hisham Muhammad127f8472014-04-09 22:32:54 -0300353 #endif
zed_0xff7afda7f2014-01-21 11:35:53 +0300354 if(number >= (100 * ONE_DECIMAL_M)) {
Hisham Muhammad2960a812010-11-20 20:35:07 +0000355 len = snprintf(buffer, 10, "%4ldG ", number / ONE_M);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300356 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300357 return;
Hisham Muhammad2960a812010-11-20 20:35:07 +0000358 }
Hisham Muhammad1ac517b2014-04-10 13:22:33 -0300359 len = snprintf(buffer, 10, "%4.1lfG ", (double)number / ONE_M);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300360 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300361 return;
Hisham Muhammad2960a812010-11-20 20:35:07 +0000362 } else if (number >= 100000) {
Hisham Muhammade3198ca2006-11-29 18:35:25 +0000363 len = snprintf(buffer, 10, "%4ldM ", number / ONE_K);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300364 RichString_appendn(str, processMegabytesColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300365 return;
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300366 } else if (number >= 1000) {
Hisham Muhammade3198ca2006-11-29 18:35:25 +0000367 len = snprintf(buffer, 10, "%2ld", number/1000);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300368 RichString_appendn(str, processMegabytesColor, buffer, len);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000369 number %= 1000;
Hisham Muhammad0a4ddab2014-04-21 19:00:12 -0300370 len = snprintf(buffer, 10, "%03lu ", number);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300371 RichString_appendn(str, processColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300372 return;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000373 }
Hisham Muhammad0a4ddab2014-04-21 19:00:12 -0300374 len = snprintf(buffer, 10, "%5lu ", number);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300375 RichString_appendn(str, processColor, buffer, len);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000376}
377
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300378static void Process_colorNumber(RichString* str, unsigned long long number, bool coloring) {
Hisham Muhammad9b351402011-05-26 16:31:18 +0000379 char buffer[14];
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300380
381 int largeNumberColor = CRT_colors[LARGE_NUMBER];
382 int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES];
383 int processColor = CRT_colors[PROCESS];
384 int processShadowColor = CRT_colors[PROCESS_SHADOW];
385 if (!coloring) {
386 largeNumberColor = CRT_colors[PROCESS];
387 processMegabytesColor = CRT_colors[PROCESS];
388 processShadowColor = CRT_colors[PROCESS];
389 }
390
Hisham Muhammad9b351402011-05-26 16:31:18 +0000391 if (number > 10000000000) {
392 snprintf(buffer, 13, "%11lld ", number / 1000);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300393 RichString_appendn(str, largeNumberColor, buffer, 5);
394 RichString_appendn(str, processMegabytesColor, buffer+5, 3);
395 RichString_appendn(str, processColor, buffer+8, 4);
Hisham Muhammad9b351402011-05-26 16:31:18 +0000396 } else {
Hisham Muhammad0a4ddab2014-04-21 19:00:12 -0300397 snprintf(buffer, 13, "%11llu ", number);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300398 RichString_appendn(str, largeNumberColor, buffer, 2);
399 RichString_appendn(str, processMegabytesColor, buffer+2, 3);
400 RichString_appendn(str, processColor, buffer+5, 3);
401 RichString_appendn(str, processShadowColor, buffer+8, 4);
Hisham Muhammad9b351402011-05-26 16:31:18 +0000402 }
403}
404
Hisham Muhammad2f1f82e2006-06-06 20:41:01 +0000405static double jiffy = 0.0;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000406
Hisham Muhammad219bb9c2011-03-28 19:06:06 +0000407static void Process_printTime(RichString* str, unsigned long long t) {
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000408 if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
409 double jiffytime = 1.0 / jiffy;
410
411 double realTime = t * jiffytime;
Hisham Muhammad078b8312012-06-25 03:06:36 +0000412 unsigned long long iRealTime = (unsigned long long) realTime;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000413
Hisham Muhammad9c44f582011-12-14 23:29:07 +0000414 unsigned long long hours = iRealTime / 3600;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000415 int minutes = (iRealTime / 60) % 60;
416 int seconds = iRealTime % 60;
417 int hundredths = (realTime - iRealTime) * 100;
418 char buffer[11];
Hisham Muhammad9c44f582011-12-14 23:29:07 +0000419 if (hours >= 100) {
420 snprintf(buffer, 10, "%7lluh ", hours);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000421 RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000422 } else {
Hisham Muhammad9c44f582011-12-14 23:29:07 +0000423 if (hours) {
424 snprintf(buffer, 10, "%2lluh", hours);
425 RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
426 snprintf(buffer, 10, "%02d:%02d ", minutes, seconds);
427 } else {
428 snprintf(buffer, 10, "%2d:%02d.%02d ", minutes, seconds, hundredths);
429 }
430 RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000431 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000432}
433
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000434static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) {
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000435 int start = RichString_size(str);
Hisham Muhammad8fa33dc2008-03-09 02:33:23 +0000436 RichString_append(str, attr, this->comm);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000437 if (this->pl->highlightBaseName) {
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000438 int finish = RichString_size(str) - 1;
Hisham Muhammadcb297af2014-04-09 17:43:54 -0300439 if (this->basenameOffset != -1)
440 finish = (start + this->basenameOffset) - 1;
Hisham Muhammadf2a190b2014-02-27 17:11:23 -0300441 int colon = RichString_findChar(str, ':', start);
442 if (colon != -1 && colon < finish) {
443 finish = colon;
444 } else {
Hisham Muhammadcb297af2014-04-09 17:43:54 -0300445 for (int i = finish - start; i >= 0; i--) {
Hisham Muhammadf2a190b2014-02-27 17:11:23 -0300446 if (this->comm[i] == '/') {
447 start += i+1;
448 break;
449 }
450 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000451 }
Hisham Muhammad8fa33dc2008-03-09 02:33:23 +0000452 RichString_setAttrn(str, baseattr, start, finish);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000453 }
454}
455
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300456static inline void Process_outputRate(RichString* str, int attr, char* buffer, int n, double rate, int coloring) {
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000457 rate = rate / 1024;
458 if (rate < 0.01)
459 snprintf(buffer, n, " 0 ");
460 else if (rate <= 10)
461 snprintf(buffer, n, "%5.2f ", rate);
462 else if (rate <= 100)
463 snprintf(buffer, n, "%5.1f ", rate);
464 else {
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300465 Process_humanNumber(str, rate, coloring);
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000466 return;
467 }
468 RichString_append(str, attr, buffer);
469}
470
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000471static void Process_writeField(Process* this, RichString* str, ProcessField field) {
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000472 char buffer[128]; buffer[127] = '\0';
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000473 int attr = CRT_colors[DEFAULT_COLOR];
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000474 int baseattr = CRT_colors[PROCESS_BASENAME];
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000475 int n = sizeof(buffer) - 1;
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300476 bool coloring = this->pl->highlightMegabytes;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000477
478 switch (field) {
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000479 case PID: snprintf(buffer, n, Process_pidFormat, this->pid); break;
480 case PPID: snprintf(buffer, n, Process_pidFormat, this->ppid); break;
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000481 case PGRP: snprintf(buffer, n, Process_pidFormat, this->pgrp); break;
482 case SESSION: snprintf(buffer, n, Process_pidFormat, this->session); break;
Hisham Muhammada227b202007-04-05 19:53:23 +0000483 case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break;
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000484 case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
485 case TPGID: snprintf(buffer, n, Process_tpgidFormat, this->tpgid); break;
Hisham Muhammada9c0ea32011-03-22 20:37:08 +0000486 case PROCESSOR: snprintf(buffer, n, "%3d ", ProcessList_cpuId(this->pl, this->processor)); break;
Hisham Muhammadd357c672007-05-21 19:10:53 +0000487 case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000488 case COMM: {
Hisham Muhammadef318932010-02-22 20:57:25 +0000489 if (this->pl->highlightThreads && Process_isThread(this)) {
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000490 attr = CRT_colors[PROCESS_THREAD];
491 baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
492 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000493 if (!this->pl->treeView || this->indent == 0) {
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000494 Process_writeCommand(this, attr, baseattr, str);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000495 return;
496 } else {
497 char* buf = buffer;
498 int maxIndent = 0;
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000499 const char **treeStr = this->pl->treeStr;
500 bool lastItem = (this->indent < 0);
501 int indent = (this->indent < 0 ? -this->indent : this->indent);
502 if (treeStr == NULL)
503 treeStr = ProcessList_treeStrAscii;
504
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000505 for (int i = 0; i < 32; i++)
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000506 if (indent & (1 << i))
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000507 maxIndent = i+1;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000508 for (int i = 0; i < maxIndent - 1; i++) {
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000509 int written;
510 if (indent & (1 << i))
511 written = snprintf(buf, n, "%s ", treeStr[TREE_STR_VERT]);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000512 else
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000513 written = snprintf(buf, n, " ");
514 buf += written;
515 n -= written;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000516 }
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000517 const char* draw = treeStr[lastItem ? (this->pl->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
518 snprintf(buf, n, "%s%s ", draw, this->showChildren ? treeStr[TREE_STR_SHUT] : treeStr[TREE_STR_OPEN] );
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000519 RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000520 Process_writeCommand(this, attr, baseattr, str);
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000521 return;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000522 }
523 }
524 case STATE: {
525 snprintf(buffer, n, "%c ", this->state);
526 attr = this->state == 'R'
527 ? CRT_colors[PROCESS_R_STATE]
528 : attr;
529 break;
530 }
531 case PRIORITY: {
532 if(this->priority == -100)
533 snprintf(buffer, n, " RT ");
534 else
535 snprintf(buffer, n, "%3ld ", this->priority);
536 break;
537 }
538 case NICE: {
539 snprintf(buffer, n, "%3ld ", this->nice);
540 attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]
541 : this->nice > 0 ? CRT_colors[PROCESS_LOW_PRIORITY]
542 : attr;
543 break;
544 }
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300545 case M_DRS: Process_humanNumber(str, this->m_drs * PAGE_SIZE_KB, coloring); return;
546 case M_DT: Process_humanNumber(str, this->m_dt * PAGE_SIZE_KB, coloring); return;
547 case M_LRS: Process_humanNumber(str, this->m_lrs * PAGE_SIZE_KB, coloring); return;
548 case M_TRS: Process_humanNumber(str, this->m_trs * PAGE_SIZE_KB, coloring); return;
549 case M_SIZE: Process_humanNumber(str, this->m_size * PAGE_SIZE_KB, coloring); return;
550 case M_RESIDENT: Process_humanNumber(str, this->m_resident * PAGE_SIZE_KB, coloring); return;
551 case M_SHARE: Process_humanNumber(str, this->m_share * PAGE_SIZE_KB, coloring); return;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000552 case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
553 case USER: {
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000554 if (Process_getuid != (int) this->st_uid)
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000555 attr = CRT_colors[PROCESS_SHADOW];
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000556 if (this->user) {
Hisham Muhammad9b351402011-05-26 16:31:18 +0000557 snprintf(buffer, n, "%-9s ", this->user);
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000558 } else {
Hisham Muhammad9b351402011-05-26 16:31:18 +0000559 snprintf(buffer, n, "%-9d ", this->st_uid);
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000560 }
Hisham Muhammad9b351402011-05-26 16:31:18 +0000561 if (buffer[9] != '\0') {
562 buffer[9] = ' ';
563 buffer[10] = '\0';
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000564 }
565 break;
566 }
567 case UTIME: Process_printTime(str, this->utime); return;
568 case STIME: Process_printTime(str, this->stime); return;
569 case CUTIME: Process_printTime(str, this->cutime); return;
570 case CSTIME: Process_printTime(str, this->cstime); return;
571 case TIME: Process_printTime(str, this->utime + this->stime); return;
572 case PERCENT_CPU: {
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000573 if (this->percent_cpu > 999.9) {
574 snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu);
575 } else if (this->percent_cpu > 99.9) {
576 snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000577 } else {
578 snprintf(buffer, n, "%4.1f ", this->percent_cpu);
579 }
580 break;
581 }
582 case PERCENT_MEM: {
583 if (this->percent_mem > 99.9) {
584 snprintf(buffer, n, "100. ");
585 } else {
586 snprintf(buffer, n, "%4.1f ", this->percent_mem);
587 }
588 break;
589 }
Hisham Muhammaddc262f42010-03-29 18:36:11 +0000590 case STARTTIME: snprintf(buffer, n, "%s", this->starttime_show); break;
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000591 #ifdef HAVE_OPENVZ
Hisham Muhammadb93e5c02009-03-11 13:05:19 +0000592 case CTID: snprintf(buffer, n, "%5u ", this->ctid); break;
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000593 case VPID: snprintf(buffer, n, "%5u ", this->vpid); break;
594 #endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000595 #ifdef HAVE_VSERVER
596 case VXID: snprintf(buffer, n, "%5u ", this->vxid); break;
597 #endif
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000598 #ifdef HAVE_TASKSTATS
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300599 case RCHAR: Process_colorNumber(str, this->io_rchar, coloring); return;
600 case WCHAR: Process_colorNumber(str, this->io_wchar, coloring); return;
601 case SYSCR: Process_colorNumber(str, this->io_syscr, coloring); return;
602 case SYSCW: Process_colorNumber(str, this->io_syscw, coloring); return;
603 case RBYTES: Process_colorNumber(str, this->io_read_bytes, coloring); return;
604 case WBYTES: Process_colorNumber(str, this->io_write_bytes, coloring); return;
605 case CNCLWB: Process_colorNumber(str, this->io_cancelled_write_bytes, coloring); return;
606 case IO_READ_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_read_bps, coloring); return;
607 case IO_WRITE_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_write_bps, coloring); return;
608 case IO_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps, coloring); return;
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000609 #endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000610 #ifdef HAVE_CGROUP
611 case CGROUP: snprintf(buffer, n, "%-10s ", this->cgroup); break;
612 #endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000613 #ifdef HAVE_OOM
614 case OOM: snprintf(buffer, n, Process_pidFormat, this->oom); break;
615 #endif
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000616 case IO_PRIORITY: {
617 int klass = IOPriority_class(this->ioPriority);
618 if (klass == IOPRIO_CLASS_NONE) {
619 // see note [1] above
620 snprintf(buffer, n, "B%1d ", (int) (this->nice + 20) / 5);
621 } else if (klass == IOPRIO_CLASS_BE) {
622 snprintf(buffer, n, "B%1d ", IOPriority_data(this->ioPriority));
623 } else if (klass == IOPRIO_CLASS_RT) {
624 attr = CRT_colors[PROCESS_HIGH_PRIORITY];
625 snprintf(buffer, n, "R%1d ", IOPriority_data(this->ioPriority));
626 } else if (this->ioPriority == IOPriority_Idle) {
627 attr = CRT_colors[PROCESS_LOW_PRIORITY];
628 snprintf(buffer, n, "id ");
629 } else {
630 snprintf(buffer, n, "?? ");
631 }
632 break;
633 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000634 default:
635 snprintf(buffer, n, "- ");
636 }
637 RichString_append(str, attr, buffer);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000638}
639
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000640static void Process_display(Object* cast, RichString* out) {
641 Process* this = (Process*) cast;
642 ProcessField* fields = this->pl->fields;
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000643 RichString_prune(out);
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000644 for (int i = 0; fields[i]; i++)
645 Process_writeField(this, out, fields[i]);
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000646 if (this->pl->shadowOtherUsers && (int)this->st_uid != Process_getuid)
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000647 RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]);
648 if (this->tag == true)
649 RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
Hisham Muhammada9c0ea32011-03-22 20:37:08 +0000650 assert(out->chlen > 0);
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000651}
652
653void Process_delete(Object* cast) {
654 Process* this = (Process*) cast;
655 assert (this != NULL);
656 if (this->comm) free(this->comm);
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000657#ifdef HAVE_CGROUP
658 if (this->cgroup) free(this->cgroup);
659#endif
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000660 free(this);
661}
662
Hisham Muhammad00b324b2012-12-05 15:12:20 +0000663ObjectClass Process_class = {
664 .extends = Class(Object),
665 .display = Process_display,
666 .delete = Process_delete,
667 .compare = Process_compare
668};
669
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000670Process* Process_new(struct ProcessList_ *pl) {
Hisham Muhammad76a715e2014-01-16 18:51:16 -0200671 Process* this = calloc(1, sizeof(Process));
Hisham Muhammad00b324b2012-12-05 15:12:20 +0000672 Object_setClass(this, Class(Process));
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000673 this->pid = 0;
674 this->pl = pl;
675 this->tag = false;
Hisham Muhammad9eb91212010-06-17 19:02:03 +0000676 this->showChildren = true;
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000677 this->show = true;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000678 this->updated = false;
679 this->utime = 0;
680 this->stime = 0;
681 this->comm = NULL;
Hisham Muhammadcb297af2014-04-09 17:43:54 -0300682 this->basenameOffset = -1;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000683 this->indent = 0;
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000684#ifdef HAVE_CGROUP
685 this->cgroup = NULL;
686#endif
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000687 if (Process_getuid == -1) Process_getuid = getuid();
688 return this;
689}
690
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000691void Process_toggleTag(Process* this) {
692 this->tag = this->tag == true ? false : true;
693}
694
695bool Process_setPriority(Process* this, int priority) {
696 int old_prio = getpriority(PRIO_PROCESS, this->pid);
697 int err = setpriority(PRIO_PROCESS, this->pid, priority);
698 if (err == 0 && old_prio != getpriority(PRIO_PROCESS, this->pid)) {
699 this->nice = priority;
700 }
701 return (err == 0);
702}
703
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000704bool Process_changePriorityBy(Process* this, size_t delta) {
705 return Process_setPriority(this, this->nice + delta);
706}
707
708IOPriority Process_updateIOPriority(Process* this) {
709 IOPriority ioprio = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, this->pid);
710 this->ioPriority = ioprio;
711 return ioprio;
712}
713
714bool Process_setIOPriority(Process* this, IOPriority ioprio) {
715 syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, this->pid, ioprio);
716 return (Process_updateIOPriority(this) == ioprio);
717}
718
719/*
720[1] Note that before kernel 2.6.26 a process that has not asked for
721an io priority formally uses "none" as scheduling class, but the
722io scheduler will treat such processes as if it were in the best
723effort class. The priority within the best effort class will be
724dynamically derived from the cpu nice level of the process:
725io_priority = (cpu_nice + 20) / 5. -- From ionice(1) man page
726*/
727#define Process_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->nice + 20) / 5) : p_->ioPriority)
728
Hisham Muhammadbc87a8f2011-11-21 02:52:41 +0000729#ifdef HAVE_LIBHWLOC
Hisham Muhammad7ca10812011-11-18 06:08:56 +0000730
Hisham Muhammadec17b702011-09-24 00:30:47 +0000731Affinity* Process_getAffinity(Process* this) {
732 hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
733 bool ok = (hwloc_linux_get_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
734 Affinity* affinity = NULL;
735 if (ok) {
736 affinity = Affinity_new();
737 if (hwloc_bitmap_last(cpuset) == -1) {
738 for (int i = 0; i < this->pl->cpuCount; i++) {
739 Affinity_add(affinity, i);
740 }
741 } else {
742 unsigned int id;
743 hwloc_bitmap_foreach_begin(id, cpuset);
744 Affinity_add(affinity, id);
745 hwloc_bitmap_foreach_end();
746 }
747 }
748 hwloc_bitmap_free(cpuset);
749 return affinity;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000750}
751
Hisham Muhammadec17b702011-09-24 00:30:47 +0000752bool Process_setAffinity(Process* this, Affinity* affinity) {
753 hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
754 for (int i = 0; i < affinity->used; i++) {
755 hwloc_bitmap_set(cpuset, affinity->cpus[i]);
756 }
757 bool ok = (hwloc_linux_set_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
758 hwloc_bitmap_free(cpuset);
759 return ok;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000760}
Hisham Muhammad7ca10812011-11-18 06:08:56 +0000761
762#elif HAVE_NATIVE_AFFINITY
763
764Affinity* Process_getAffinity(Process* this) {
765 cpu_set_t cpuset;
766 bool ok = (sched_getaffinity(this->pid, sizeof(cpu_set_t), &cpuset) == 0);
767 if (!ok) return NULL;
768 Affinity* affinity = Affinity_new();
769 for (int i = 0; i < this->pl->cpuCount; i++) {
770 if (CPU_ISSET(i, &cpuset))
771 Affinity_add(affinity, i);
772 }
773 return affinity;
774}
775
776bool Process_setAffinity(Process* this, Affinity* affinity) {
777 cpu_set_t cpuset;
778 CPU_ZERO(&cpuset);
779 for (int i = 0; i < affinity->used; i++) {
780 CPU_SET(affinity->cpus[i], &cpuset);
781 }
782 bool ok = (sched_setaffinity(this->pid, sizeof(unsigned long), &cpuset) == 0);
783 return ok;
784}
785
Hisham Muhammad3b950e42009-03-11 13:15:43 +0000786#endif
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000787
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000788void Process_sendSignal(Process* this, size_t sgn) {
789 kill(this->pid, (int) sgn);
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000790}
791
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000792int Process_pidCompare(const void* v1, const void* v2) {
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000793 Process* p1 = (Process*)v1;
794 Process* p2 = (Process*)v2;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000795 return (p1->pid - p2->pid);
796}
797
798int Process_compare(const void* v1, const void* v2) {
799 Process *p1, *p2;
800 ProcessList *pl = ((Process*)v1)->pl;
801 if (pl->direction == 1) {
802 p1 = (Process*)v1;
803 p2 = (Process*)v2;
804 } else {
805 p2 = (Process*)v1;
806 p1 = (Process*)v2;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000807 }
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000808 long long diff;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000809 switch (pl->sortKey) {
810 case PID:
811 return (p1->pid - p2->pid);
812 case PPID:
813 return (p1->ppid - p2->ppid);
814 case USER:
Hisham Muhammad6330ff32009-06-02 04:51:23 +0000815 return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : "");
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000816 case PRIORITY:
817 return (p1->priority - p2->priority);
Hisham Muhammad843aded2009-03-11 13:52:39 +0000818 case PROCESSOR:
819 return (p1->processor - p2->processor);
820 case SESSION:
821 return (p1->session - p2->session);
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000822 case STATE:
823 return (p1->state - p2->state);
824 case NICE:
825 return (p1->nice - p2->nice);
Hisham Muhammadf56c8012007-04-05 20:13:32 +0000826 case M_DRS:
827 return (p2->m_drs - p1->m_drs);
828 case M_DT:
829 return (p2->m_dt - p1->m_dt);
830 case M_LRS:
831 return (p2->m_lrs - p1->m_lrs);
832 case M_TRS:
833 return (p2->m_trs - p1->m_trs);
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000834 case M_SIZE:
835 return (p2->m_size - p1->m_size);
836 case M_RESIDENT:
837 return (p2->m_resident - p1->m_resident);
838 case M_SHARE:
839 return (p2->m_share - p1->m_share);
840 case PERCENT_CPU:
841 return (p2->percent_cpu > p1->percent_cpu ? 1 : -1);
842 case PERCENT_MEM:
843 return (p2->m_resident - p1->m_resident);
844 case UTIME:
845 return (p2->utime - p1->utime);
846 case STIME:
847 return (p2->stime - p1->stime);
848 case TIME:
849 return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
850 case COMM:
851 return strcmp(p1->comm, p2->comm);
Hisham Muhammadd357c672007-05-21 19:10:53 +0000852 case NLWP:
853 return (p1->nlwp - p2->nlwp);
Hisham Muhammad8d0fff22010-03-29 18:44:14 +0000854 case STARTTIME: {
855 if (p1->starttime_ctime == p2->starttime_ctime)
856 return (p1->pid - p2->pid);
857 else
858 return (p1->starttime_ctime - p2->starttime_ctime);
859 }
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000860 #ifdef HAVE_OPENVZ
Hisham Muhammadb93e5c02009-03-11 13:05:19 +0000861 case CTID:
862 return (p1->ctid - p2->ctid);
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000863 case VPID:
864 return (p1->vpid - p2->vpid);
865 #endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000866 #ifdef HAVE_VSERVER
867 case VXID:
868 return (p1->vxid - p2->vxid);
869 #endif
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000870 #ifdef HAVE_TASKSTATS
871 case RCHAR: diff = p2->io_rchar - p1->io_rchar; goto test_diff;
872 case WCHAR: diff = p2->io_wchar - p1->io_wchar; goto test_diff;
873 case SYSCR: diff = p2->io_syscr - p1->io_syscr; goto test_diff;
874 case SYSCW: diff = p2->io_syscw - p1->io_syscw; goto test_diff;
875 case RBYTES: diff = p2->io_read_bytes - p1->io_read_bytes; goto test_diff;
876 case WBYTES: diff = p2->io_write_bytes - p1->io_write_bytes; goto test_diff;
877 case CNCLWB: diff = p2->io_cancelled_write_bytes - p1->io_cancelled_write_bytes; goto test_diff;
878 case IO_READ_RATE: diff = p2->io_rate_read_bps - p1->io_rate_read_bps; goto test_diff;
879 case IO_WRITE_RATE: diff = p2->io_rate_write_bps - p1->io_rate_write_bps; goto test_diff;
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000880 case IO_RATE: diff = (p2->io_rate_read_bps + p2->io_rate_write_bps) - (p1->io_rate_read_bps + p1->io_rate_write_bps); goto test_diff;
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000881 #endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000882 #ifdef HAVE_CGROUP
883 case CGROUP:
884 return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
885 #endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000886 #ifdef HAVE_OOM
887 case OOM:
888 return (p1->oom - p2->oom);
889 #endif
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000890 case IO_PRIORITY:
891 return Process_effectiveIOPriority(p1) - Process_effectiveIOPriority(p2);
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000892 default:
893 return (p1->pid - p2->pid);
894 }
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000895 test_diff:
896 return (diff > 0) ? 1 : (diff < 0 ? -1 : 0);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000897}