signal: If the thread receiving the signal is not current, the signal is not processed.
This commit is contained in:
@ -875,8 +875,9 @@ void interrupt_exit(struct x86_user_context *regs)
|
|||||||
{
|
{
|
||||||
if (interrupt_from_user(regs)) {
|
if (interrupt_from_user(regs)) {
|
||||||
cpu_enable_interrupt();
|
cpu_enable_interrupt();
|
||||||
check_signal(0, regs, 0);
|
check_sig_pending();
|
||||||
check_need_resched();
|
check_need_resched();
|
||||||
|
check_signal(0, regs, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
check_sig_pending();
|
check_sig_pending();
|
||||||
|
|||||||
@ -1055,10 +1055,9 @@ out:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
check_sig_pending()
|
check_sig_pending_thread(struct thread *thread)
|
||||||
{
|
{
|
||||||
struct thread *thread;
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
struct list_head *head;
|
struct list_head *head;
|
||||||
mcs_rwlock_lock_t *lock;
|
mcs_rwlock_lock_t *lock;
|
||||||
@ -1067,22 +1066,11 @@ check_sig_pending()
|
|||||||
struct sig_pending *pending;
|
struct sig_pending *pending;
|
||||||
__sigset_t w;
|
__sigset_t w;
|
||||||
__sigset_t x;
|
__sigset_t x;
|
||||||
int sig;
|
int sig = 0;
|
||||||
struct k_sigaction *k;
|
struct k_sigaction *k;
|
||||||
|
struct cpu_local_var *v;
|
||||||
|
|
||||||
|
v = get_this_cpu_local_var();
|
||||||
if(clv == NULL)
|
|
||||||
return;
|
|
||||||
thread = cpu_local_var(current);
|
|
||||||
|
|
||||||
if (thread == NULL || thread == &cpu_local_var(idle)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread->in_syscall_offload == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
w = thread->sigmask.__val[0];
|
w = thread->sigmask.__val[0];
|
||||||
|
|
||||||
lock = &thread->sigcommon->lock;
|
lock = &thread->sigcommon->lock;
|
||||||
@ -1101,6 +1089,12 @@ check_sig_pending()
|
|||||||
if (pending->interrupted == 0) {
|
if (pending->interrupted == 0) {
|
||||||
pending->interrupted = 1;
|
pending->interrupted = 1;
|
||||||
found = 1;
|
found = 1;
|
||||||
|
if (sig != SIGCHLD &&
|
||||||
|
sig != SIGURG &&
|
||||||
|
!k->sa.sa_handler) {
|
||||||
|
found = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1108,6 +1102,10 @@ check_sig_pending()
|
|||||||
|
|
||||||
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
|
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
|
if (found == 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (lock == &thread->sigpendinglock) {
|
if (lock == &thread->sigpendinglock) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1116,17 +1114,49 @@ check_sig_pending()
|
|||||||
head = &thread->sigpending;
|
head = &thread->sigpending;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found == 2) {
|
||||||
if (sig != SIGCHLD && sig != SIGURG &&
|
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
|
||||||
thread->sigcommon->action[sig - 1].sa.sa_handler == NULL) {
|
|
||||||
terminate_mcexec(0, sig);
|
terminate_mcexec(0, sig);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else if (thread->sigcommon->action[sig - 1].sa.sa_handler &&
|
else if (found == 1) {
|
||||||
thread->sigcommon->action[sig - 1].sa.sa_handler !=
|
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
|
||||||
(void *)1) {
|
|
||||||
interrupt_syscall(thread, 0);
|
interrupt_syscall(thread, 0);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
check_sig_pending()
|
||||||
|
{
|
||||||
|
struct thread *thread;
|
||||||
|
struct cpu_local_var *v;
|
||||||
|
|
||||||
|
if (clv == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
v = get_this_cpu_local_var();
|
||||||
|
repeat:
|
||||||
|
v->runq_irqstate = ihk_mc_spinlock_lock(&v->runq_lock);
|
||||||
|
list_for_each_entry(thread, &(v->runq), sched_list) {
|
||||||
|
|
||||||
|
if (thread == NULL || thread == &cpu_local_var(idle)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->in_syscall_offload == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread->proc->exit_status & 0x0000000100000000L) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_sig_pending_thread(thread))
|
||||||
|
goto repeat;
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
|
|||||||
Reference in New Issue
Block a user