1:1 Userland threading stage 2.20/4:
authorSimon Schubert <corecode@dragonflybsd.org>
Wed, 21 Feb 2007 15:46:48 +0000 (15:46 +0000)
committerSimon Schubert <corecode@dragonflybsd.org>
Wed, 21 Feb 2007 15:46:48 +0000 (15:46 +0000)
Unify access to pending threads with a new function, lwp_sigpend(), which
returns pending signals for the lwp, which includes both lwp-specific
signals and signals pending on the process.  The new function lwp_delsig()
is used to remove a certain signal from the pending set of both process and
lwp.

Rework the places which access the pending signal list to either use those
two functions or, where not possibly, to work on both lwp and proc signal
lists.

sys/emulation/linux/linux_misc.c
sys/kern/kern_exit.c
sys/kern/kern_sig.c
sys/kern/tty.c
sys/netproto/ncp/ncp_ncp.c
sys/netproto/smb/smb_subr.c
sys/sys/signalvar.h
sys/vfs/mfs/mfs_vfsops.c
sys/vfs/nfs/nfs_socket.c
sys/vfs/procfs/procfs_ctl.c

index 4ad0a1b..b59b21b 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_misc.c,v 1.85.2.9 2002/09/24 08:11:41 mdodd Exp $
- * $DragonFly: src/sys/emulation/linux/linux_misc.c,v 1.35 2007/01/06 19:37:18 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_misc.c,v 1.36 2007/02/21 15:46:48 corecode Exp $
  */
 
 #include "opt_compat.h"
@@ -797,11 +797,11 @@ int
 sys_linux_wait4(struct linux_wait4_args *args)
 {
        struct thread *td = curthread;
-       struct proc *p = td->td_proc;
+       struct lwp *lp = td->td_lwp;
        struct rusage rusage;
        int error, options, status;
 
-       KKASSERT(p);
+       KKASSERT(lp);
 
 #ifdef DEBUG
        if (ldebug(wait4))
@@ -818,7 +818,7 @@ sys_linux_wait4(struct linux_wait4_args *args)
            args->rusage ? &rusage : NULL, &args->sysmsg_result);
 
        if (error == 0)
-               SIGDELSET(p->p_siglist, SIGCHLD);
+               lwp_delsig(lp, SIGCHLD);
 
        if (error == 0 && args->status) {
                status &= 0xffff;
index b71abed..603a765 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
  * $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $
- * $DragonFly: src/sys/kern/kern_exit.c,v 1.73 2007/02/18 16:17:09 corecode Exp $
+ * $DragonFly: src/sys/kern/kern_exit.c,v 1.74 2007/02/21 15:46:48 corecode Exp $
  */
 
 #include "opt_compat.h"
@@ -174,6 +174,7 @@ exit1(int rv)
        p->p_flag &= ~(P_TRACED | P_PPWAIT);
        p->p_flag |= P_WEXIT;
        SIGEMPTYSET(p->p_siglist);
+       SIGEMPTYSET(lp->lwp_siglist);
        if (timevalisset(&p->p_realtimer.it_value))
                callout_stop(&p->p_ithandle);
 
index d43e5ee..0cc89b6 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)kern_sig.c  8.7 (Berkeley) 4/18/94
  * $FreeBSD: src/sys/kern/kern_sig.c,v 1.72.2.17 2003/05/16 16:34:34 obrien Exp $
- * $DragonFly: src/sys/kern/kern_sig.c,v 1.67 2007/02/21 15:45:36 corecode Exp $
+ * $DragonFly: src/sys/kern/kern_sig.c,v 1.68 2007/02/21 15:46:48 corecode Exp $
  */
 
 #include "opt_ktrace.h"
@@ -229,6 +229,7 @@ kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
+       struct lwp *lp;
        struct sigacts *ps = p->p_sigacts;
 
        if (sig <= 0 || sig > _SIG_MAXSIG)
