blob: de25cbbbad928090c8f5cf67819f73cdcdd29d77 [file] [log] [blame]
Hisham Muhammadd6231ba2006-03-04 18:16:49 +00001/*
2htop - Process.c
Hisham Muhammadeb229d92014-11-24 18:55:03 -02003(C) 2004-2014 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 Muhammadb4f6b112014-11-27 20:10:23 -020014#include "Platform.h"
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000015
16#include <stdio.h>
17#include <sys/time.h>
18#include <sys/resource.h>
19#include <sys/param.h>
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000020#include <sys/stat.h>
21#include <unistd.h>
Hisham Muhammad84281bd2011-12-26 21:35:57 +000022#include <stdlib.h>
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000023#include <signal.h>
24#include <string.h>
25#include <stdbool.h>
26#include <pwd.h>
Hisham Muhammada7c2aed2007-11-08 23:23:01 +000027#include <sched.h>
Hisham Muhammaddc262f42010-03-29 18:36:11 +000028#include <time.h>
Hisham Muhammad84281bd2011-12-26 21:35:57 +000029#include <assert.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 Muhammadeb229d92014-11-24 18:55:03 -020035// On Linux, this works only with glibc 2.1+. On earlier versions
Hisham Muhammadd6231ba2006-03-04 18:16:49 +000036// 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 Muhammadeb229d92014-11-24 18:55:03 -020045
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 Muhammaddc262f42010-03-29 18:36:11 +0000125 char starttime_show[8];
126 time_t starttime_ctime;
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300127
128 #ifdef HAVE_TASKSTATS
129 unsigned long long io_rchar;
130 unsigned long long io_wchar;
131 unsigned long long io_syscr;
132 unsigned long long io_syscw;
133 unsigned long long io_read_bytes;
134 unsigned long long io_write_bytes;
135 unsigned long long io_cancelled_write_bytes;
136 double io_rate_read_bps;
137 unsigned long long io_rate_read_time;
138 double io_rate_write_bps;
139 unsigned long long io_rate_write_time;
140 #endif
141
142 int processor;
Hisham Muhammad127f8472014-04-09 22:32:54 -0300143 long m_size;
144 long m_resident;
145 long m_share;
146 long m_trs;
147 long m_drs;
148 long m_lrs;
149 long m_dt;
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300150
151 #ifdef HAVE_OPENVZ
152 unsigned int ctid;
153 unsigned int vpid;
154 #endif
155 #ifdef HAVE_VSERVER
156 unsigned int vxid;
157 #endif
158
159 #ifdef HAVE_CGROUP
160 char* cgroup;
161 #endif
162 #ifdef HAVE_OOM
163 unsigned int oom;
164 #endif
165
166 int exit_signal;
Hisham Muhammadf2a190b2014-02-27 17:11:23 -0300167 int basenameOffset;
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300168 bool updated;
169
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300170 unsigned long int minflt;
171 unsigned long int cminflt;
172 unsigned long int majflt;
173 unsigned long int cmajflt;
Hisham Muhammade0209da2014-04-24 19:40:47 -0300174 #ifdef DEBUG
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000175 long int itrealvalue;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000176 unsigned long int vsize;
177 long int rss;
178 unsigned long int rlim;
179 unsigned long int startcode;
180 unsigned long int endcode;
181 unsigned long int startstack;
182 unsigned long int kstkesp;
183 unsigned long int kstkeip;
184 unsigned long int signal;
185 unsigned long int blocked;
186 unsigned long int sigignore;
187 unsigned long int sigcatch;
188 unsigned long int wchan;
189 unsigned long int nswap;
190 unsigned long int cnswap;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000191 #endif
Hisham Muhammad6d90e582014-02-27 16:35:22 -0300192
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000193} Process;
194
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000195}*/
196
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000197const char *Process_fieldNames[] = {
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000198 "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION",
199 "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT",
200 "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE",
201 "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK",
202 "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN",
203 "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE",
204 "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM",
205 "USER", "TIME", "NLWP", "TGID",
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000206#ifdef HAVE_OPENVZ
Hisham Muhammadb93e5c02009-03-11 13:05:19 +0000207 "CTID", "VPID",
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000208#endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000209#ifdef HAVE_VSERVER
210 "VXID",
211#endif
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000212#ifdef HAVE_TASKSTATS
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000213 "RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
214 "IO_READ_RATE", "IO_WRITE_RATE", "IO_RATE",
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000215#endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000216#ifdef HAVE_CGROUP
217 "CGROUP",
218#endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000219#ifdef HAVE_OOM
220 "OOM",
221#endif
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000222 "IO_PRIORITY",
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000223"*** report bug! ***"
Hisham Muhammad2f1f82e2006-06-06 20:41:01 +0000224};
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000225
Hisham Muhammad6cfa9e02013-05-24 22:46:01 +0000226const int Process_fieldFlags[] = {
227 0, 0, 0, 0, 0, 0, 0,
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,
235#ifdef HAVE_OPENVZ
236 PROCESS_FLAG_OPENVZ, PROCESS_FLAG_OPENVZ,
237#endif
238#ifdef HAVE_VSERVER
239 PROCESS_FLAG_VSERVER,
240#endif
241#ifdef HAVE_TASKSTATS
242 PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
243 PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
244#endif
245#ifdef HAVE_CGROUP
246 PROCESS_FLAG_CGROUP,
247#endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000248#ifdef HAVE_OOM
249 0,
250#endif
Hisham Muhammad6cfa9e02013-05-24 22:46:01 +0000251 PROCESS_FLAG_IOPRIO
252};
253
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000254const char *Process_fieldTitles[] = {
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000255 "", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ",
Hisham Muhammade0209da2014-04-24 19:40:47 -0300256 " TTY ", " TPGID ", "- ", " MINFLT ", " CMINFLT ", " MAJFLT ", " CMAJFLT ",
Hisham Muhammad3e265ce2011-09-08 04:21:31 +0000257 " UTIME+ ", " STIME+ ", " CUTIME+ ", " CSTIME+ ", "PRI ", " NI ", "- ",
Hisham Muhammaddc262f42010-03-29 18:36:11 +0000258 "START ", "- ", "- ", "- ", "- ", "- ", "- ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000259 "- ", "- ", "- ", "- ", "- ", "- ", "- ",
260 "- ", "- ", "- ", "CPU ", " VIRT ", " RES ", " SHR ",
261 " CODE ", " DATA ", " LIB ", " DIRTY ", " UID ", "CPU% ", "MEM% ",
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000262 "USER ", " TIME+ ", "NLWP ", " TGID ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000263#ifdef HAVE_OPENVZ
Hisham Muhammadc3e66b22014-05-03 17:26:11 -0300264 " CTID ", " VPID ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000265#endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000266#ifdef HAVE_VSERVER
267 " VXID ",
268#endif
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000269#ifdef HAVE_TASKSTATS
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300270 " RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RBYTES ", " IO_WBYTES ", " IO_CANCEL ",
Hisham Muhammadf8685172014-04-24 12:52:26 -0300271 " IORR ", " IOWR ", " IORW ",
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000272#endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000273#ifdef HAVE_CGROUP
274 " CGROUP ",
275#endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000276#ifdef HAVE_OOM
277 " OOM ",
278#endif
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000279 "IO ",
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000280"*** report bug! ***"
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000281};
282
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000283static int Process_getuid = -1;
284
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000285static char* Process_pidFormat = "%7u ";
286static char* Process_tpgidFormat = "%7u ";
287
Hisham Muhammadb4f6b112014-11-27 20:10:23 -0200288void Process_setupColumnWidths() {
289 int maxPid = Platform_getMaxPid();
290 if (maxPid == -1) return;
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000291 if (maxPid > 99999) {
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000292 Process_fieldTitles[PID] = " PID ";
293 Process_fieldTitles[PPID] = " PPID ";
Hisham Muhammadc3e66b22014-05-03 17:26:11 -0300294 #ifdef HAVE_OPENVZ
295 Process_fieldTitles[VPID] = " VPID ";
296 #endif
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000297 Process_fieldTitles[TPGID] = " TPGID ";
298 Process_fieldTitles[TGID] = " TGID ";
299 Process_fieldTitles[PGRP] = " PGRP ";
300 Process_fieldTitles[SESSION] = " SESN ";
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000301 #ifdef HAVE_OOM
302 Process_fieldTitles[OOM] = " OOM ";
303 #endif
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000304 Process_pidFormat = "%7u ";
305 Process_tpgidFormat = "%7d ";
306 } else {
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000307 Process_fieldTitles[PID] = " PID ";
308 Process_fieldTitles[PPID] = " PPID ";
Hisham Muhammadc3e66b22014-05-03 17:26:11 -0300309 #ifdef HAVE_OPENVZ
310 Process_fieldTitles[VPID] = " VPID ";
311 #endif
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000312 Process_fieldTitles[TPGID] = "TPGID ";
313 Process_fieldTitles[TGID] = " TGID ";
314 Process_fieldTitles[PGRP] = " PGRP ";
315 Process_fieldTitles[SESSION] = " SESN ";
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000316 #ifdef HAVE_OOM
317 Process_fieldTitles[OOM] = " OOM ";
318 #endif
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000319 Process_pidFormat = "%5u ";
320 Process_tpgidFormat = "%5d ";
321 }
322}
323
Hisham Muhammad5d6ad852014-04-09 22:49:36 -0300324#define ONE_K 1024L
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000325#define ONE_M (ONE_K * ONE_K)
326#define ONE_G (ONE_M * ONE_K)
327
Hisham Muhammad5d6ad852014-04-09 22:49:36 -0300328#define ONE_DECIMAL_K 1000L
zed_0xff7afda7f2014-01-21 11:35:53 +0300329#define ONE_DECIMAL_M (ONE_DECIMAL_K * ONE_DECIMAL_K)
Hisham Muhammad127f8472014-04-09 22:32:54 -0300330#define ONE_DECIMAL_G (ONE_DECIMAL_M * ONE_DECIMAL_K)
zed_0xff7afda7f2014-01-21 11:35:53 +0300331
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300332static void Process_humanNumber(RichString* str, unsigned long number, bool coloring) {
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000333 char buffer[11];
334 int len;
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300335
336 int largeNumberColor = CRT_colors[LARGE_NUMBER];
337 int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES];
338 int processColor = CRT_colors[PROCESS];
339 if (!coloring) {
340 largeNumberColor = CRT_colors[PROCESS];
341 processMegabytesColor = CRT_colors[PROCESS];
342 }
Hisham Muhammadea191b52014-04-25 19:37:07 -0300343
zed_0xff7afda7f2014-01-21 11:35:53 +0300344 if(number >= (10 * ONE_DECIMAL_M)) {
Hisham Muhammad127f8472014-04-09 22:32:54 -0300345 #ifdef __LP64__
346 if(number >= (100 * ONE_DECIMAL_G)) {
347 len = snprintf(buffer, 10, "%4ldT ", number / ONE_G);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300348 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300349 return;
Hisham Muhammad5d6ad852014-04-09 22:49:36 -0300350 } else if (number >= (1000 * ONE_DECIMAL_M)) {
Hisham Muhammad1ac517b2014-04-10 13:22:33 -0300351 len = snprintf(buffer, 10, "%4.1lfT ", (double)number / ONE_G);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300352 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300353 return;
354 }
Hisham Muhammad127f8472014-04-09 22:32:54 -0300355 #endif
zed_0xff7afda7f2014-01-21 11:35:53 +0300356 if(number >= (100 * ONE_DECIMAL_M)) {
Hisham Muhammad2960a812010-11-20 20:35:07 +0000357 len = snprintf(buffer, 10, "%4ldG ", number / ONE_M);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300358 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300359 return;
Hisham Muhammad2960a812010-11-20 20:35:07 +0000360 }
Hisham Muhammad1ac517b2014-04-10 13:22:33 -0300361 len = snprintf(buffer, 10, "%4.1lfG ", (double)number / ONE_M);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300362 RichString_appendn(str, largeNumberColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300363 return;
Hisham Muhammad2960a812010-11-20 20:35:07 +0000364 } else if (number >= 100000) {
Hisham Muhammade3198ca2006-11-29 18:35:25 +0000365 len = snprintf(buffer, 10, "%4ldM ", number / ONE_K);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300366 RichString_appendn(str, processMegabytesColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300367 return;
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300368 } else if (number >= 1000) {
Hisham Muhammade3198ca2006-11-29 18:35:25 +0000369 len = snprintf(buffer, 10, "%2ld", number/1000);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300370 RichString_appendn(str, processMegabytesColor, buffer, len);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000371 number %= 1000;
Hisham Muhammad0a4ddab2014-04-21 19:00:12 -0300372 len = snprintf(buffer, 10, "%03lu ", number);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300373 RichString_appendn(str, processColor, buffer, len);
Hisham Muhammad96858742014-04-09 23:14:41 -0300374 return;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000375 }
Hisham Muhammad0a4ddab2014-04-21 19:00:12 -0300376 len = snprintf(buffer, 10, "%5lu ", number);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300377 RichString_appendn(str, processColor, buffer, len);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000378}
379
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300380static void Process_colorNumber(RichString* str, unsigned long long number, bool coloring) {
Hisham Muhammad9b351402011-05-26 16:31:18 +0000381 char buffer[14];
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300382
383 int largeNumberColor = CRT_colors[LARGE_NUMBER];
384 int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES];
385 int processColor = CRT_colors[PROCESS];
386 int processShadowColor = CRT_colors[PROCESS_SHADOW];
387 if (!coloring) {
388 largeNumberColor = CRT_colors[PROCESS];
389 processMegabytesColor = CRT_colors[PROCESS];
390 processShadowColor = CRT_colors[PROCESS];
391 }
392
Hisham Muhammad9b351402011-05-26 16:31:18 +0000393 if (number > 10000000000) {
394 snprintf(buffer, 13, "%11lld ", number / 1000);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300395 RichString_appendn(str, largeNumberColor, buffer, 5);
396 RichString_appendn(str, processMegabytesColor, buffer+5, 3);
397 RichString_appendn(str, processColor, buffer+8, 4);
Hisham Muhammad9b351402011-05-26 16:31:18 +0000398 } else {
Hisham Muhammad0a4ddab2014-04-21 19:00:12 -0300399 snprintf(buffer, 13, "%11llu ", number);
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300400 RichString_appendn(str, largeNumberColor, buffer, 2);
401 RichString_appendn(str, processMegabytesColor, buffer+2, 3);
402 RichString_appendn(str, processColor, buffer+5, 3);
403 RichString_appendn(str, processShadowColor, buffer+8, 4);
Hisham Muhammad9b351402011-05-26 16:31:18 +0000404 }
405}
406
Hisham Muhammad2f1f82e2006-06-06 20:41:01 +0000407static double jiffy = 0.0;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000408
Hisham Muhammad219bb9c2011-03-28 19:06:06 +0000409static void Process_printTime(RichString* str, unsigned long long t) {
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000410 if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
411 double jiffytime = 1.0 / jiffy;
412
413 double realTime = t * jiffytime;
Hisham Muhammad078b8312012-06-25 03:06:36 +0000414 unsigned long long iRealTime = (unsigned long long) realTime;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000415
Hisham Muhammad9c44f582011-12-14 23:29:07 +0000416 unsigned long long hours = iRealTime / 3600;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000417 int minutes = (iRealTime / 60) % 60;
418 int seconds = iRealTime % 60;
419 int hundredths = (realTime - iRealTime) * 100;
420 char buffer[11];
Hisham Muhammad9c44f582011-12-14 23:29:07 +0000421 if (hours >= 100) {
422 snprintf(buffer, 10, "%7lluh ", hours);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000423 RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000424 } else {
Hisham Muhammad9c44f582011-12-14 23:29:07 +0000425 if (hours) {
426 snprintf(buffer, 10, "%2lluh", hours);
427 RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
428 snprintf(buffer, 10, "%02d:%02d ", minutes, seconds);
429 } else {
430 snprintf(buffer, 10, "%2d:%02d.%02d ", minutes, seconds, hundredths);
431 }
432 RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000433 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000434}
435
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000436static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) {
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000437 int start = RichString_size(str);
Hisham Muhammad8fa33dc2008-03-09 02:33:23 +0000438 RichString_append(str, attr, this->comm);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000439 if (this->pl->highlightBaseName) {
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000440 int finish = RichString_size(str) - 1;
Hisham Muhammadcb297af2014-04-09 17:43:54 -0300441 if (this->basenameOffset != -1)
442 finish = (start + this->basenameOffset) - 1;
Hisham Muhammadf2a190b2014-02-27 17:11:23 -0300443 int colon = RichString_findChar(str, ':', start);
444 if (colon != -1 && colon < finish) {
445 finish = colon;
446 } else {
Hisham Muhammadcb297af2014-04-09 17:43:54 -0300447 for (int i = finish - start; i >= 0; i--) {
Hisham Muhammadf2a190b2014-02-27 17:11:23 -0300448 if (this->comm[i] == '/') {
449 start += i+1;
450 break;
451 }
452 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000453 }
Hisham Muhammad8fa33dc2008-03-09 02:33:23 +0000454 RichString_setAttrn(str, baseattr, start, finish);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000455 }
456}
457
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300458static inline void Process_outputRate(RichString* str, int attr, char* buffer, int n, double rate, int coloring) {
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000459 rate = rate / 1024;
460 if (rate < 0.01)
461 snprintf(buffer, n, " 0 ");
462 else if (rate <= 10)
463 snprintf(buffer, n, "%5.2f ", rate);
464 else if (rate <= 100)
465 snprintf(buffer, n, "%5.1f ", rate);
466 else {
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300467 Process_humanNumber(str, rate, coloring);
Hisham Muhammad2338ad52008-03-14 18:50:49 +0000468 return;
469 }
470 RichString_append(str, attr, buffer);
471}
472
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000473static void Process_writeField(Process* this, RichString* str, ProcessField field) {
Hisham Muhammad2f30cd12014-04-24 15:08:32 -0300474 char buffer[256]; buffer[255] = '\0';
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000475 int attr = CRT_colors[DEFAULT_COLOR];
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000476 int baseattr = CRT_colors[PROCESS_BASENAME];
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000477 int n = sizeof(buffer) - 1;
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300478 bool coloring = this->pl->highlightMegabytes;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000479
480 switch (field) {
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000481 case PID: snprintf(buffer, n, Process_pidFormat, this->pid); break;
482 case PPID: snprintf(buffer, n, Process_pidFormat, this->ppid); break;
Hisham Muhammad259e1a22012-10-20 01:45:41 +0000483 case PGRP: snprintf(buffer, n, Process_pidFormat, this->pgrp); break;
484 case SESSION: snprintf(buffer, n, Process_pidFormat, this->session); break;
Hisham Muhammada227b202007-04-05 19:53:23 +0000485 case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break;
Hisham Muhammad75080ce2011-09-29 18:40:23 +0000486 case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
487 case TPGID: snprintf(buffer, n, Process_tpgidFormat, this->tpgid); break;
Hisham Muhammade0209da2014-04-24 19:40:47 -0300488 case MINFLT: Process_colorNumber(str, this->minflt, coloring); return;
489 case CMINFLT: Process_colorNumber(str, this->cminflt, coloring); return;
490 case MAJFLT: Process_colorNumber(str, this->majflt, coloring); return;
491 case CMAJFLT: Process_colorNumber(str, this->cmajflt, coloring); return;
Hisham Muhammada9c0ea32011-03-22 20:37:08 +0000492 case PROCESSOR: snprintf(buffer, n, "%3d ", ProcessList_cpuId(this->pl, this->processor)); break;
Hisham Muhammadd357c672007-05-21 19:10:53 +0000493 case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000494 case COMM: {
Hisham Muhammadef318932010-02-22 20:57:25 +0000495 if (this->pl->highlightThreads && Process_isThread(this)) {
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000496 attr = CRT_colors[PROCESS_THREAD];
497 baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
498 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000499 if (!this->pl->treeView || this->indent == 0) {
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000500 Process_writeCommand(this, attr, baseattr, str);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000501 return;
502 } else {
503 char* buf = buffer;
504 int maxIndent = 0;
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000505 const char **treeStr = this->pl->treeStr;
506 bool lastItem = (this->indent < 0);
507 int indent = (this->indent < 0 ? -this->indent : this->indent);
508 if (treeStr == NULL)
509 treeStr = ProcessList_treeStrAscii;
510
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000511 for (int i = 0; i < 32; i++)
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000512 if (indent & (1 << i))
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000513 maxIndent = i+1;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000514 for (int i = 0; i < maxIndent - 1; i++) {
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000515 int written;
516 if (indent & (1 << i))
517 written = snprintf(buf, n, "%s ", treeStr[TREE_STR_VERT]);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000518 else
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000519 written = snprintf(buf, n, " ");
520 buf += written;
521 n -= written;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000522 }
Hisham Muhammadca6b9232011-11-03 22:12:12 +0000523 const char* draw = treeStr[lastItem ? (this->pl->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
524 snprintf(buf, n, "%s%s ", draw, this->showChildren ? treeStr[TREE_STR_SHUT] : treeStr[TREE_STR_OPEN] );
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000525 RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000526 Process_writeCommand(this, attr, baseattr, str);
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000527 return;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000528 }
529 }
530 case STATE: {
531 snprintf(buffer, n, "%c ", this->state);
Valmiky Arquissandas64e0d942014-10-14 02:30:17 +0100532 switch(this->state) {
533 case 'R':
534 attr = CRT_colors[PROCESS_R_STATE];
535 break;
536 case 'D':
537 attr = CRT_colors[PROCESS_D_STATE];
538 break;
Valmiky Arquissandas64e0d942014-10-14 02:30:17 +0100539 }
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000540 break;
541 }
542 case PRIORITY: {
543 if(this->priority == -100)
544 snprintf(buffer, n, " RT ");
545 else
546 snprintf(buffer, n, "%3ld ", this->priority);
547 break;
548 }
549 case NICE: {
550 snprintf(buffer, n, "%3ld ", this->nice);
551 attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]
552 : this->nice > 0 ? CRT_colors[PROCESS_LOW_PRIORITY]
553 : attr;
554 break;
555 }
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300556 case M_DRS: Process_humanNumber(str, this->m_drs * PAGE_SIZE_KB, coloring); return;
557 case M_DT: Process_humanNumber(str, this->m_dt * PAGE_SIZE_KB, coloring); return;
558 case M_LRS: Process_humanNumber(str, this->m_lrs * PAGE_SIZE_KB, coloring); return;
559 case M_TRS: Process_humanNumber(str, this->m_trs * PAGE_SIZE_KB, coloring); return;
560 case M_SIZE: Process_humanNumber(str, this->m_size * PAGE_SIZE_KB, coloring); return;
561 case M_RESIDENT: Process_humanNumber(str, this->m_resident * PAGE_SIZE_KB, coloring); return;
562 case M_SHARE: Process_humanNumber(str, this->m_share * PAGE_SIZE_KB, coloring); return;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000563 case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
564 case USER: {
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000565 if (Process_getuid != (int) this->st_uid)
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000566 attr = CRT_colors[PROCESS_SHADOW];
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000567 if (this->user) {
Hisham Muhammad9b351402011-05-26 16:31:18 +0000568 snprintf(buffer, n, "%-9s ", this->user);
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000569 } else {
Hisham Muhammad9b351402011-05-26 16:31:18 +0000570 snprintf(buffer, n, "%-9d ", this->st_uid);
Hisham Muhammadeb2803c2006-07-12 01:35:59 +0000571 }
Hisham Muhammad9b351402011-05-26 16:31:18 +0000572 if (buffer[9] != '\0') {
573 buffer[9] = ' ';
574 buffer[10] = '\0';
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000575 }
576 break;
577 }
578 case UTIME: Process_printTime(str, this->utime); return;
579 case STIME: Process_printTime(str, this->stime); return;
580 case CUTIME: Process_printTime(str, this->cutime); return;
581 case CSTIME: Process_printTime(str, this->cstime); return;
582 case TIME: Process_printTime(str, this->utime + this->stime); return;
583 case PERCENT_CPU: {
Hisham Muhammad93f091c2008-03-08 23:39:48 +0000584 if (this->percent_cpu > 999.9) {
585 snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu);
586 } else if (this->percent_cpu > 99.9) {
587 snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000588 } else {
589 snprintf(buffer, n, "%4.1f ", this->percent_cpu);
590 }
591 break;
592 }
593 case PERCENT_MEM: {
594 if (this->percent_mem > 99.9) {
595 snprintf(buffer, n, "100. ");
596 } else {
597 snprintf(buffer, n, "%4.1f ", this->percent_mem);
598 }
599 break;
600 }
Hisham Muhammaddc262f42010-03-29 18:36:11 +0000601 case STARTTIME: snprintf(buffer, n, "%s", this->starttime_show); break;
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000602 #ifdef HAVE_OPENVZ
Hisham Muhammadc3e66b22014-05-03 17:26:11 -0300603 case CTID: snprintf(buffer, n, "%7u ", this->ctid); break;
604 case VPID: snprintf(buffer, n, Process_pidFormat, this->vpid); break;
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000605 #endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000606 #ifdef HAVE_VSERVER
607 case VXID: snprintf(buffer, n, "%5u ", this->vxid); break;
608 #endif
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000609 #ifdef HAVE_TASKSTATS
Hisham Muhammada939cdf2014-04-24 15:00:09 -0300610 case RCHAR: Process_colorNumber(str, this->io_rchar, coloring); return;
611 case WCHAR: Process_colorNumber(str, this->io_wchar, coloring); return;
612 case SYSCR: Process_colorNumber(str, this->io_syscr, coloring); return;
613 case SYSCW: Process_colorNumber(str, this->io_syscw, coloring); return;
614 case RBYTES: Process_colorNumber(str, this->io_read_bytes, coloring); return;
615 case WBYTES: Process_colorNumber(str, this->io_write_bytes, coloring); return;
616 case CNCLWB: Process_colorNumber(str, this->io_cancelled_write_bytes, coloring); return;
617 case IO_READ_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_read_bps, coloring); return;
618 case IO_WRITE_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_write_bps, coloring); return;
619 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 +0000620 #endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000621 #ifdef HAVE_CGROUP
622 case CGROUP: snprintf(buffer, n, "%-10s ", this->cgroup); break;
623 #endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000624 #ifdef HAVE_OOM
625 case OOM: snprintf(buffer, n, Process_pidFormat, this->oom); break;
626 #endif
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000627 default:
628 snprintf(buffer, n, "- ");
629 }
630 RichString_append(str, attr, buffer);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000631}
632
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000633static void Process_display(Object* cast, RichString* out) {
634 Process* this = (Process*) cast;
635 ProcessField* fields = this->pl->fields;
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000636 RichString_prune(out);
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000637 for (int i = 0; fields[i]; i++)
638 Process_writeField(this, out, fields[i]);
Hisham Muhammad02a30bf2010-02-25 01:43:18 +0000639 if (this->pl->shadowOtherUsers && (int)this->st_uid != Process_getuid)
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000640 RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]);
641 if (this->tag == true)
642 RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
Hisham Muhammada9c0ea32011-03-22 20:37:08 +0000643 assert(out->chlen > 0);
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000644}
645
646void Process_delete(Object* cast) {
647 Process* this = (Process*) cast;
648 assert (this != NULL);
Hisham Muhammadf54a37b2014-05-03 17:49:05 -0300649 free(this->comm);
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000650#ifdef HAVE_CGROUP
Hisham Muhammadf54a37b2014-05-03 17:49:05 -0300651 free(this->cgroup);
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000652#endif
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000653 free(this);
654}
655
Hisham Muhammad00b324b2012-12-05 15:12:20 +0000656ObjectClass Process_class = {
657 .extends = Class(Object),
658 .display = Process_display,
659 .delete = Process_delete,
660 .compare = Process_compare
661};
662
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000663Process* Process_new(struct ProcessList_ *pl) {
Hisham Muhammad76a715e2014-01-16 18:51:16 -0200664 Process* this = calloc(1, sizeof(Process));
Hisham Muhammad00b324b2012-12-05 15:12:20 +0000665 Object_setClass(this, Class(Process));
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000666 this->pid = 0;
667 this->pl = pl;
668 this->tag = false;
Hisham Muhammad9eb91212010-06-17 19:02:03 +0000669 this->showChildren = true;
Hisham Muhammadd8e14802010-11-22 12:40:20 +0000670 this->show = true;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000671 this->updated = false;
672 this->utime = 0;
673 this->stime = 0;
674 this->comm = NULL;
Hisham Muhammadcb297af2014-04-09 17:43:54 -0300675 this->basenameOffset = -1;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000676 this->indent = 0;
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000677#ifdef HAVE_CGROUP
678 this->cgroup = NULL;
679#endif
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000680 if (Process_getuid == -1) Process_getuid = getuid();
681 return this;
682}
683
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000684void Process_toggleTag(Process* this) {
685 this->tag = this->tag == true ? false : true;
686}
687
688bool Process_setPriority(Process* this, int priority) {
689 int old_prio = getpriority(PRIO_PROCESS, this->pid);
690 int err = setpriority(PRIO_PROCESS, this->pid, priority);
691 if (err == 0 && old_prio != getpriority(PRIO_PROCESS, this->pid)) {
692 this->nice = priority;
693 }
694 return (err == 0);
695}
696
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000697bool Process_changePriorityBy(Process* this, size_t delta) {
698 return Process_setPriority(this, this->nice + delta);
699}
700
Hisham Muhammadbc87a8f2011-11-21 02:52:41 +0000701#ifdef HAVE_LIBHWLOC
Hisham Muhammad7ca10812011-11-18 06:08:56 +0000702
Hisham Muhammadec17b702011-09-24 00:30:47 +0000703Affinity* Process_getAffinity(Process* this) {
704 hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
705 bool ok = (hwloc_linux_get_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
706 Affinity* affinity = NULL;
707 if (ok) {
708 affinity = Affinity_new();
709 if (hwloc_bitmap_last(cpuset) == -1) {
710 for (int i = 0; i < this->pl->cpuCount; i++) {
711 Affinity_add(affinity, i);
712 }
713 } else {
714 unsigned int id;
715 hwloc_bitmap_foreach_begin(id, cpuset);
716 Affinity_add(affinity, id);
717 hwloc_bitmap_foreach_end();
718 }
719 }
720 hwloc_bitmap_free(cpuset);
721 return affinity;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000722}
723
Hisham Muhammadec17b702011-09-24 00:30:47 +0000724bool Process_setAffinity(Process* this, Affinity* affinity) {
725 hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
726 for (int i = 0; i < affinity->used; i++) {
727 hwloc_bitmap_set(cpuset, affinity->cpus[i]);
728 }
729 bool ok = (hwloc_linux_set_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
730 hwloc_bitmap_free(cpuset);
731 return ok;
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000732}
Hisham Muhammad7ca10812011-11-18 06:08:56 +0000733
734#elif HAVE_NATIVE_AFFINITY
735
736Affinity* Process_getAffinity(Process* this) {
737 cpu_set_t cpuset;
738 bool ok = (sched_getaffinity(this->pid, sizeof(cpu_set_t), &cpuset) == 0);
739 if (!ok) return NULL;
740 Affinity* affinity = Affinity_new();
741 for (int i = 0; i < this->pl->cpuCount; i++) {
742 if (CPU_ISSET(i, &cpuset))
743 Affinity_add(affinity, i);
744 }
745 return affinity;
746}
747
748bool Process_setAffinity(Process* this, Affinity* affinity) {
749 cpu_set_t cpuset;
750 CPU_ZERO(&cpuset);
751 for (int i = 0; i < affinity->used; i++) {
752 CPU_SET(affinity->cpus[i], &cpuset);
753 }
754 bool ok = (sched_setaffinity(this->pid, sizeof(unsigned long), &cpuset) == 0);
755 return ok;
756}
757
Hisham Muhammad3b950e42009-03-11 13:15:43 +0000758#endif
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000759
Hisham Muhammad47e881f2012-10-04 23:59:45 +0000760void Process_sendSignal(Process* this, size_t sgn) {
761 kill(this->pid, (int) sgn);
Hisham Muhammadda23c8c2008-03-09 08:58:38 +0000762}
763
Hisham Muhammad78d09f92014-04-25 19:41:23 -0300764long Process_pidCompare(const void* v1, const void* v2) {
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000765 Process* p1 = (Process*)v1;
766 Process* p2 = (Process*)v2;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000767 return (p1->pid - p2->pid);
768}
769
Hisham Muhammad78d09f92014-04-25 19:41:23 -0300770long Process_compare(const void* v1, const void* v2) {
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000771 Process *p1, *p2;
772 ProcessList *pl = ((Process*)v1)->pl;
773 if (pl->direction == 1) {
774 p1 = (Process*)v1;
775 p2 = (Process*)v2;
776 } else {
777 p2 = (Process*)v1;
778 p1 = (Process*)v2;
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000779 }
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000780 long long diff;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000781 switch (pl->sortKey) {
782 case PID:
783 return (p1->pid - p2->pid);
784 case PPID:
785 return (p1->ppid - p2->ppid);
786 case USER:
Hisham Muhammad6330ff32009-06-02 04:51:23 +0000787 return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : "");
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000788 case PRIORITY:
789 return (p1->priority - p2->priority);
Hisham Muhammad843aded2009-03-11 13:52:39 +0000790 case PROCESSOR:
791 return (p1->processor - p2->processor);
792 case SESSION:
793 return (p1->session - p2->session);
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000794 case STATE:
795 return (p1->state - p2->state);
796 case NICE:
797 return (p1->nice - p2->nice);
Hisham Muhammadf56c8012007-04-05 20:13:32 +0000798 case M_DRS:
799 return (p2->m_drs - p1->m_drs);
800 case M_DT:
801 return (p2->m_dt - p1->m_dt);
802 case M_LRS:
803 return (p2->m_lrs - p1->m_lrs);
804 case M_TRS:
805 return (p2->m_trs - p1->m_trs);
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000806 case M_SIZE:
807 return (p2->m_size - p1->m_size);
808 case M_RESIDENT:
809 return (p2->m_resident - p1->m_resident);
810 case M_SHARE:
811 return (p2->m_share - p1->m_share);
812 case PERCENT_CPU:
813 return (p2->percent_cpu > p1->percent_cpu ? 1 : -1);
814 case PERCENT_MEM:
815 return (p2->m_resident - p1->m_resident);
Hisham Muhammadea191b52014-04-25 19:37:07 -0300816 case UTIME: diff = p2->utime - p1->utime; goto test_diff;
817 case CUTIME: diff = p2->cutime - p1->cutime; goto test_diff;
818 case STIME: diff = p2->stime - p1->stime; goto test_diff;
819 case CSTIME: diff = p2->cstime - p2->cstime; goto test_diff;
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000820 case TIME:
821 return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
822 case COMM:
823 return strcmp(p1->comm, p2->comm);
Hisham Muhammadd357c672007-05-21 19:10:53 +0000824 case NLWP:
825 return (p1->nlwp - p2->nlwp);
Hisham Muhammad8d0fff22010-03-29 18:44:14 +0000826 case STARTTIME: {
827 if (p1->starttime_ctime == p2->starttime_ctime)
828 return (p1->pid - p2->pid);
829 else
830 return (p1->starttime_ctime - p2->starttime_ctime);
831 }
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000832 #ifdef HAVE_OPENVZ
Hisham Muhammadb93e5c02009-03-11 13:05:19 +0000833 case CTID:
834 return (p1->ctid - p2->ctid);
Hisham Muhammad4c51ad02007-08-10 05:07:14 +0000835 case VPID:
836 return (p1->vpid - p2->vpid);
837 #endif
Hisham Muhammada5dfaa22008-09-23 04:31:13 +0000838 #ifdef HAVE_VSERVER
839 case VXID:
840 return (p1->vxid - p2->vxid);
841 #endif
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000842 #ifdef HAVE_TASKSTATS
843 case RCHAR: diff = p2->io_rchar - p1->io_rchar; goto test_diff;
844 case WCHAR: diff = p2->io_wchar - p1->io_wchar; goto test_diff;
845 case SYSCR: diff = p2->io_syscr - p1->io_syscr; goto test_diff;
846 case SYSCW: diff = p2->io_syscw - p1->io_syscw; goto test_diff;
847 case RBYTES: diff = p2->io_read_bytes - p1->io_read_bytes; goto test_diff;
848 case WBYTES: diff = p2->io_write_bytes - p1->io_write_bytes; goto test_diff;
849 case CNCLWB: diff = p2->io_cancelled_write_bytes - p1->io_cancelled_write_bytes; goto test_diff;
850 case IO_READ_RATE: diff = p2->io_rate_read_bps - p1->io_rate_read_bps; goto test_diff;
851 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 +0000852 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 +0000853 #endif
Hisham Muhammad84ed4c02010-10-30 19:24:07 +0000854 #ifdef HAVE_CGROUP
855 case CGROUP:
856 return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
857 #endif
Leigh Simpsonda236ca2014-01-29 22:41:55 +0000858 #ifdef HAVE_OOM
859 case OOM:
860 return (p1->oom - p2->oom);
861 #endif
Hisham Muhammad5d48ab82006-07-11 06:13:32 +0000862 default:
863 return (p1->pid - p2->pid);
864 }
Hisham Muhammad12f4f092008-03-09 08:02:22 +0000865 test_diff:
866 return (diff > 0) ? 1 : (diff < 0 ? -1 : 0);
Hisham Muhammadd6231ba2006-03-04 18:16:49 +0000867}