diff options
author | julian <julian@FreeBSD.org> | 2001-09-12 08:38:13 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 2001-09-12 08:38:13 +0000 |
commit | 5596676e6c6c1e81e899cd0531f9b1c28a292669 (patch) | |
tree | b1a19fcdf05759281fab0d89efb13f0fdf42102e /sys/kern/kern_sig.c | |
parent | 83e00d4274950d2b531c24692cd123538ffbddb9 (diff) | |
download | FreeBSD-src-5596676e6c6c1e81e899cd0531f9b1c28a292669.zip FreeBSD-src-5596676e6c6c1e81e899cd0531f9b1c28a292669.tar.gz |
KSE Milestone 2
Note ALL MODULES MUST BE RECOMPILED
make the kernel aware that there are smaller units of scheduling than the
process. (but only allow one thread per process at this time).
This is functionally equivalent to teh previousl -current except
that there is a thread associated with each process.
Sorry john! (your next MFC will be a doosie!)
Reviewed by: peter@freebsd.org, dillon@freebsd.org
X-MFC after: ha ha ha ha
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r-- | sys/kern/kern_sig.c | 244 |
1 files changed, 166 insertions, 78 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 607c78c..233bdbe 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -74,7 +74,7 @@ #define ONSIG 32 /* NSIG for osig* syscalls. XXX. */ -static int coredump __P((struct proc *)); +static int coredump __P((struct thread *)); static int do_sigaction __P((struct proc *p, int sig, struct sigaction *act, struct sigaction *oact, int old)); static int do_sigprocmask __P((struct proc *p, int how, sigset_t *set, @@ -351,10 +351,11 @@ struct sigaction_args { */ /* ARGSUSED */ int -sigaction(p, uap) - struct proc *p; +sigaction(td, uap) + struct thread *td; register struct sigaction_args *uap; { + struct proc *p = td->td_proc; struct sigaction act, oact; register struct sigaction *actp, *oactp; int error; @@ -390,10 +391,11 @@ struct osigaction_args { */ /* ARGSUSED */ int -osigaction(p, uap) - struct proc *p; +osigaction(td, uap) + struct thread *td; register struct osigaction_args *uap; { + struct proc *p = td->td_proc; struct osigaction sa; struct sigaction nsa, osa; register struct sigaction *nsap, *osap; @@ -534,7 +536,7 @@ do_sigprocmask(p, how, set, oset, old) } /* - * sigprocmask() - MP SAFE + * sigprocmask() - MP SAFE (XXXKSE not under KSE it isn't) */ #ifndef _SYS_SYSPROTO_H_ @@ -545,10 +547,11 @@ struct sigprocmask_args { }; #endif int -sigprocmask(p, uap) - register struct proc *p; +sigprocmask(td, uap) + register struct thread *td; struct sigprocmask_args *uap; { + struct proc *p = td->td_proc; sigset_t set, oset; sigset_t *setp, *osetp; int error; @@ -578,16 +581,17 @@ struct osigprocmask_args { }; #endif int -osigprocmask(p, uap) - register struct proc *p; +osigprocmask(td, uap) + register struct thread *td; struct osigprocmask_args *uap; { + struct proc *p = td->td_proc; sigset_t set, oset; int error; OSIG2SIG(uap->mask, set); error = do_sigprocmask(p, uap->how, &set, &oset, 1); - SIG2OSIG(oset, p->p_retval[0]); + SIG2OSIG(oset, td->td_retval[0]); return (error); } #endif /* COMPAT_43 */ @@ -602,10 +606,11 @@ struct sigpending_args { */ /* ARGSUSED */ int -sigpending(p, uap) - struct proc *p; +sigpending(td, uap) + struct thread *td; struct sigpending_args *uap; { + struct proc *p = td->td_proc; sigset_t siglist; int error; @@ -629,13 +634,15 @@ struct osigpending_args { */ /* ARGSUSED */ int -osigpending(p, uap) - struct proc *p; +osigpending(td, uap) + struct thread *td; struct osigpending_args *uap; { + struct proc *p = td->td_proc; + mtx_lock(&Giant); PROC_LOCK(p); - SIG2OSIG(p->p_siglist, p->p_retval[0]); + SIG2OSIG(p->p_siglist, td->td_retval[0]); PROC_UNLOCK(p); mtx_unlock(&Giant); return (0); @@ -658,10 +665,11 @@ struct osigvec_args { */ /* ARGSUSED */ int -osigvec(p, uap) - struct proc *p; +osigvec(td, uap) + struct thread *td; register struct osigvec_args *uap; { + struct proc *p = td->td_proc; struct sigvec vec; struct sigaction nsa, osa; register struct sigaction *nsap, *osap; @@ -709,17 +717,18 @@ struct osigblock_args { * MPSAFE */ int -osigblock(p, uap) - register struct proc *p; +osigblock(td, uap) + register struct thread *td; struct osigblock_args *uap; { + struct proc *p = td->td_proc; sigset_t set; OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); mtx_lock(&Giant); PROC_LOCK(p); - SIG2OSIG(p->p_sigmask, p->p_retval[0]); + SIG2OSIG(p->p_sigmask, td->td_retval[0]); SIGSETOR(p->p_sigmask, set); PROC_UNLOCK(p); mtx_unlock(&Giant); @@ -735,17 +744,18 @@ struct osigsetmask_args { * MPSAFE */ int -osigsetmask(p, uap) - struct proc *p; +osigsetmask(td, uap) + struct thread *td; struct osigsetmask_args *uap; { + struct proc *p = td->td_proc; sigset_t set; OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); mtx_lock(&Giant); PROC_LOCK(p); - SIG2OSIG(p->p_sigmask, p->p_retval[0]); + SIG2OSIG(p->p_sigmask, td->td_retval[0]); SIGSETLO(p->p_sigmask, set); PROC_UNLOCK(p); mtx_unlock(&Giant); @@ -757,6 +767,9 @@ osigsetmask(p, uap) * Suspend process until signal, providing mask to be set * in the meantime. Note nonstandard calling convention: * libc stub passes mask, not pointer, to save a copyin. + ***** XXXKSE this doesn't make sense under KSE. + ***** Do we suspend the thread or all threads in the process? + ***** How do we suspend threads running NOW on another processor? */ #ifndef _SYS_SYSPROTO_H_ struct sigsuspend_args { @@ -768,10 +781,11 @@ struct sigsuspend_args { */ /* ARGSUSED */ int -sigsuspend(p, uap) - register struct proc *p; +sigsuspend(td, uap) + struct thread *td; struct sigsuspend_args *uap; { + struct proc *p = td->td_proc; sigset_t mask; register struct sigacts *ps; int error; @@ -814,10 +828,11 @@ struct osigsuspend_args { */ /* ARGSUSED */ int -osigsuspend(p, uap) - register struct proc *p; +osigsuspend(td, uap) + struct thread *td; struct osigsuspend_args *uap; { + struct proc *p = td->td_proc; sigset_t mask; register struct sigacts *ps; @@ -850,10 +865,11 @@ struct osigstack_args { */ /* ARGSUSED */ int -osigstack(p, uap) - struct proc *p; +osigstack(td, uap) + struct thread *td; register struct osigstack_args *uap; { + struct proc *p = td->td_proc; struct sigstack ss; int error = 0; @@ -862,7 +878,7 @@ osigstack(p, uap) if (uap->oss != NULL) { PROC_LOCK(p); ss.ss_sp = p->p_sigstk.ss_sp; - ss.ss_onstack = sigonstack(cpu_getstack(p)); + ss.ss_onstack = sigonstack(cpu_getstack(td)); PROC_UNLOCK(p); error = copyout(&ss, uap->oss, sizeof(struct sigstack)); if (error) @@ -896,17 +912,18 @@ struct sigaltstack_args { */ /* ARGSUSED */ int -sigaltstack(p, uap) - struct proc *p; +sigaltstack(td, uap) + struct thread *td; register struct sigaltstack_args *uap; { + struct proc *p = td->td_proc; stack_t ss; int oonstack; int error = 0; mtx_lock(&Giant); - oonstack = sigonstack(cpu_getstack(p)); + oonstack = sigonstack(cpu_getstack(td)); if (uap->oss != NULL) { PROC_LOCK(p); @@ -1027,10 +1044,11 @@ struct kill_args { */ /* ARGSUSED */ int -kill(cp, uap) - register struct proc *cp; +kill(td, uap) + register struct thread *td; register struct kill_args *uap; { + register struct proc *cp = td->td_proc; register struct proc *p; int error = 0; @@ -1080,8 +1098,8 @@ struct okillpg_args { */ /* ARGSUSED */ int -okillpg(p, uap) - struct proc *p; +okillpg(td, uap) + struct thread *td; register struct okillpg_args *uap; { int error; @@ -1089,7 +1107,7 @@ okillpg(p, uap) if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); mtx_lock(&Giant); - error = killpg1(p, uap->signum, uap->pgid, 0); + error = killpg1(td->td_proc, uap->signum, uap->pgid, 0); mtx_unlock(&Giant); return (error); } @@ -1198,6 +1216,8 @@ psignal(p, sig) { register int prop; register sig_t action; + struct thread *td; + struct ksegrp *kg; if (sig > _SIG_MAXSIG || sig <= 0) { printf("psignal: signal %d\n", sig); @@ -1214,9 +1234,9 @@ psignal(p, sig) * if signal event is tracked by procfs, give *that* * a chance, as well. */ - if ((p->p_flag & P_TRACED) || (p->p_stops & S_SIG)) + if ((p->p_flag & P_TRACED) || (p->p_stops & S_SIG)) { action = SIG_DFL; - else { + } else { /* * If the signal is being ignored, * then we forget about it immediately. @@ -1234,10 +1254,27 @@ psignal(p, sig) action = SIG_DFL; } + /* + * bring the priority of a process up if we want it to get + * killed in this lifetime. + * XXXKSE think if a better way to do this. + * + * What we need to do is see if there is a thread that will + * be able to accept the signal. e.g. + * FOREACH_THREAD_IN_PROC() { + * if runnable, we're done + * else pick one at random. + * } + */ + /* XXXKSE + * For now there is one thread per proc. + * Effectively select one sucker thread.. + */ + td = &p->p_thread; mtx_lock_spin(&sched_lock); - if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) && - (p->p_flag & P_TRACED) == 0) - p->p_nice = NZERO; + if ((p->p_ksegrp.kg_nice > NZERO) && (action == SIG_DFL) && + (prop & SA_KILL) && ((p->p_flag & P_TRACED) == 0)) + p->p_ksegrp.kg_nice = NZERO; /* XXXKSE */ mtx_unlock_spin(&sched_lock); if (prop & SA_CONT) @@ -1266,6 +1303,7 @@ psignal(p, sig) mtx_unlock_spin(&sched_lock); return; } + switch (p->p_stat) { case SSLEEP: @@ -1275,7 +1313,7 @@ psignal(p, sig) * be noticed when the process returns through * trap() or syscall(). */ - if ((p->p_sflag & PS_SINTR) == 0) { + if ((td->td_flags & TDF_SINTR) == 0) { mtx_unlock_spin(&sched_lock); goto out; } @@ -1357,11 +1395,28 @@ psignal(p, sig) if (action == SIG_CATCH) goto runfast; mtx_lock_spin(&sched_lock); - if (p->p_wchan == NULL) - goto run; - p->p_stat = SSLEEP; - mtx_unlock_spin(&sched_lock); - goto out; + /* + * XXXKSE + * do this for each thread. + */ + if (p->p_flag & P_KSES) { + mtx_assert(&sched_lock, + MA_OWNED | MA_NOTRECURSED); + FOREACH_THREAD_IN_PROC(p, td) { + if (td->td_wchan == NULL) { + setrunnable(td); /* XXXKSE */ + } else { + /* mark it as sleeping */ + } + } + mtx_unlock_spin(&sched_lock); + goto out; + } else { + if (p->p_thread.td_wchan == NULL) + goto run; + p->p_stat = SSLEEP; + mtx_unlock_spin(&sched_lock); + } } if (prop & SA_STOP) { @@ -1378,13 +1433,25 @@ psignal(p, sig) * wakeup so that when it is continued, it will be made * runnable and can look at the signal. But don't make * the process runnable, leave it stopped. + * XXXKSE should we wake ALL blocked threads? */ mtx_lock_spin(&sched_lock); - if (p->p_wchan && p->p_sflag & PS_SINTR) { - if (p->p_sflag & PS_CVWAITQ) - cv_waitq_remove(p); - else - unsleep(p); + if (p->p_flag & P_KSES) { + FOREACH_THREAD_IN_PROC(p, td) { + if (td->td_wchan && (td->td_flags & TDF_SINTR)){ + if (td->td_flags & TDF_CVWAITQ) + cv_waitq_remove(td); + else + unsleep(td); /* XXXKSE */ + } + } + } else { + if (td->td_wchan && td->td_flags & TDF_SINTR) { + if (td->td_flags & TDF_CVWAITQ) + cv_waitq_remove(td); + else + unsleep(td); /* XXXKSE */ + } } mtx_unlock_spin(&sched_lock); goto out; @@ -1396,9 +1463,21 @@ psignal(p, sig) * It will either never be noticed, or noticed very soon. */ if (p->p_stat == SRUN) { - signotify(p); #ifdef SMP - forward_signal(p); + struct kse *ke; + struct thread *td = curthread; + signotify(&p->p_kse); /* XXXKSE */ +/* we should only deliver to one thread.. but which one? */ + FOREACH_KSEGRP_IN_PROC(p, kg) { + FOREACH_KSE_IN_GROUP(kg, ke) { + if (ke->ke_thread == td) { + continue; + } + forward_signal(ke->ke_thread); + } + } +#else + signotify(&p->p_kse); /* XXXKSE */ #endif } mtx_unlock_spin(&sched_lock); @@ -1409,14 +1488,19 @@ psignal(p, sig) runfast: /* * Raise priority to at least PUSER. + * XXXKSE Should we make them all run fast? + * Maybe just one would be enough? */ mtx_lock_spin(&sched_lock); - if (p->p_pri.pri_level > PUSER) - p->p_pri.pri_level = PUSER; + FOREACH_KSEGRP_IN_PROC(p, kg) { + if (kg->kg_pri.pri_level > PUSER) { + kg->kg_pri.pri_level = PUSER; + } + } run: /* If we jump here, sched_lock has to be owned. */ mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); - setrunnable(p); + setrunnable(td); /* XXXKSE */ mtx_unlock_spin(&sched_lock); out: /* If we jump here, sched_lock should not be owned. */ @@ -1623,7 +1707,8 @@ void postsig(sig) register int sig; { - register struct proc *p = curproc; + struct thread *td = curthread; + register struct proc *p = td->td_proc; struct sigacts *ps; sig_t action; sigset_t returnmask; @@ -1647,7 +1732,7 @@ postsig(sig) * Default action, where the default is to kill * the process. (Other cases were ignored above.) */ - sigexit(p, sig); + sigexit(td, sig); /* NOTREACHED */ } else { /* @@ -1722,10 +1807,11 @@ killproc(p, why) * does not return. */ void -sigexit(p, sig) - register struct proc *p; +sigexit(td, sig) + struct thread *td; int sig; { + struct proc *p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); p->p_acflag |= AXSIG; @@ -1740,7 +1826,7 @@ sigexit(p, sig) PROC_UNLOCK(p); if (!mtx_owned(&Giant)) mtx_lock(&Giant); - if (coredump(p) == 0) + if (coredump(td) == 0) sig |= WCOREFLAG; if (kern_logsigexit) log(LOG_INFO, @@ -1754,7 +1840,7 @@ sigexit(p, sig) if (!mtx_owned(&Giant)) mtx_lock(&Giant); } - exit1(p, W_EXITCODE(0, sig)); + exit1(td, W_EXITCODE(0, sig)); /* NOTREACHED */ } @@ -1849,9 +1935,9 @@ const char *name; uid_t uid; pid_t pid; { */ static int -coredump(p) - register struct proc *p; +coredump(struct thread *td) { + struct proc *p = td->td_proc; register struct vnode *vp; register struct ucred *cred = p->p_ucred; struct flock lf; @@ -1889,7 +1975,7 @@ restart: name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid); if (name == NULL) return (EINVAL); - NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p); + NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); /* XXXKSE */ flags = O_CREAT | FWRITE | O_NOFOLLOW; error = vn_open(&nd, &flags, S_IRUSR | S_IWUSR); free(name, M_TEMP); @@ -1898,7 +1984,7 @@ restart: NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp, 0, td); lf.l_whence = SEEK_SET; lf.l_start = 0; lf.l_len = 0; @@ -1910,7 +1996,7 @@ restart: if (vn_start_write(vp, &mp, V_NOWAIT) != 0) { lf.l_type = F_UNLCK; VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK); - if ((error = vn_close(vp, FWRITE, cred, p)) != 0) + if ((error = vn_close(vp, FWRITE, cred, td)) != 0) return (error); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); @@ -1919,20 +2005,20 @@ restart: /* Don't dump to non-regular files or files with links. */ if (vp->v_type != VREG || - VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) { + VOP_GETATTR(vp, &vattr, cred, td) || vattr.va_nlink != 1) { error = EFAULT; goto out1; } VATTR_NULL(&vattr); vattr.va_size = 0; - VOP_LEASE(vp, p, cred, LEASE_WRITE); - VOP_SETATTR(vp, &vattr, cred, p); + VOP_LEASE(vp, td, cred, LEASE_WRITE); + VOP_SETATTR(vp, &vattr, cred, td); PROC_LOCK(p); p->p_acflag |= ACORE; PROC_UNLOCK(p); error = p->p_sysent->sv_coredump ? - p->p_sysent->sv_coredump(p, vp, limit) : + p->p_sysent->sv_coredump(td, vp, limit) : ENOSYS; out1: @@ -1940,7 +2026,7 @@ out1: VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK); vn_finished_write(mp); out2: - error1 = vn_close(vp, FWRITE, cred, p); + error1 = vn_close(vp, FWRITE, cred, td); if (error == 0) error = error1; return (error); @@ -1960,10 +2046,12 @@ struct nosys_args { */ /* ARGSUSED */ int -nosys(p, args) - struct proc *p; +nosys(td, args) + struct thread *td; struct nosys_args *args; { + struct proc *p = td->td_proc; + mtx_lock(&Giant); PROC_LOCK(p); psignal(p, SIGSYS); |