Support SIGSTOP and SIGCONT
This commit is contained in:
@ -274,6 +274,30 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
|
||||
case SIGCHLD:
|
||||
case SIGURG:
|
||||
return;
|
||||
case SIGSTOP: {
|
||||
dkprintf("do_signal,SIGSTOP,changing state\n");
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct fork_tree_node *ftn = proc->ftn;
|
||||
int exit_code = SIGSTOP;
|
||||
|
||||
/* Update process state in fork tree */
|
||||
ihk_mc_spinlock_lock_noirq(&ftn->lock);
|
||||
ftn->exit_status = (exit_code << 8) | 0x7f;
|
||||
ftn->status = PS_STOPPED;
|
||||
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
|
||||
|
||||
/* Wake up the parent who tried wait4 and sleeping */
|
||||
waitq_wakeup(&proc->ftn->parent->waitpid_q);
|
||||
|
||||
dkprintf("do_signal,SIGSTOP,sleeping\n");
|
||||
/* Sleep */
|
||||
proc->status = PS_STOPPED;
|
||||
schedule();
|
||||
dkprintf("SIGSTOP(): woken up\n");
|
||||
goto out; }
|
||||
case SIGCONT:
|
||||
dkprintf("do_signal,SIGCONT,do nothing\n");
|
||||
goto out;
|
||||
case SIGQUIT:
|
||||
case SIGILL:
|
||||
case SIGTRAP:
|
||||
@ -288,6 +312,7 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
|
||||
}
|
||||
terminate(0, sig | coredumped, (ihk_mc_user_context_t *)regs->rsp);
|
||||
}
|
||||
out:;
|
||||
}
|
||||
|
||||
void
|
||||
@ -555,21 +580,39 @@ do_kill(int pid, int tid, int sig)
|
||||
else{
|
||||
ihk_mc_spinlock_unlock_noirq(&tproc->sigpendinglock);
|
||||
}
|
||||
|
||||
dkprintf("do_kill,pid=%d,sig=%d\n", pid, sig);
|
||||
if(doint && !(mask & tproc->sigmask.__val[0])){
|
||||
int cpuid = tproc->cpu_id;
|
||||
dkprintf("do_kill,proc=%p,tproc=%p\n", proc, tproc);
|
||||
if(proc != tproc){
|
||||
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(cpuid)->apic_id, 0xd0);
|
||||
}
|
||||
pid = tproc->pid;
|
||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
||||
cpu_restore_interrupt(irqstate);
|
||||
dkprintf("do_kill,sending kill to mcexec,pid=%d,cpuid=%d\n", pid, cpuid);
|
||||
interrupt_syscall(pid, cpuid);
|
||||
}
|
||||
else{
|
||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
||||
cpu_restore_interrupt(irqstate);
|
||||
}
|
||||
if(!(mask & tproc->sigmask.__val[0])) {
|
||||
switch(sig) {
|
||||
case SIGCONT:
|
||||
dkprintf("do_kill,SIGCONT\n");
|
||||
/* Wake up the target only when stopped by SIGSTOP */
|
||||
sched_wakeup_process(tproc, PS_STOPPED);
|
||||
if (tproc->ftn->status & PS_STOPPED) {
|
||||
ihk_mc_spinlock_lock_noirq(&tproc->ftn->lock);
|
||||
xchg4((int *)(&tproc->ftn->status), PS_RUNNING);
|
||||
ihk_mc_spinlock_unlock_noirq(&tproc->ftn->lock);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
#define PS_UNINTERRUPTIBLE 0x4
|
||||
#define PS_ZOMBIE 0x8
|
||||
#define PS_EXITED 0x10
|
||||
#define PS_STOPPED 0x20
|
||||
|
||||
#define PS_NORMAL (PS_INTERRUPTIBLE | PS_UNINTERRUPTIBLE)
|
||||
|
||||
|
||||
@ -367,6 +367,18 @@ rescan:
|
||||
if (ret != pid)
|
||||
kprintf("WARNING: host waitpid failed?\n");
|
||||
|
||||
goto exit;
|
||||
} else if(child->status == PS_STOPPED) {
|
||||
ihk_mc_spinlock_unlock_noirq(&child->lock);
|
||||
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
|
||||
|
||||
/* exit_status is created in do_signal */
|
||||
if (status) {
|
||||
*status = child->exit_status;
|
||||
}
|
||||
pid = child->pid;
|
||||
dkprintf("wait4,PS_STOPPED,pid=%d,status=%08x\n", pid, *status);
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user