@@ -786,6 +786,11 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
786
786
}
787
787
const ScreenSettings * ss = this -> settings -> ss ;
788
788
if (!ss -> treeView || this -> indent == 0 ) {
789
+ if (this -> merged > 1 ) {
790
+ char merged [16 ];
791
+ xSnprintf (merged , sizeof (merged ), "[%u] " , this -> merged );
792
+ RichString_appendAscii (str , CRT_colors [PROCESS_SHADOW ], merged );
793
+ }
789
794
Process_writeCommand (this , attr , baseattr , str );
790
795
return ;
791
796
}
@@ -820,6 +825,11 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
820
825
const char * draw = CRT_treeStr [lastItem ? TREE_STR_BEND : TREE_STR_RTEE ];
821
826
xSnprintf (buf , n , "%s%s " , draw , this -> showChildren ? CRT_treeStr [TREE_STR_SHUT ] : CRT_treeStr [TREE_STR_OPEN ] );
822
827
RichString_appendWide (str , CRT_colors [PROCESS_TREE ], buffer );
828
+ if (this -> merged > 1 ) {
829
+ char merged [16 ];
830
+ xSnprintf (merged , sizeof (merged ), "[%u] " , this -> merged );
831
+ RichString_appendAscii (str , CRT_colors [PROCESS_SHADOW ], merged );
832
+ }
823
833
Process_writeCommand (this , attr , baseattr , str );
824
834
return ;
825
835
}
@@ -1088,6 +1098,40 @@ int Process_pidCompare(const void* v1, const void* v2) {
1088
1098
return SPACESHIP_NUMBER (p1 -> pid , p2 -> pid );
1089
1099
}
1090
1100
1101
+ static bool isTransitiveChildOf (const Process * child , const Process * parent ) {
1102
+ assert (child -> processList == parent -> processList );
1103
+
1104
+ for (const Process * tChild = child ; tChild ; tChild = ProcessList_findProcess (parent -> processList , Process_getParentPid (tChild )))
1105
+ if (Process_isChildOf (tChild , parent -> pid ))
1106
+ return true;
1107
+
1108
+ return false;
1109
+ }
1110
+
1111
+ int Process_sameApplication (const Process * v1 , const Process * v2 ) {
1112
+ const char * exe1 = v1 -> procExe ;
1113
+ const char * exe2 = v2 -> procExe ;
1114
+
1115
+ if (!exe1 || !exe2 || !String_eq (exe1 , exe2 ))
1116
+ return 0 ;
1117
+
1118
+
1119
+ if (v1 -> session != v2 -> session )
1120
+ return 0 ;
1121
+
1122
+ // we can compare pointers since the field user points to a hashtable entry
1123
+ if (v1 -> user != v2 -> user )
1124
+ return 0 ;
1125
+
1126
+ if (isTransitiveChildOf (v1 , v2 ))
1127
+ return 2 ;
1128
+
1129
+ if (isTransitiveChildOf (v2 , v1 ))
1130
+ return 1 ;
1131
+
1132
+ return 0 ;
1133
+ }
1134
+
1091
1135
int Process_compare (const void * v1 , const void * v2 ) {
1092
1136
const Process * p1 = (const Process * )v1 ;
1093
1137
const Process * p2 = (const Process * )v2 ;
@@ -1251,3 +1295,33 @@ void Process_updateExe(Process* this, const char* exe) {
1251
1295
}
1252
1296
this -> mergedCommand .exeChanged = true;
1253
1297
}
1298
+
1299
+ void Process_mergeData (Process * p1 , const Process * p2 ) {
1300
+
1301
+ p1 -> percent_cpu += p2 -> percent_cpu ;
1302
+ p1 -> percent_mem += p2 -> percent_mem ;
1303
+ // keep COMM
1304
+ p1 -> majflt += p2 -> majflt ;
1305
+ p1 -> minflt += p2 -> minflt ;
1306
+ p1 -> m_resident += p2 -> m_resident ;
1307
+ p1 -> m_virt += p2 -> m_virt ;
1308
+ // store min NICE
1309
+ p1 -> nice = MINIMUM (p1 -> nice , p2 -> nice );
1310
+ p1 -> nlwp += p2 -> nlwp ;
1311
+ // keep PGRP
1312
+ // keep PID
1313
+ // keep PPID
1314
+ p1 -> priority = MAXIMUM (p1 -> priority , p2 -> priority );
1315
+ // keep PROCESSOR
1316
+ // keep SESSION
1317
+ p1 -> starttime_ctime = MINIMUM (p1 -> starttime_ctime , p2 -> starttime_ctime );
1318
+ // keep STATE
1319
+ // keep ST_UID
1320
+ p1 -> time += p2 -> time ;
1321
+ // keep TGID
1322
+ // keep TPGID
1323
+ // keep TTY_NR
1324
+ // keep USER
1325
+
1326
+ p1 -> merged += p2 -> merged ;
1327
+ }
0 commit comments