interrupt syscall sufficient threads

This commit is contained in:
Tomoki Shirasawa
2014-08-18 16:49:49 +09:00
parent 23ab6032ba
commit 663c121308
3 changed files with 57 additions and 42 deletions

View File

@@ -309,6 +309,8 @@ do_kill(int pid, int tid, int sig)
struct list_head *head; struct list_head *head;
int rc; int rc;
unsigned long irqstate; unsigned long irqstate;
struct k_sigaction *k;
int doint;
if(proc == NULL || proc->pid == 0){ if(proc == NULL || proc->pid == 0){
return -ESRCH; return -ESRCH;
@@ -317,27 +319,30 @@ do_kill(int pid, int tid, int sig)
if(sig > 64 || sig < 0) if(sig > 64 || sig < 0)
return -EINVAL; return -EINVAL;
mask = __sigmask(sig);
if(tid == -1){ if(tid == -1){
if(pid == -1) struct process *tproc0 = NULL;
return -EPERM;
if(proc->pid == -pid)
pid = -pid;
if(pid == proc->pid || pid == 0){ if(pid == proc->pid || pid == 0){
tproc = proc; tproc0 = proc;
} }
else{ for(i = 0; i < num_processors; i++){
for(i = 0; i < num_processors; i++){ v = get_cpu_local_var(i);
v = get_cpu_local_var(i); irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); list_for_each_entry(p, &(v->runq), sched_list){
list_for_each_entry(p, &(v->runq), sched_list){ if(p->pid == pid){
if(p->pid == pid){ if(p->tid == pid || tproc0 == NULL)
tproc = p; tproc0 = p;
break; if(mask & p->sigmask.__val[0]){
if(p->tid == pid || tproc == NULL)
tproc = p;
} }
} }
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
} }
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
} }
if(tproc == NULL)
tproc = tproc0;
} }
else if(pid == -1){ else if(pid == -1){
for(i = 0; i < num_processors; i++){ for(i = 0; i < num_processors; i++){
@@ -376,6 +381,8 @@ do_kill(int pid, int tid, int sig)
if(sig == 0) if(sig == 0)
return 0; return 0;
doint = 0;
if(tid == -1){ if(tid == -1){
irqstate = ihk_mc_spinlock_lock(&tproc->sigshared->lock); irqstate = ihk_mc_spinlock_lock(&tproc->sigshared->lock);
head = &tproc->sigshared->sigpending; head = &tproc->sigshared->sigpending;
@@ -384,38 +391,47 @@ do_kill(int pid, int tid, int sig)
irqstate = ihk_mc_spinlock_lock(&tproc->sigpendinglock); irqstate = ihk_mc_spinlock_lock(&tproc->sigpendinglock);
head = &tproc->sigpending; head = &tproc->sigpending;
} }
mask = __sigmask(sig);
pending = NULL; k = tproc->sighandler->action + sig - 1;
rc = 0; if(k->sa.sa_handler != (void *)1 &&
if(sig < 33){ // SIGRTMIN - SIGRTMAX (k->sa.sa_handler != NULL ||
list_for_each_entry(pending, head, list){ (sig != SIGCHLD && sig != SIGURG))){
if(pending->sigmask.__val[0] == mask) pending = NULL;
break; rc = 0;
if(sig < 33){ // SIGRTMIN - SIGRTMAX
list_for_each_entry(pending, head, list){
if(pending->sigmask.__val[0] == mask)
break;
}
if(&pending->list == head)
pending = NULL;
} }
if(&pending->list == head) if(pending == NULL){
pending = NULL; doint = 1;
} pending = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT);
if(pending == NULL){ pending->sigmask.__val[0] = mask;
pending = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT); if(!pending){
pending->sigmask.__val[0] = mask; rc = -ENOMEM;
if(!pending){ }
rc = -ENOMEM; else{
} list_add_tail(&pending->list, head);
else{ tproc->sigevent = 1;
list_add_tail(&pending->list, head); }
tproc->sigevent = 1;
} }
} }
if(tid == -1){ if(tid == -1){
ihk_mc_spinlock_unlock(&tproc->sigshared->lock, irqstate); ihk_mc_spinlock_unlock(&tproc->sigshared->lock, irqstate);
} }
else{ else{
ihk_mc_spinlock_unlock(&tproc->sigpendinglock, irqstate); ihk_mc_spinlock_unlock(&tproc->sigpendinglock, irqstate);
} }
if(proc != tproc){ if(doint && !(mask & tproc->sigmask.__val[0])){
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tproc->cpu_id)->apic_id, 0xd0); if(proc != tproc){
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tproc->cpu_id)->apic_id, 0xd0);
}
interrupt_syscall(tproc->pid, tproc->cpu_id);
} }
interrupt_syscall(1, tproc->pid);
return rc; return rc;
} }

View File

@@ -1111,7 +1111,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
break; break;
case __NR_kill: // interrupt syscall case __NR_kill: // interrupt syscall
kill_thread(w.sr.args[0]); kill_thread(w.sr.args[1]);
do_syscall_return(fd, cpu, 0, 0, 0, 0, 0); do_syscall_return(fd, cpu, 0, 0, 0, 0, 0);
break; break;
case __NR_exit: case __NR_exit:

View File

@@ -129,7 +129,7 @@ static void send_syscall(struct syscall_request *req, int cpu, int pid)
* exit/receive signals at the same time?? */ * exit/receive signals at the same time?? */
cpu = num_processors; cpu = num_processors;
if(req->number == __NR_kill) if(req->number == __NR_kill)
pid = req->args[2]; pid = req->args[0];
} }
else{ else{
scp = &get_cpu_local_var(cpu)->scp; scp = &get_cpu_local_var(cpu)->scp;
@@ -454,14 +454,13 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
} }
void void
interrupt_syscall(int all, int pid) interrupt_syscall(int pid, int cpuid)
{ {
ihk_mc_user_context_t ctx; ihk_mc_user_context_t ctx;
long lerror; long lerror;
ihk_mc_syscall_arg0(&ctx) = all? -1: ihk_mc_get_processor_id(); ihk_mc_syscall_arg0(&ctx) = pid;
ihk_mc_syscall_arg1(&ctx) = 0; ihk_mc_syscall_arg1(&ctx) = cpuid;
ihk_mc_syscall_arg2(&ctx) = pid;
lerror = syscall_generic_forwarding(__NR_kill, &ctx); lerror = syscall_generic_forwarding(__NR_kill, &ctx);
if (lerror) { if (lerror) {