64
71
long int totalSwap;
84
bool shadowOtherUsers;
85
bool hideKernelThreads;
87
bool highlightBaseName;
88
bool highlightMegabytes;
70
ProcessList* ProcessList_new(ProcessFilter* filter, UsersTable* usersTable) {
94
void ProcessList_getKernelVersion(ProcessList* this) {
97
char** items = String_split(uts.release, '.');
98
this->kernelMajor = atoi(items[0]);
99
this->kernelMiddle = atoi(items[1]);
100
this->kernelMinor = atoi(items[2]);
101
this->kernelTiny = items[3] ? atoi(items[3]) : 0;
102
for (int i = 0; items[i] != NULL; i++) free(items[i]);
106
/* private property */
107
ProcessField defaultHeaders[LAST_PROCESSFIELD] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, LAST_PROCESSFIELD };
109
ProcessList* ProcessList_new(UsersTable* usersTable) {
71
110
ProcessList* this;
72
111
this = malloc(sizeof(ProcessList));
73
this->processes = TypedVector_new(PROCESS_CLASS, true);
112
this->processes = TypedVector_new(PROCESS_CLASS, true, DEFAULT_SIZE);
74
113
this->processTable = Hashtable_new(20, false);
75
114
TypedVector_setCompareFunction(this->processes, Process_compare);
76
this->filter = filter;
77
this->prototype = Process_new(this->filter);
115
this->prototype = Process_new(this);
79
116
this->usersTable = usersTable;
118
/* tree-view auxiliary buffers */
119
this->processes2 = TypedVector_new(PROCESS_CLASS, true, DEFAULT_SIZE);
120
TypedVector_setCompareFunction(this->processes2, Process_compare);
122
ProcessList_getKernelVersion(this);
124
FILE* status = fopen(PROCSTATFILE, "r");
125
assert(status != NULL);
130
fgets(buffer, 255, status);
131
} while (String_startsWith(buffer, "cpu"));
133
this->processorCount = procs - 1;
134
this->totalTime = calloc(procs, sizeof(long int));
135
this->userTime = calloc(procs, sizeof(long int));
136
this->systemTime = calloc(procs, sizeof(long int));
137
this->niceTime = calloc(procs, sizeof(long int));
138
this->idleTime = calloc(procs, sizeof(long int));
139
this->totalPeriod = calloc(procs, sizeof(long int));
140
this->userPeriod = calloc(procs, sizeof(long int));
141
this->systemPeriod = calloc(procs, sizeof(long int));
142
this->nicePeriod = calloc(procs, sizeof(long int));
143
this->idlePeriod = calloc(procs, sizeof(long int));
144
for (int i = 0; i < procs; i++) {
145
this->totalTime[i] = 1;
146
this->totalPeriod[i] = 1;
149
this->fields = malloc(sizeof(ProcessField) * LAST_PROCESSFIELD);
150
// TODO: turn 'fields' into a TypedVector,
151
// (and ProcessFields into proper objects).
152
for (int i = 0; i < LAST_PROCESSFIELD; i++) {
153
this->fields[i] = defaultHeaders[i];
155
this->sortKey = PERCENT_CPU;
157
this->hideThreads = false;
158
this->shadowOtherUsers = false;
159
this->hideKernelThreads = false;
160
this->treeView = false;
161
this->highlightBaseName = false;
162
this->highlightMegabytes = false;
83
167
void ProcessList_delete(ProcessList* this) {
84
168
Hashtable_delete(this->processTable);
85
169
TypedVector_delete(this->processes);
170
TypedVector_delete(this->processes2);
86
171
Process_delete((Object*)this->prototype);
173
free(this->totalTime);
174
free(this->userTime);
175
free(this->systemTime);
176
free(this->niceTime);
177
free(this->idleTime);
178
free(this->totalPeriod);
179
free(this->userPeriod);
180
free(this->systemPeriod);
181
free(this->nicePeriod);
182
free(this->idlePeriod);
188
void ProcessList_invertSortOrder(ProcessList* this) {
189
if (this->direction == 1)
190
this->direction = -1;
195
void ProcessList_sortKey(ProcessList* this, int delta) {
196
assert(delta == 1 || delta == -1);
198
while (this->fields[i] != this->sortKey)
203
while (this->fields[i] != LAST_PROCESSFIELD)
206
} else if (this->fields[i] == LAST_PROCESSFIELD)
208
this->sortKey = this->fields[i];
213
RichString ProcessList_printHeader(ProcessList* this) {
214
RichString out = RichString_new();
215
ProcessField* fields = this->fields;
216
for (int i = 0; fields[i] != LAST_PROCESSFIELD; i++) {
217
char* field = Process_printField(fields[i]);
218
if (this->sortKey == fields[i])
219
RichString_append(&out, CRT_colors[PANEL_HIGHLIGHT_FOCUS], field);
221
RichString_append(&out, CRT_colors[PANEL_HEADER_FOCUS], field);
90
227
void ProcessList_prune(ProcessList* this) {
91
228
TypedVector_prune(this->processes);
110
247
return (TypedVector_size(this->processes));
251
void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) {
252
TypedVector* children = TypedVector_new(PROCESS_CLASS, false, DEFAULT_SIZE);
254
for (int i = 0; i < TypedVector_size(this->processes); i++) {
255
Process* process = (Process*) (TypedVector_get(this->processes, i));
256
if (process->ppid == pid) {
257
Process* process = (Process*) (TypedVector_take(this->processes, i));
258
TypedVector_add(children, process);
262
int size = TypedVector_size(children);
263
for (int i = 0; i < size; i++) {
264
Process* process = (Process*) (TypedVector_get(children, i));
266
TypedVector_add(this->processes2, process);
268
TypedVector_insert(this->processes2, 0, process);
269
int nextIndent = indent;
271
nextIndent = indent | (1 << level);
272
ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction);
273
process->indent = indent | (1 << level);
275
TypedVector_delete(children);
113
278
void ProcessList_sort(ProcessList* this) {
114
TypedVector_sort(this->processes);
279
if (!this->treeView) {
280
TypedVector_sort(this->processes);
282
int direction = this->direction;
283
int sortKey = this->sortKey;
286
TypedVector_sort(this->processes);
287
this->sortKey = sortKey;
288
this->direction = direction;
289
Process* init = (Process*) (TypedVector_take(this->processes, 0));
290
assert(init->pid == 1);
292
TypedVector_add(this->processes2, init);
293
ProcessList_buildTree(this, init->pid, 0, 0, direction);
294
TypedVector* t = this->processes;
295
this->processes = this->processes2;
296
this->processes2 = t;
196
379
status = fopen(PROCSTATFILE, "r");
197
380
assert(status != NULL);
198
fscanf(status, "cpu %ld %ld %ld %ld", &usertime, &nicetime, &systemtime, &idletime);
199
totaltime = usertime + nicetime + systemtime + idletime;
200
long int totalperiod = totaltime - this->totalTime;
381
for (int i = 0; i <= this->processorCount; i++) {
383
if (this->kernelMajor == 2 && this->kernelMiddle <= 4) {
385
fscanf(status, "cpu %ld %ld %ld %ld\n", &usertime, &nicetime, &systemtime, &idletime);
387
fscanf(status, "cpu%d %ld %ld %ld %ld\n", &cpuid, &usertime, &nicetime, &systemtime, &idletime);
388
assert(cpuid == i - 1);
390
totaltime = usertime + nicetime + systemtime + idletime;
392
long int ioWait, irq, softIrq;
394
fscanf(status, "cpu %ld %ld %ld %ld %ld %ld %ld\n", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq);
396
fscanf(status, "cpu%d %ld %ld %ld %ld %ld %ld %ld\n", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq);
397
assert(cpuid == i - 1);
399
systemtime += ioWait + irq + softIrq;
400
totaltime = usertime + nicetime + systemtime + idletime;
402
assert (usertime >= this->userTime[i]);
403
assert (nicetime >= this->niceTime[i]);
404
assert (systemtime >= this->systemTime[i]);
405
assert (idletime >= this->idleTime[i]);
406
assert (totaltime >= this->totalTime[i]);
407
this->userPeriod[i] = usertime - this->userTime[i];
408
this->nicePeriod[i] = nicetime - this->niceTime[i];
409
this->systemPeriod[i] = systemtime - this->systemTime[i];
410
this->idlePeriod[i] = idletime - this->idleTime[i];
411
this->totalPeriod[i] = totaltime - this->totalTime[i];
412
this->userTime[i] = usertime;
413
this->niceTime[i] = nicetime;
414
this->systemTime[i] = systemtime;
415
this->idleTime[i] = idletime;
416
this->totalTime[i] = totaltime;
418
float period = (float)this->totalPeriod[0] / this->processorCount;
203
421
// mark all process as "dirty"
325
558
p->updated = false;
328
totalperiod = totaltime - this->totalTime;
329
long int userperiod = usertime - this->userTime;
330
long int niceperiod = nicetime - this->niceTime;
331
long int systemperiod = systemtime - this->systemTime;
332
long int idleperiod = idletime - this->idleTime;
334
this->totalTime = totaltime;
335
this->userTime = usertime;
336
this->niceTime = nicetime;
337
this->systemTime = systemtime;
338
this->idleTime = idletime;
340
this->totalPeriod = totalperiod;
341
this->userPeriod = userperiod;
342
this->nicePeriod = niceperiod;
343
this->systemPeriod = systemperiod;
344
this->idlePeriod = idleperiod;
347
563
void ProcessList_dontCrash(int signal) {