#define MAX_NAME 100\r
\r
\r
-#define add_childs 1ULL\r
-\r
unsigned long long Hertz = 1;\r
\r
long pid_max = 32768;\r
int new_entry;\r
unsigned long merge_count;\r
struct wanted *target;\r
- int target_inherited;\r
struct pid_stat *parent;\r
struct pid_stat *prev;\r
struct pid_stat *next;\r
{\r
if(!all_pids[pid]) return;\r
\r
+ if(debug) fprintf(stderr, "Process %d %s exited, deleting it.\n", pid, all_pids[pid]->comm);\r
+\r
if(root == all_pids[pid]) root = all_pids[pid]->next;\r
if(all_pids[pid]->next) all_pids[pid]->next->prev = all_pids[pid]->prev;\r
if(all_pids[pid]->prev) all_pids[pid]->prev->next = all_pids[pid]->next;\r
p->merged = 0;\r
p->new_entry = 0;\r
p->merge_count = 0;\r
-\r
- if(p->target_inherited) p->target = NULL;\r
}\r
\r
while((file = readdir(dir))) {\r
\r
close(fd);\r
if(bytes < 100) continue;\r
+ buffer[bytes] = '\0';\r
+ if(debug) fprintf(stderr, "READ: %s", buffer);\r
\r
p = get_entry(pid);\r
if(!p) continue;\r
strncpy(p->comm, name, MAX_COMPARE_NAME + 2);\r
p->comm[MAX_COMPARE_NAME + 2] = '\0';\r
\r
+ if(debug) fprintf(stderr, "VALUES: %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
+\r
if(parsed < 39) fprintf(stderr, "file %s gave %d results (expected 44)\n", filename, parsed);\r
\r
// check if it is wanted\r
}\r
\r
// just a few checks\r
- if(p->ppid < 1 || p->ppid > pid_max) p->ppid = 1;\r
+ if(p->ppid < 0 || p->ppid > pid_max) p->ppid = 0;\r
\r
// mark it as updated\r
p->updated = 1;\r
}\r
closedir(dir);\r
\r
- // cleanup all un-updated\r
+ // cleanup all un-updated processed (exited, killed, etc)\r
int c;\r
for(p = root, c = 0; p ; c++) {\r
if(!p->updated) {\r
+ \r
pid_t r = p->pid;\r
p = p->next;\r
del_entry(r);\r
else p = p->next;\r
}\r
\r
- if(debug) fprintf(stderr, "There are %d processes active\n", c);\r
-\r
return 1;\r
}\r
\r
+void walk_down(pid_t pid, int level) {\r
+ struct pid_stat *p = NULL;\r
+ char b[level+3];\r
+ int i;\r
+\r
+ for(i = 0; i < level; i++) b[i] = '\t';\r
+ b[level] = '|';\r
+ b[level+1] = '-';\r
+ b[level+2] = '\0';\r
+\r
+ p = all_pids[pid];\r
+ if(p) fprintf(stderr, "%s %s %d [%s] c=%d u=%llu, s=%llu, cu=%llu, cs=%llu, n=%llu, j=%llu, cn=%llu, cj=%llu\n", b, p->comm, p->pid, p->updated?"OK":"KILLED", p->childs, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
+\r
+ for(p = root; p ; p = p->next) {\r
+ if(p->ppid == pid) {\r
+ walk_down(p->pid, level+1);\r
+ }\r
+ }\r
+}\r
+\r
void merge_processes(void)\r
{\r
struct pid_stat *p = NULL;\r
\r
+ if(debug) walk_down(0, 1);\r
+\r
// link all parents and update childs count\r
for(p = root; p ; p = p->next) {\r
- if(p->ppid > 1 && p->ppid <= pid_max && all_pids[p->ppid]) {\r
+ if(p->ppid > 0 && p->ppid <= pid_max && all_pids[p->ppid]) {\r
if(debug) fprintf(stderr, "\tParent of %d %s is %d %s\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm);\r
\r
p->parent = all_pids[p->ppid];\r
- if(!p->parent) {\r
- if(debug) fprintf(stderr, "\t\tpid %d %s states parent %d, but the later does not exist.\n", p->pid, p->comm, p->ppid);\r
- continue;\r
- }\r
-\r
p->parent->childs++;\r
}\r
+ else if(p->ppid != 0) fprintf(stderr, "\t\tWRONG! pid %d %s states parent %d, but the later does not exist.\n", p->pid, p->comm, p->ppid);\r
}\r
\r
// find all the procs with 0 childs and merge them to their parents\r
// repeat, until nothing more can be done.\r
int found = 1;\r
- for( ; found ; ) {\r
+ while(found) {\r
found = 0;\r
for(p = root; p ; p = p->next) {\r
- // if this process does not any childs, and\r
+ // if this process does not have any childs, and\r
// is not already merged, and\r
- // its parents has childs waiting to be merged, and\r
+ // its parent has childs waiting to be merged, and\r
// the target of this process and its parent is the same, or the parent does not have a target, or this process does not have a parent\r
+ // and its parent is not init\r
// then... merge them!\r
- if(!p->childs && !p->merged && p->parent && p->parent->childs && (p->target == p->parent->target || !p->parent->target || !p->target)) {\r
- if(debug) fprintf(stderr, "\tMerging %d %s to %d %s (count: %lu)\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm, p->parent->merge_count+1);\r
+ if(!p->childs && !p->merged && p->parent && p->parent->childs && (p->target == p->parent->target || !p->parent->target || !p->target) && p->ppid != 1) {\r
+\r
+ if(debug) fprintf(stderr, "\n\t\tPARENT BEFORE MERGE: %d %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->parent->pid, p->parent->comm, p->parent->utime, p->parent->stime, p->parent->cutime, p->parent->cstime, p->parent->minflt, p->parent->majflt, p->parent->cminflt, p->parent->cmajflt);\r
\r
p->parent->minflt += p->minflt;\r
p->parent->majflt += p->majflt;\r
p->parent->num_threads += p->num_threads;\r
p->parent->rss += p->rss;\r
\r
+ if(debug) fprintf(stderr, "\tMERGED %d %s to %d %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
+\r
p->parent->childs--;\r
p->merged = 1;\r
\r
+ if(debug) fprintf(stderr, "\t\tPARENT AFTER MERGE: %d %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->parent->pid, p->parent->comm, p->parent->utime, p->parent->stime, p->parent->cutime, p->parent->cstime, p->parent->minflt, p->parent->majflt, p->parent->cminflt, p->parent->cmajflt);\r
+\r
p->parent->merge_count += p->merge_count + 1;\r
\r
// the parent inherits the child's target, if it does not have a target itself\r
if(p->target && !p->parent->target) {\r
p->parent->target = p->target;\r
- p->parent->target_inherited = 1;\r
if(debug) fprintf(stderr, "\t\ttarget %s is inherited by %d %s from its child %d %s.\n", p->target->name, p->parent->pid, p->parent->comm, p->pid, p->comm);\r
}\r
\r
if(debug) fprintf(stderr, "Merged %d processes\n", found);\r
}\r
\r
- if(debug) {\r
- fprintf(stderr, "Root level processes: \n");\r
- for(p = root, found = 0; p ; p = p->next) {\r
- if(!p->childs && !p->merged && !p->parent) {\r
- fprintf(stderr, "\t\t%s %d on target %s\n", p->comm, p->pid, p->target?p->target->name:"-");\r
+ // give a default target on all top level processes\r
+ // init goes always to default target\r
+ if(all_pids[1]) all_pids[1]->target = default_target;\r
+\r
+ for(p = root, found = 0; p ; p = p->next) {\r
+ // if the process is not merged itself\r
+ // then is is a top level process\r
+ if(!p->merged && !p->target) p->target = default_target;\r
+ }\r
+\r
+ // give a target to all merged child processes\r
+ found = 1;\r
+ while(found) {\r
+ found = 0;\r
+ for(p = root; p ; p = p->next) {\r
+ if(!p->target && p->merged && p->parent && p->parent->target) {\r
+ p->target = p->parent->target;\r
+ found++;\r
}\r
}\r
}\r
\r
- // zero the targets\r
+ // zero all the targets\r
struct wanted *w;\r
for (w = wanted_root; w ; w = w->next) {\r
w->minflt = 0;\r
for(p = root; p ; p = p->next) {\r
//if(p->parent && !p->merged) fprintf(stderr, "\tprocess %s pid %d has a parent, but has not been merged!\n", p->comm, p->pid);\r
//if(p->childs) fprintf(stderr, "\tprocess %s pid %d has %d childs that have not been merged!\n", p->comm, p->pid, p->childs);\r
- if(p->merged) continue;\r
\r
if(!p->target) {\r
- p->target = default_target;\r
- p->target_inherited = 1;\r
- if(debug) fprintf(stderr, "\tprocess %s pid %d is orphan\n", p->comm, p->pid);\r
+ fprintf(stderr, "WRONG! pid %d %s was left without a target!\n", p->pid, p->comm);\r
+ continue;\r
}\r
\r
+ if(p->merged) continue;\r
+\r
p->target->minflt += p->minflt;\r
p->target->majflt += p->majflt;\r
p->target->utime += p->utime;\r
p->target->rss += p->rss;\r
\r
p->target->merge_count += p->merge_count + 1;\r
- if(debug) fprintf(stderr, "\tAgregating %s pid %d on %s (count: %lu)\n", p->comm, p->pid, p->target->name, p->target->merge_count);\r
+\r
+ if(debug) fprintf(stderr, "\tAgregating %s pid %d on %s (count: %lu) utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->pid, p->target->name, p->target->merge_count, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
}\r
}\r
\r
for (w = wanted_root; w ; w = w->next) {\r
if(w->target || (!w->merge_count && !w->exposed)) continue;\r
\r
- fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime + (w->cutime * add_childs) + (w->cstime * add_childs));\r
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime);\r
}\r
fprintf(stdout, "END\n");\r
\r
for (w = wanted_root; w ; w = w->next) {\r
if(w->target || (!w->merge_count && !w->exposed)) continue;\r
\r
- fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + (w->cutime * add_childs));\r
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->utime);\r
}\r
fprintf(stdout, "END\n");\r
\r
for (w = wanted_root; w ; w = w->next) {\r
if(w->target || (!w->merge_count && !w->exposed)) continue;\r
\r
- fprintf(stdout, "SET %s = %llu\n", w->name, w->stime + (w->cstime * add_childs));\r
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->stime);\r
}\r
fprintf(stdout, "END\n");\r
\r
for (w = wanted_root; w ; w = w->next) {\r
if(w->target || (!w->merge_count && !w->exposed)) continue;\r
\r
- fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt + (w->cminflt * add_childs));\r
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt);\r
}\r
fprintf(stdout, "END\n");\r
\r
for (w = wanted_root; w ; w = w->next) {\r
if(w->target || (!w->merge_count && !w->exposed)) continue;\r
\r
- fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt + (w->cmajflt * add_childs));\r
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt);\r
}\r
fprintf(stdout, "END\n");\r
\r
- fflush(stdout);\r
+ fflush(NULL);\r
}\r
\r
void show_charts(void)\r
fprintf(stdout, "DIMENSION %s '' incremental 1 1\n", w->name);\r
}\r
\r
- fflush(stdout);\r
+ fflush(NULL);\r
}\r
\r
unsigned long long get_hertz(void)\r
hz = (sizeof(long)==sizeof(int) || htons(999)==999) ? 100UL : 1024UL;\r
#endif\r
\r
- fprintf(stderr, "Unknown HZ value. Assuming %llu", hz);\r
+ fprintf(stderr, "Unknown HZ value. Assuming %llu.\n", hz);\r
return hz;\r
}\r
\r