@@ -336,6 +337,12 @@ kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact)
                     ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)) {
                        /* never to be seen again */
                        SIGDELSET(p->p_siglist, sig);
+                       /*
+                        * Remove the signal also from the thread lists.
+                        */
+                       FOREACH_LWP_IN_PROC(lp, p) {
+                               SIGDELSET(lp->lwp_siglist, sig);
+                       }
                        if (sig != SIGCONT)
                                /* easier in ksignal */
                                SIGADDSET(p->p_sigignore, sig);
@@ -398,6 +405,8 @@ execsigs(struct proc *p)
        struct lwp *lp;
        int sig;
 
+       lp = ONLY_LWP_IN_PROC(p);
+
        /*
         * Reset caught signals.  Held signals remain held
         * through p_sigmask (unless they were caught,
@@ -410,14 +419,15 @@ execsigs(struct proc *p)
                        if (sig != SIGCONT)
                                SIGADDSET(p->p_sigignore, sig);
                        SIGDELSET(p->p_siglist, sig);
+                       SIGDELSET(lp->lwp_siglist, sig);
                }
                ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
        }
+
        /*
         * Reset stack state to the user stack.
         * Clear set of signals caught on the signal stack.
         */
-       lp = ONLY_LWP_IN_PROC(p);
        lp->lwp_sigstk.ss_flags = SS_DISABLE;
        lp->lwp_sigstk.ss_size = 0;
        lp->lwp_sigstk.ss_sp = 0;
@@ -493,10 +503,9 @@ sys_sigprocmask(struct sigprocmask_args *uap)
 int
 kern_sigpending(struct __sigset *set)
 {
-       struct thread *td = curthread;
-       struct proc *p = td->td_proc;
+       struct lwp *lp = curthread->td_lwp;
 
-       *set = p->p_siglist;
+       *set = lwp_sigpend(lp);
 
        return (0);
 }
@@ -1156,7 +1165,7 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
        }
 
        for (;;) {
-               set = p->p_siglist;
+               set = lwp_sigpend(lp);
                SIGSETAND(set, waitset);
                if ((sig = sig_ffs(&set)) != 0) {
                        SIGFILLSET(lp->lwp_sigmask);
@@ -1223,7 +1232,7 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
                error = 0;
                bzero(info, sizeof(*info));
                info->si_signo = sig;
-               SIGDELSET(p->p_siglist, sig);   /* take the signal! */
+               lwp_delsig(lp, sig);    /* take the signal! */
 
                if (sig == SIGKILL)
                        sigexit(p, sig);
@@ -1333,7 +1342,7 @@ issignal(struct lwp *lp)
        for (;;) {
                int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG);
 
-               mask = p->p_siglist;
+               mask = lwp_sigpend(lp);
                SIGSETNAND(mask, lp->lwp_sigmask);
                if (p->p_flag & P_PPWAIT)
                        SIG_STOPSIGMASK(mask);
@@ -1350,7 +1359,7 @@ issignal(struct lwp *lp)
                 * only if P_TRACED was on when they were posted.
                 */
                if (SIGISMEMBER(p->p_sigignore, sig) && (traced == 0)) {
-                       SIGDELSET(p->p_siglist, sig);
+                       lwp_delsig(lp, sig);
                        continue;
                }
                if ((p->p_flag & P_TRACED) && (p->p_flag & P_PPWAIT) == 0) {
@@ -1376,7 +1385,7 @@ issignal(struct lwp *lp)
                         * then it will leave it in p->p_xstat;
                         * otherwise we just look for signals again.
                         */
-                       SIGDELSET(p->p_siglist, sig);   /* clear old signal */
+                       lwp_delsig(lp, sig);    /* clear old signal */
                        sig = p->p_xstat;
                        if (sig == 0)
                                continue;
@@ -1385,6 +1394,7 @@ issignal(struct lwp *lp)
                         * Put the new signal into p_siglist.  If the
                         * signal is being masked, look for other signals.
                         */
+                       /* XXX should run via ksignal? */
                        SIGADDSET(p->p_siglist, sig);
                        if (SIGISMEMBER(lp->lwp_sigmask, sig))
                                continue;
@@ -1480,7 +1490,7 @@ issignal(struct lwp *lp)
                        rel_mplock();
                        return (sig);
                }
-               SIGDELSET(p->p_siglist, sig);           /* take the signal! */
+               lwp_delsig(lp, sig);            /* take the signal! */
        }
        /* NOTREACHED */
 }
@@ -1512,7 +1522,7 @@ postsig(int sig)
                vkernel_trap(p, tf);
        }
 
-       SIGDELSET(p->p_siglist, sig);
+       lwp_delsig(lp, sig);
        action = ps->ps_sigact[_SIG_IDX(sig)];
 #ifdef KTRACE
        if (KTRPOINT(lp->lwp_thread, KTR_PSIG))
