Skip to content
Snippets Groups Projects
Commit 789649f0 authored by FKHals's avatar FKHals
Browse files

Fix PBM generation and add (many) debug prints

since previously the fork and join nodes were not correctly connected
inside the PBM-graph.
Also fix Nullptr error.
parent 5d28268c
No related branches found
No related tags found
No related merge requests found
......@@ -145,13 +145,27 @@ pbm_NODE* task_alloc(void) {
return new_task_node;
}
/*
* Get the index of a given task (which can then be used as an unambiguous identificator).
* Returns -1 if given NULL.
*/
static int64_t task_2_index(pbm_NODE* task) {
int64_t res = ((uint64_t)task - (uint64_t)tasks->task_buffer) / sizeof(pbm_NODE);
if (!task || res > PROC_BUF_SIZE) {
return -1;
} else {
return res;
}
}
void debug_print_tasks(void) {
size_t i;
pbm_NODE t;
printk(KERN_WARNING "-----\nTASKS:\n");
for(i = 0; i <= tasks->curr_task_index; i++) {
t = tasks->task_buffer[i];
printk(KERN_WARNING "type: %u, thread_id: %u, count: %llu, children: %llx, next_sib: %llx\n", t.type, t.thread_id, t.count, (uint64_t)t.children, (uint64_t)t.next_sib);
printk(KERN_WARNING "addr: %lu, type: %u, thread_id: %u, count: %llu, children: %lli, next_sib: %lli\n",
i, t.type, t.thread_id, t.count, task_2_index(t.children), task_2_index(t.next_sib));
}
printk(KERN_WARNING "^^^^^\n");
}
......@@ -196,13 +210,28 @@ PBM* proc_alloc(void) {
return new_pbm;
}
/*
* Get the index of a given PBM (which can then be used as an unambiguous identificator)
* Returns -1 if given NULL.
*/
static int64_t pbm_2_index(PBM* pbm) {
int64_t res = ((uint64_t)pbm - (uint64_t)procs->process_buffer) / sizeof(PBM);
if (!pbm || res > PROC_BUF_SIZE) {
return -1;
} else {
return res;
}
}
void debug_print_procs(void) {
size_t i;
PBM p;
printk(KERN_WARNING "-----\nPROCS:\n");
for(i = 0; i <= procs->curr_proc_index; i++) {
p = procs->process_buffer[i];
printk(KERN_WARNING "root: %llx, last: %llx, children: %llx, next_sib: %llx\n", (uint64_t)p.root, (uint64_t)p.last, (uint64_t)p.children, (uint64_t)p.next_sib);
printk(KERN_WARNING "index: %lu, root: %lli, last: %lli, children: %lli, next_sib: %lli\n",
// calculate indices instead of using the pointers for more readability and represent NULL-values with -1
i, task_2_index(p.root), task_2_index(p.last), pbm_2_index(p.children), pbm_2_index(p.next_sib));
}
printk(KERN_WARNING "^^^^^\n");
}
......@@ -395,7 +424,8 @@ int pbm_task_end(PBM* pbm) {
/*
* Before starting the new task, append the fork-node to the task graph to maintain the correct order
*/
*/
printk(KERN_WARNING ">> CREATE NEW FORK NODE! by %u\n", parent_proc->pid);
fork_node = _pbm_create_node(FORK, parent_proc->pid);
if(!fork_node) {
printk(KERN_WARNING "COULD NOT CREATE NEW FORK NODE!\n");
......@@ -408,6 +438,10 @@ int pbm_task_end(PBM* pbm) {
}
parent_pbm->last = fork_node; // the new node becomes the last inserted one
// any fork-node has exactly two children because a fork creates only one
// copy of an existing process (1 (copy) + 1 (existing) = 2)
fork_node->count = 2;
// start the new task
pbm_task_start(parent_pbm, COMP, parent_proc);
......@@ -422,7 +456,7 @@ int pbm_task_end(PBM* pbm) {
* This function must get called in the _do_fork() routine AFTER (!) the child process starts to
* run (current == child) otherwise the perf counting will fail!
*/
int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_date) {
int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_node) {
unsigned long irq_flags;
PBM* parent_pbm;
......@@ -494,11 +528,23 @@ int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_date) {
// We have to know WHEN the exit happens relative to the parent. So every child remembers the
// current fork-task-node of the parent on exit (so that the join can happen at the correct
// position (more or less, may be imperfect due to parallelism))
child_pbm->fork_date = fork_date;
child_pbm->fork_date = fork_node;
// continue performance counting for child (restarting parent counting has already been started
pbm_task_start(child_pbm, COMP, proc);
// insert front of child task graph into parent task graph:
// prepend child-task-tree to list of child-nodes in the fork-node
// preconditions:
// * child_pbm->root->next_sib == NULL: since any fork-node has at most two children and
// only one before the join-operation)
// * child_pbm->root != NULL: since the previously called pbm_task_start() should have
// written to that
if (fork_node) {
child_pbm->root->next_sib = fork_node->children;
fork_node->children = child_pbm->root;
}
return 1;
}
......@@ -539,6 +585,7 @@ int pbm_join(PBM* child_pbm) {
if(!child_pbm)
return 0;
printk(KERN_WARNING "Joining thread %u with fork_node: %lli\n", child_pbm->last->thread_id, task_2_index(child_pbm->fork_date));
fork_node = child_pbm->fork_date;
// the child process is used to label the join operation to know which process the join belongs
......@@ -551,31 +598,20 @@ int pbm_join(PBM* child_pbm) {
return 0;
}
// any fork-node has exactly two children because a fork creates only one
// copy of an existing process (1 (copy) + 1 (existing) = 2)
fork_node->count = 2;
// any join-node has exactly two children because it is reversing a fork
// which creates only one copy of an existing process (1 (copy) + 1 (existing) = 2)
join_node->count = 2;
// insert front of child task graph into parent task graph:
// prepend child-task-tree to list of child-nodes in the fork-node
{
// assumption: child_pbm->root->next_sib == NULL (since any fork-node
// has at most two children and only one before the join-operation)
child_pbm->root->next_sib = fork_node->children;
fork_node->children = child_pbm->root;
}
// insert back of child task graph with appended join-node into parent task
// graph
{
// assumption: child_pbm->last->children == NULL (since it should be
// the last task the child did before exit)
// append join node to child task-graph
child_pbm->last->children = join_node;
// insert join node directly after the exit-date-node in the parent pbm
join_node->children = child_pbm->exit_date->children;
child_pbm->exit_date->children = join_node->children;
}
// insert back of child task graph with appended join-node into parent task graph
// precondition:
// * child_pbm->last->children == NULL: since it should be the last task the child did
// before exit
// append join node to child task-graph
child_pbm->last->children = join_node;
// insert join node directly after the exit-date-node in the parent pbm
printk(KERN_WARNING "Exit-date: %lli, child: %lli\n", task_2_index(child_pbm->exit_date), task_2_index(child_pbm->exit_date->children));
join_node->children = child_pbm->exit_date->children;
child_pbm->exit_date->children = join_node;
return 1;
}
......@@ -585,6 +621,7 @@ void pbm_post_processing(PBM* pbm) {
PBM* sib_pbm;
PBM* child_pbm = pbm->children;
if(child_pbm) {
printk(KERN_WARNING "Joining child thread %u\n", child_pbm->last->thread_id);
pbm_post_processing(child_pbm);
pbm_join(child_pbm);
// TODO Remove from list of childs or just mark as visited?
......@@ -592,7 +629,9 @@ void pbm_post_processing(PBM* pbm) {
sib_pbm = pbm->next_sib;
if(sib_pbm) {
printk(KERN_WARNING "Joining sib thread %u\n", sib_pbm->last->thread_id);
pbm_post_processing(sib_pbm);
pbm_join(sib_pbm);
// TODO Remove from list of siblings or just mark as visited?
}
}
......@@ -611,6 +650,8 @@ void pbm_join_and_print_graph_self(pid_t pid) {
pbm = get_pbm_by_pid(pid);
if (pbm) {
pbm_post_processing(pbm);
printk(KERN_WARNING "After post-processing:\n");
debug_print_tasks();
pbm_print_graph(pbm, pbm->root);
} else {
printk(KERN_WARNING "JOIN: PBM not found for: %u\n", pid);
......@@ -629,17 +670,20 @@ void pbm_print_graph(PBM* pbm, pbm_NODE* node) {
return;
root = node;
printk(KERN_WARNING "Node %p: (%s, count = %llu), children:\n", node, types[node->type], node->count);
printk(KERN_WARNING "Node %lli: (%s, pid = %u, count = %llu), children:\n",
task_2_index(node), types[node->type], node->thread_id, node->count);
if(node->children)
{
node = node->children;
while(node)
{
printk(KERN_WARNING " -- Node %p: (%s, count = %llu), next sibling: %p\n", node, types[node->type], node->count, node->next_sib);
printk(KERN_WARNING " -- Node %lli: (%s, pid = %u, count = %llu), next sibling: %lli\n",
task_2_index(node), types[node->type], node->thread_id, node->count, task_2_index(node->next_sib));
node = node->next_sib;
}
} else {
printk(KERN_WARNING " -- Exit (pid = %u)\n", node->thread_id);
}
if(root->children)
......
......@@ -128,7 +128,7 @@ int pbm_task_end(PBM* pbm);
*
* The process as an explicit argument is needed since the fork is called by the parent.
*/
int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_date);
int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_node);
int pbm_exit(pid_t pid, pid_t parent_pid);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment