Skip to content

Commit 58b42e4

Browse files
tanriolBenBE
authored andcommitted
ProcessList: introduce displayList
Separate `processes` (the vector owning the processes, sorted in whatever order is needed right now internally) and `displayList` (a vector referencing the processes in the same order they're to be displayed).
1 parent 2477a5a commit 58b42e4

File tree

2 files changed

+59
-66
lines changed

2 files changed

+59
-66
lines changed

ProcessList.c

Lines changed: 55 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ in the source distribution for its full text.
2222

2323
ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, UsersTable* usersTable, Hashtable* dynamicMeters, Hashtable* dynamicColumns, Hashtable* pidMatchList, uid_t userId) {
2424
this->processes = Vector_new(klass, true, DEFAULT_SIZE);
25-
this->processes2 = Vector_new(klass, true, DEFAULT_SIZE); // tree-view auxiliary buffer
25+
this->displayList = Vector_new(klass, false, DEFAULT_SIZE);
2626

2727
this->processTable = Hashtable_new(200, false);
2828
this->displayTreeSet = Hashtable_new(200, false);
@@ -78,7 +78,7 @@ void ProcessList_done(ProcessList* this) {
7878
Hashtable_delete(this->displayTreeSet);
7979
Hashtable_delete(this->processTable);
8080

81-
Vector_delete(this->processes2);
81+
Vector_delete(this->displayList);
8282
Vector_delete(this->processes);
8383
}
8484

@@ -224,7 +224,7 @@ static void ProcessList_updateTreeSetLayer(ProcessList* this, unsigned int leftB
224224
if (layerSize == 0)
225225
return;
226226

227-
Vector* layer = Vector_new(Vector_type(this->processes), false, layerSize);
227+
Vector* layer = Vector_new(Vector_type(this->displayList), false, layerSize);
228228

229229
// Find all processes on the same layer (process with the same `deep` value
230230
// and included in a range from `leftBound` to `rightBound`).
@@ -317,7 +317,7 @@ static void ProcessList_updateTreeSet(ProcessList* this) {
317317
unsigned int index = 0;
318318
unsigned int tree_index = 1;
319319

320-
const int vsize = Vector_size(this->processes);
320+
const int vsize = Vector_size(this->displayList);
321321

322322
assert(Hashtable_count(this->draftingTreeSet) == 0);
323323
assert((int)Hashtable_count(this->displayTreeSet) == vsize);
@@ -344,7 +344,6 @@ static void ProcessList_buildTreeBranch(ProcessList* this, pid_t pid, int level,
344344
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
345345
Process* process = (Process*)Vector_get(this->processes, i);
346346
if (Process_isChildOf(process, pid)) {
347-
process = (Process*)Vector_take(this->processes, i);
348347
if (process->show)
349348
lastShown = Vector_size(children);
350349
Vector_add(children, process);
@@ -362,14 +361,14 @@ static void ProcessList_buildTreeBranch(ProcessList* this, pid_t pid, int level,
362361
process->show = false;
363362
}
364363

365-
int s = Vector_size(this->processes2);
364+
int s = Vector_size(this->displayList);
366365
if (direction == 1) {
367-
Vector_add(this->processes2, process);
366+
Vector_add(this->displayList, process);
368367
} else {
369-
Vector_insert(this->processes2, 0, process);
368+
Vector_insert(this->displayList, 0, process);
370369
}
371370

372-
assert(Vector_size(this->processes2) == s + 1); (void)s;
371+
assert(Vector_size(this->displayList) == s + 1); (void)s;
373372

374373
int nextIndent = indent | (1 << level);
375374
ProcessList_buildTreeBranch(this, process->pid, level + 1, (i < lastShown) ? nextIndent : indent, direction, process->show && process->showChildren, node_counter, node_index);
@@ -406,6 +405,8 @@ static int ProcessList_treeProcessCompareByPID(const void* v1, const void* v2) {
406405

407406
// Builds a sorted tree from scratch, without relying on previously gathered information
408407
static void ProcessList_buildTree(ProcessList* this) {
408+
Vector_prune(this->displayList);
409+
409410
int node_counter = 1;
410411
int node_index = 0;
411412
int direction = ScreenSettings_getActiveDirection(this->settings->ss);
@@ -415,64 +416,57 @@ static void ProcessList_buildTree(ProcessList* this) {
415416
int vsize = Vector_size(this->processes);
416417

417418
// Find all processes whose parent is not visible
418-
int size;
419-
while ((size = Vector_size(this->processes))) {
420-
int i;
421-
for (i = 0; i < size; i++) {
422-
Process* process = (Process*)Vector_get(this->processes, i);
423-
424-
pid_t ppid = Process_getParentPid(process);
425-
bool isRoot = false;
426-
427-
// If PID corresponds with PPID (e.g. "kernel_task" (PID:0, PPID:0)
428-
// on Mac OS X 10.11.6) regard this process as root.
429-
if (process->pid == ppid)
430-
isRoot = true;
431-
432-
// On Linux both the init process (pid 1) and the root UMH kernel thread (pid 2)
433-
// use a ppid of 0. As that PID can't exist, we can skip searching for it.
434-
if (!ppid)
435-
isRoot = true;
436-
437-
// Lookup the parent via the processTable hashtable not modified in buildTree
438-
if (ProcessList_findProcess(this, ppid) == NULL)
439-
isRoot = true;
440-
441-
// If parent not found, then construct the tree with this node as root
442-
if (isRoot) {
443-
process = (Process*)Vector_take(this->processes, i);
444-
process->indent = 0;
445-
process->tree_depth = 0;
446-
process->tree_left = node_counter++;
447-
process->tree_index = node_index++;
448-
Vector_add(this->processes2, process);
449-
Hashtable_put(this->displayTreeSet, process->tree_index, process);
450-
ProcessList_buildTreeBranch(this, process->pid, 0, 0, direction, process->showChildren, &node_counter, &node_index);
451-
process->tree_right = node_counter++;
452-
break;
453-
}
454-
}
419+
int size = Vector_size(this->processes);
420+
for (int i = 0; i < size; i++) {
421+
Process* process = (Process*)Vector_get(this->processes, i);
455422

456-
// There should be no loop in the process tree
457-
assert(i < size);
423+
pid_t ppid = Process_getParentPid(process);
424+
bool isRoot = false;
425+
426+
// If PID corresponds with PPID (e.g. "kernel_task" (PID:0, PPID:0)
427+
// on Mac OS X 10.11.6) regard this process as root.
428+
if (process->pid == ppid)
429+
isRoot = true;
430+
431+
// On Linux both the init process (pid 1) and the root UMH kernel thread (pid 2)
432+
// use a ppid of 0. As that PID can't exist, we can skip searching for it.
433+
if (!ppid)
434+
isRoot = true;
435+
436+
// Lookup the parent via the processTable hashtable not modified in buildTree
437+
if (ProcessList_findProcess(this, ppid) == NULL)
438+
isRoot = true;
439+
440+
// If parent not found, then construct the tree with this node as root
441+
if (isRoot) {
442+
process = (Process*)Vector_get(this->processes, i);
443+
process->indent = 0;
444+
process->tree_depth = 0;
445+
process->tree_left = node_counter++;
446+
process->tree_index = node_index++;
447+
Vector_add(this->displayList, process);
448+
Hashtable_put(this->displayTreeSet, process->tree_index, process);
449+
ProcessList_buildTreeBranch(this, process->pid, 0, 0, direction, process->showChildren, &node_counter, &node_index);
450+
process->tree_right = node_counter++;
451+
continue;
452+
}
458453
}
459454

460-
// Swap listings around
461-
Vector* t = this->processes;
462-
this->processes = this->processes2;
463-
this->processes2 = t;
464-
465455
// Check consistency of the built structures
466-
assert(Vector_size(this->processes) == vsize); (void)vsize;
467-
assert(Vector_size(this->processes2) == 0);
456+
assert(Vector_size(this->displayList) == vsize); (void)vsize;
468457
}
469458

470-
void ProcessList_sort(ProcessList* this) {
459+
void ProcessList_updateDisplayList(ProcessList* this) {
471460
if (this->settings->ss->treeView) {
472461
ProcessList_updateTreeSet(this);
473-
Vector_quickSortCustomCompare(this->processes, ProcessList_treeProcessCompare);
462+
Vector_quickSortCustomCompare(this->displayList, ProcessList_treeProcessCompare);
474463
} else {
475-
Vector_insertionSort(this->processes);
464+
if (this->needsSort)
465+
Vector_insertionSort(this->processes);
466+
Vector_prune(this->displayList);
467+
int size = Vector_size(this->processes);
468+
for (int i = 0; i < size; i++)
469+
Vector_add(this->displayList, Vector_get(this->processes, i));
476470
}
477471
this->needsSort = false;
478472
}
@@ -510,8 +504,7 @@ void ProcessList_collapseAllBranches(ProcessList* this) {
510504
}
511505

512506
void ProcessList_rebuildPanel(ProcessList* this) {
513-
if (this->needsSort)
514-
ProcessList_sort(this);
507+
ProcessList_updateDisplayList(this);
515508

516509
const char* incFilter = this->incFilter;
517510

@@ -530,12 +523,12 @@ void ProcessList_rebuildPanel(ProcessList* this) {
530523
}
531524
}
532525

533-
const int processCount = Vector_size(this->processes);
526+
const int processCount = Vector_size(this->displayList);
534527
int idx = 0;
535528
bool foundFollowed = false;
536529

537530
for (int i = 0; i < processCount; i++) {
538-
Process* p = (Process*) Vector_get(this->processes, i);
531+
Process* p = (Process*) Vector_get(this->displayList, i);
539532

540533
if ( (!p->show)
541534
|| (this->userId != (uid_t) -1 && (p->st_uid != this->userId))

ProcessList.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ typedef unsigned long long int memory_t;
4343
typedef struct ProcessList_ {
4444
const Settings* settings;
4545

46-
Vector* processes;
47-
Vector* processes2;
48-
Hashtable* processTable;
46+
Vector* processes; /* all known processes; sort order can vary and differ from display order */
47+
Vector* displayList; /* process tree flattened in display order (borrowed) */
48+
Hashtable* processTable; /* fast known process lookup by PID */
4949
UsersTable* usersTable;
5050

5151
Hashtable* displayTreeSet;
@@ -109,7 +109,7 @@ void ProcessList_add(ProcessList* this, Process* p);
109109

110110
void ProcessList_remove(ProcessList* this, const Process* p);
111111

112-
void ProcessList_sort(ProcessList* this);
112+
void ProcessList_updateDisplayList(ProcessList* this);
113113

114114
ProcessField ProcessList_keyAt(const ProcessList* this, int at);
115115

0 commit comments

Comments
 (0)