index c34d770..ab70494 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)tty.c       8.8 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/kern/tty.c,v 1.129.2.5 2002/03/11 01:32:31 dd Exp $
- * $DragonFly: src/sys/kern/tty.c,v 1.39 2007/02/18 16:15:23 corecode Exp $
+ * $DragonFly: src/sys/kern/tty.c,v 1.40 2007/02/21 15:46:48 corecode Exp $
  */
 
 /*-
@@ -1803,20 +1803,24 @@ out:
 int
 ttycheckoutq(struct tty *tp, int wait)
 {
+       struct lwp *lp = curthread->td_lwp;
        int hiwat;
-       sigset_t oldmask;
+       sigset_t oldset, newset;
 
        hiwat = tp->t_ohiwat;
-       SIGEMPTYSET(oldmask);
+       SIGEMPTYSET(oldset);
+       SIGEMPTYSET(newset);
        crit_enter();
        if (wait)
-               oldmask = curproc->p_siglist;
+               oldset = lwp_sigpend(lp);
        if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) {
                while (tp->t_outq.c_cc > hiwat) {
                        ttstart(tp);
                        if (tp->t_outq.c_cc <= hiwat)
                                break;
-                       if (!(wait && SIGSETEQ(curproc->p_siglist, oldmask))) {
+                       if (wait)
+                               newset = lwp_sigpend(lp);
+                       if (!wait || SIGSETNEQ(oldset, newset)) {
                                crit_exit();
                                return (0);
                        }
index dbd790a..a815e5c 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/netncp/ncp_ncp.c,v 1.3 1999/10/29 10:21:07 bp Exp $
- * $DragonFly: src/sys/netproto/ncp/ncp_ncp.c,v 1.11 2007/02/03 17:05:58 corecode Exp $
+ * $DragonFly: src/sys/netproto/ncp/ncp_ncp.c,v 1.12 2007/02/21 15:46:48 corecode Exp $
  *
  * Core of NCP protocol
  */
@@ -94,8 +94,7 @@ ncp_chkintr(struct ncp_conn *conn, struct thread *td)
 
        if (p == NULL)
                return 0;
-       tmpset = p->p_siglist;
-       SIGSETOR(tmpset, lp->lwp_siglist);
+       tmpset = lwp_sigpend(lp);
        SIGSETNAND(tmpset, lp->lwp_sigmask);
        SIGSETNAND(tmpset, p->p_sigignore);
        if (SIGNOTEMPTY(tmpset) && NCP_SIGMASK(tmpset))
index 4a84ea8..d45dc01 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/netsmb/smb_subr.c,v 1.1.2.2 2001/09/03 08:55:11 bp Exp $
- * $DragonFly: src/sys/netproto/smb/smb_subr.c,v 1.26 2007/02/03 17:05:58 corecode Exp $
+ * $DragonFly: src/sys/netproto/smb/smb_subr.c,v 1.27 2007/02/21 15:46:48 corecode Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -83,8 +83,7 @@ smb_proc_intr(struct thread *td)
        if (td == NULL || (p = td->td_proc) == NULL)
                return 0;
        lp = td->td_lwp;
-       tmpset = p->p_siglist;
-       SIGSETOR(tmpset, lp->lwp_siglist);
+       tmpset = lwp_sigpend(lp);
        SIGSETNAND(tmpset, lp->lwp_sigmask);
        SIGSETNAND(tmpset, p->p_sigignore);
        if (SIGNOTEMPTY(tmpset) && SMB_SIGMASK(tmpset))
index 2a0e663..58bd9ad 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)signalvar.h 8.6 (Berkeley) 2/19/95
  * $FreeBSD: src/sys/sys/signalvar.h,v 1.34.2.1 2000/05/16 06:58:05 dillon Exp $
- * $DragonFly: src/sys/sys/signalvar.h,v 1.18 2007/02/21 15:45:37 corecode Exp $
+ * $DragonFly: src/sys/sys/signalvar.h,v 1.19 2007/02/21 15:46:48 corecode Exp $
  */
 
 #ifndef        _SYS_SIGNALVAR_H_               /* tmp for user.h */
@@ -212,6 +212,29 @@ int        checkpoint_signal_handler(struct lwp *p);
 /*
  * Inline functions:
  */
