diff --git a/kernel/behave.c b/kernel/behave.c index b3cb71774f54b208170dd59328e1660ebe57817c..821e231901c6c5e60f039ea1847a0a24ae88bc76 100644 --- a/kernel/behave.c +++ b/kernel/behave.c @@ -386,10 +386,12 @@ int pbm_task_end(PBM* pbm) { // end task of parent process parent_pbm = get_pbm_by_pid(parent_proc->pid); if(!parent_pbm) { - printk(KERN_WARNING "COULD NOT FIND PARENT-PBM!\n"); - //TODO Since this will happen right at the first call to pbm_fork() - //TODO since no parent process has been initialized (since this is - //TODO the first relevant parent process) + // this should only happen right at the first call to pbm_fork() since at this point no + // parent process has been initialized yet since this is the first relevant parent process + if (current->pid != root_proc) { + printk(KERN_WARNING "ERROR: COULD NOT FIND PARENT-PBM!\n"); + BUG(); + } return NULL; } pbm_task_end(parent_pbm); @@ -484,7 +486,9 @@ int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_node) { child_pbm->next_sib = parent_pbm->children; } parent_pbm->children = child_pbm; - } + } else { + BUG_ON(current->pid != root_proc); + } // 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 @@ -527,7 +531,15 @@ int pbm_exit(pid_t pid, pid_t parent_pid) { // set current parent task as the exit task of this child where the join // gets inserted if(parent_pbm) { + if (parent_pbm->last == NULL) { + printk(KERN_WARNING "ERROR: ParentPBM->LAST is NULL! ppid: %u\n", parent_pid); + } pbm->exit_date = parent_pbm->last; + } else { + if (current->pid != root_proc) { + printk(KERN_WARNING "ERROR: COULD NOT FIND PARENT! child: %u, parent: %u\n", pid, parent_pid); + BUG(); + } } return 1; @@ -546,6 +558,10 @@ int pbm_join(PBM* child_pbm) { if(!child_pbm) return 0; + if (!child_pbm->exit_date) { + printk(KERN_WARNING "Exit date missing for pid %u. Has the process really been exited?\n", child_pbm->last->thread_id); + } + 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; @@ -601,6 +617,14 @@ void pbm_post_processing(PBM* pbm) { * PBM graph output functions */ +/** + * BEWARE: + * This function must not be called before ALL childs, grandchilds etc. of the root process of a + * measured program are exited since otherwise the informations in the model are not complete and + * therefore this function will throw an error! + * In this case most probably pbm_join() will generate the error since the exit_date of the not yet + * exited process will not be set and also the perf counter values will probably be wrong. + */ void pbm_join_and_print_graph_self(pid_t pid) { PBM* pbm; diff --git a/kernel/exit.c b/kernel/exit.c index 1d7f88f7aec2e1e55e042ce72a034f57a3d9a4e2..c4d3a454dcda95a134497ea90269b864c147d0bf 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -771,6 +771,13 @@ void __noreturn do_exit(long code) if (is_relevant_process(tsk)) { pbm_exit(tsk->pid, tsk->real_parent->pid); } + + /** + * BEWARE: + * It is necessary that the root process of a measured program does not exit before ALL its + * childs, grandchilds etc. are exited since otherwise the informations in the model are not + * complete and therefore pbm_join_and_print_graph_self() will throw an error! + */ if (is_root_process(tsk)) { pbm_join_and_print_graph_self(tsk->pid); } diff --git a/pb_utils/pb_submitter/test_prog.c b/pb_utils/pb_submitter/test_prog.c index 5a6e77fbdb2896c1bcd98ee1fd50a5cc57a65748..c4d3cb192bd93dd121f0920245163159a4ede172 100644 --- a/pb_utils/pb_submitter/test_prog.c +++ b/pb_utils/pb_submitter/test_prog.c @@ -26,10 +26,11 @@ int main(void) printf("run completed\n"); usleep(1); - if (n1 > 0 && n2 > 0) { - // barrier: let the father wait for all the child processes - while ((wpid = wait(&status)) > 0) {}; + // barrier: make all fathers wait for all its child processes (since all processes use that line) + while ((wpid = wait(&status)) > 0) {}; + if (n1 > 0 && n2 > 0) + { fprintf(stderr, "This is the parent %d (%d, %d)\n", getpid(), n1, n2); // syscall to switch tasks