diff --git a/kernel/process.c b/kernel/process.c index 01dddb50..ac48fa36 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1789,6 +1789,38 @@ static void idle(void) while (1) { schedule(); cpu_disable_interrupt(); + /* + * XXX: KLUDGE: It is desirable to be resolved in schedule(). + * + * There is a problem which causes wait4(2) hang when + * wait4(2) called by a process races with its child process + * termination. This is a quick fix for this problem. + * + * The problem occurrd in the following sequence. + * 1) The parent process called schedule() from sys_wait4() to + * wait for an event generated by the child process. + * 2) schedule() resumed the idle process because there was no + * runnable process in run queue. + * 3) At the moment, the child process began to end. It set + * the parent process runnable, and sent an interrupt to + * the parent process's cpu. But this interrupt had no + * effect because the parent process's cpu had not halted. + * 4) The idle process was resumed, and halted for waiting for + * the interrupt that had already been handled. + */ + if (v->status == CPU_STATUS_IDLE) { + long s; + struct process *p; + + s = ihk_mc_spinlock_lock(&v->runq_lock); + list_for_each_entry(p, &v->runq, sched_list) { + if (p->status == PS_RUNNING) { + v->status = CPU_STATUS_RUNNING; + break; + } + } + ihk_mc_spinlock_unlock(&v->runq_lock, s); + } if (v->status == CPU_STATUS_IDLE) { cpu_safe_halt(); }