+/*
+ * Determine which signals are pending for a lwp.
+ */
+static __inline sigset_t
+lwp_sigpend(struct lwp *lp)
+{
+       sigset_t set;
+
+       set = lp->lwp_proc->p_siglist;
+       SIGSETOR(set, lp->lwp_siglist);
+       return (set);
+}
+
+/*
+ * Mark a signal as handled by the lwp.
+ */
+static __inline void
+lwp_delsig(struct lwp *lp, int sig)
+{
+       SIGDELSET(lp->lwp_siglist, sig);
+       SIGDELSET(lp->lwp_proc->p_siglist, sig);
+}
+
 #define        CURSIG(lp)      __cursig(lp)
 #define CURSIGNB(lp)   __cursignb(lp)
 
@@ -231,8 +254,7 @@ __cursig(struct lwp *lp)
        int r;
 
        p = lp->lwp_proc;
-       tmpset = p->p_siglist;
-       SIGSETOR(tmpset, lp->lwp_siglist);
+       tmpset = lwp_sigpend(lp);
        SIGSETNAND(tmpset, lp->lwp_sigmask);
        if (!(p->p_flag & P_TRACED) && SIGISEMPTY(tmpset))
                return(0);
@@ -248,8 +270,7 @@ __cursignb(struct lwp *lp)
        sigset_t tmpset;
 
        p = lp->lwp_proc;
-       tmpset = p->p_siglist;
-       SIGSETOR(tmpset, lp->lwp_siglist);
+       tmpset = lwp_sigpend(lp);
        SIGSETNAND(tmpset, lp->lwp_sigmask);
        if ((!(p->p_flag & P_TRACED) && SIGISEMPTY(tmpset))) {
                return(FALSE);
index 6d12468..2306555 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)mfs_vfsops.c        8.11 (Berkeley) 6/19/95
  * $FreeBSD: src/sys/ufs/mfs/mfs_vfsops.c,v 1.81.2.3 2001/07/04 17:35:21 tegge Exp $
- * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.36 2007/02/03 17:05:59 corecode Exp $
+ * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.37 2007/02/21 15:46:48 corecode Exp $
  */
 
 
@@ -443,7 +443,7 @@ mfs_start(struct mount *mp, int flags)
                                KKASSERT(td->td_proc);
                                sig = CURSIG(td->td_lwp);
                                if (sig)
-                                       SIGDELSET(td->td_proc->p_siglist, sig);
+                                       lwp_delsig(td->td_lwp, sig);
                        }
                }
                else if (tsleep((caddr_t)mfsp, PCATCH, "mfsidl", 0))
index 241978f..5daac50 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_socket.c        8.5 (Berkeley) 3/30/95
  * $FreeBSD: src/sys/nfs/nfs_socket.c,v 1.60.2.6 2003/03/26 01:44:46 alfred Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_socket.c,v 1.40 2007/02/03 17:05:59 corecode Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_socket.c,v 1.41 2007/02/21 15:46:48 corecode Exp $
  */
 
 /*
@@ -1562,8 +1562,7 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
                return (0);
 
        lp = td->td_lwp;
-       tmpset = lp->lwp_siglist;
-       SIGSETOR(tmpset, p->p_siglist);
+       tmpset = lwp_sigpend(lp);
        SIGSETNAND(tmpset, lp->lwp_sigmask);
        SIGSETNAND(tmpset, p->p_sigignore);
        if (SIGNOTEMPTY(tmpset) && NFSINT_SIGMASK(tmpset))
index 59be5f1..3fbf81e 100644 (file)
@@ -38,7 +38,7 @@
  *
  * From:
  * $FreeBSD: src/sys/miscfs/procfs/procfs_ctl.c,v 1.20.2.2 2002/01/22 17:22:59 nectar Exp $
- * $DragonFly: src/sys/vfs/procfs/procfs_ctl.c,v 1.12 2007/02/19 01:14:24 corecode Exp $
+ * $DragonFly: src/sys/vfs/procfs/procfs_ctl.c,v 1.13 2007/02/21 15:46:48 corecode Exp $
  */
 
 #include <sys/param.h>
@@ -203,8 +203,7 @@ procfs_control(struct proc *curp, struct lwp *lp, int op)
                p->p_flag &= ~P_TRACED;
 
                /* remove pending SIGTRAP, else the process will die */
-               SIGDELSET(p->p_siglist, SIGTRAP);
-               SIGDELSET(lp->lwp_siglist, SIGTRAP);
+               lwp_delsig(lp, SIGTRAP);
 
                /* give process back to original parent */
                if (p->p_oppid != p->p_pptr->p_pid) {