diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-02-06 18:42:38 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-02-06 18:42:38 +0000 |
commit | 7bcb40987b41efda8dd493434be65ee5d6371643 (patch) | |
tree | 226d9329979a1f6cd588e7384676bd9cf8e3560e | |
parent | 09e30a1a861156e28f380f5a15736860313eb75d (diff) |
Use atomic.h operation for manipulating p_siglist in struct proc. Solves
the problem with lost signals in MP kernels.
miod@, kettenis@ ok
-rw-r--r-- | sys/compat/linux/linux_misc.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 30 | ||||
-rw-r--r-- | sys/kern/sched_bsd.c | 4 | ||||
-rw-r--r-- | sys/sys/proc.h | 3 | ||||
-rw-r--r-- | sys/sys/signalvar.h | 4 |
5 files changed, 24 insertions, 21 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index cef5a180206..a88eab1f886 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_misc.c,v 1.59 2006/10/08 19:49:57 sturm Exp $ */ +/* $OpenBSD: linux_misc.c,v 1.60 2007/02/06 18:42:37 art Exp $ */ /* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */ /*- @@ -185,7 +185,7 @@ linux_sys_wait4(p, v, retval) if ((error = sys_wait4(p, &w4a, retval))) return error; - p->p_siglist &= ~sigmask(SIGCHLD); + atomic_clearbits_int(&p->p_siglist, sigmask(SIGCHLD)); if (status != NULL) { if ((error = copyin(status, &tstat, sizeof tstat))) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 5183532147a..acc868830d8 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.86 2007/01/17 23:08:18 art Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.87 2007/02/06 18:42:37 art Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -339,7 +339,7 @@ setsigvec(struct proc *p, int signum, struct sigaction *sa) */ if (sa->sa_handler == SIG_IGN || (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) { - p->p_siglist &= ~bit; /* never to be seen again */ + atomic_clearbits_int(&p->p_siglist, bit); if (signum != SIGCONT) p->p_sigignore |= bit; /* easier in psignal */ p->p_sigcatch &= ~bit; @@ -391,7 +391,7 @@ execsigs(struct proc *p) if (sigprop[nc] & SA_IGNORE) { if (nc != SIGCONT) p->p_sigignore |= mask; - p->p_siglist &= ~mask; + atomic_clearbits_int(&p->p_siglist, mask); } ps->ps_sigact[nc] = SIG_DFL; } @@ -842,7 +842,7 @@ psignal(struct proc *p, int signum) LIST_FOREACH(q, &p->p_thrchildren, p_thrsib) psignal(q, signum); #endif - p->p_siglist &= ~stopsigmask; + atomic_clearbits_int(&p->p_siglist, stopsigmask); } if (prop & SA_STOP) { @@ -850,11 +850,11 @@ psignal(struct proc *p, int signum) LIST_FOREACH(q, &p->p_thrchildren, p_thrsib) psignal(q, signum); #endif - p->p_siglist &= ~contsigmask; + atomic_clearbits_int(&p->p_siglist, contsigmask); p->p_flag &= ~P_CONTINUED; } - p->p_siglist |= mask; + atomic_setbits_int(&p->p_siglist, mask); /* * Defer further processing for signals which are held, @@ -889,7 +889,7 @@ psignal(struct proc *p, int signum) * be awakened. */ if ((prop & SA_CONT) && action == SIG_DFL) { - p->p_siglist &= ~mask; + atomic_clearbits_int(&p->p_siglist, mask); goto out; } /* @@ -903,7 +903,7 @@ psignal(struct proc *p, int signum) */ if (p->p_flag & P_PPWAIT) goto out; - p->p_siglist &= ~mask; + atomic_clearbits_int(&p->p_siglist, mask); p->p_xstat = signum; if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) psignal(p->p_pptr, SIGCHLD); @@ -945,7 +945,7 @@ psignal(struct proc *p, int signum) p->p_flag |= P_CONTINUED; wakeup(p->p_pptr); if (action == SIG_DFL) - p->p_siglist &= ~mask; + atomic_clearbits_int(&p->p_siglist, mask); if (action == SIG_CATCH) goto runfast; if (p->p_wchan == 0) @@ -959,7 +959,7 @@ psignal(struct proc *p, int signum) * Already stopped, don't need to stop again. * (If we did the shell could get confused.) */ - p->p_siglist &= ~mask; /* take it away */ + atomic_clearbits_int(&p->p_siglist, mask); goto out; } @@ -1024,7 +1024,7 @@ issignal(struct proc *p) return (0); signum = ffs((long)mask); mask = sigmask(signum); - p->p_siglist &= ~mask; /* take the signal! */ + atomic_clearbits_int(&p->p_siglist, mask); /* * We should see pending but ignored signals @@ -1061,7 +1061,9 @@ issignal(struct proc *p) mask = sigmask(signum); if ((p->p_sigmask & mask) != 0) continue; - p->p_siglist &= ~mask; /* take the signal! */ + + /* take the signal! */ + atomic_clearbits_int(&p->p_siglist, mask); } prop = sigprop[signum]; @@ -1140,7 +1142,7 @@ issignal(struct proc *p) /* NOTREACHED */ keep: - p->p_siglist |= mask; /* leave the signal for later */ + atomic_setbits_int(&p->p_siglist, mask); /*leave the signal for later */ return (signum); } @@ -1184,7 +1186,7 @@ postsig(int signum) KERNEL_PROC_LOCK(p); mask = sigmask(signum); - p->p_siglist &= ~mask; + atomic_clearbits_int(&p->p_siglist, mask); action = ps->ps_sigact[signum]; sigval.sival_ptr = 0; type = SI_USER; diff --git a/sys/kern/sched_bsd.c b/sys/kern/sched_bsd.c index a62c5248b86..699f4dd807a 100644 --- a/sys/kern/sched_bsd.c +++ b/sys/kern/sched_bsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sched_bsd.c,v 1.9 2006/11/29 12:24:18 miod Exp $ */ +/* $OpenBSD: sched_bsd.c,v 1.10 2007/02/06 18:42:37 art Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /*- @@ -609,7 +609,7 @@ setrunnable(struct proc *p) * while we were stopped), check for a signal from the debugger. */ if ((p->p_flag & P_TRACED) != 0 && p->p_xstat != 0) - p->p_siglist |= sigmask(p->p_xstat); + atomic_setbits_int(&p->p_siglist, sigmask(p->p_xstat)); case SSLEEP: unsleep(p); /* e.g. when sending signals */ break; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 65ad8c42bf4..a86ea27d412 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.89 2006/11/29 12:24:18 miod Exp $ */ +/* $OpenBSD: proc.h,v 1.90 2007/02/06 18:42:37 art Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -45,6 +45,7 @@ #include <sys/queue.h> #include <sys/timeout.h> /* For struct timeout. */ #include <sys/event.h> /* For struct klist */ +#include <machine/atomic.h> #ifdef __HAVE_CPUINFO #define curproc curcpu()->ci_curproc diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 8618c280032..8853ab2c6f2 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signalvar.h,v 1.15 2005/06/17 22:33:34 niklas Exp $ */ +/* $OpenBSD: signalvar.h,v 1.16 2007/02/06 18:42:37 art Exp $ */ /* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */ /* @@ -89,7 +89,7 @@ struct sigacts { /* * Clear a pending signal from a process. */ -#define CLRSIG(p, sig) { (p)->p_siglist &= ~sigmask(sig); } +#define CLRSIG(p, sig) atomic_clearbits_int(&(p)->p_siglist, sigmask(sig)) /* * Signal properties and actions. |