diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-08-07 22:57:16 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-08-07 22:57:16 +0000 |
commit | 4f88a0c9663039f11796f655f37fbadef8132949 (patch) | |
tree | cfc9bd25537c4c8bd52662cd713c4d1273c95c10 | |
parent | 554ced2812aefc9196d6374d548a3d0b91cd4526 (diff) |
Change tsleep into ltsleep.
ltsleep takes an additional argument - a simplelock and unlocks it when it's
safe to do so.
tsleep now becomes a wrapper around ltsleep.
From NetBSD
-rw-r--r-- | sys/kern/kern_synch.c | 39 | ||||
-rw-r--r-- | sys/sys/param.h | 8 | ||||
-rw-r--r-- | sys/sys/proc.h | 8 |
3 files changed, 44 insertions, 11 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 6777e6cb93e..ab0ada25e05 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.36 2001/06/27 04:49:45 art Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.37 2001/08/07 22:57:15 art Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /*- @@ -336,17 +336,24 @@ int safepri; * signal needs to be delivered, ERESTART is returned if the current system * call should be restarted if possible, and EINTR is returned if the system * call should be interrupted by the signal (return EINTR). + * + * The interlock is held until the scheduler_slock (XXX) is held. The + * interlock will be locked before returning back to the caller + * unless the PNORELOCK flag is specified, in which case the + * interlock will always be unlocked upon return. */ int -tsleep(ident, priority, wmesg, timo) +ltsleep(ident, priority, wmesg, timo, interlock) void *ident; int priority, timo; char *wmesg; + volatile struct simplelock *interlock; { - register struct proc *p = curproc; - register struct slpque *qp; - register int s; - int sig, catch = priority & PCATCH; + struct proc *p = curproc; + struct slpque *qp; + int s, sig; + int catch = priority & PCATCH; + int relock = (priority & PNORELOCK) == 0; #ifdef KTRACE if (KTRPOINT(p, KTR_CSW)) @@ -362,6 +369,8 @@ tsleep(ident, priority, wmesg, timo) */ splx(safepri); splx(s); + if (interlock != NULL && relock == 0) + simple_unlock(interlock); return (0); } #ifdef DIAGNOSTIC @@ -381,6 +390,18 @@ tsleep(ident, priority, wmesg, timo) if (timo) timeout_add(&p->p_sleep_to, timo); /* + * We can now release the interlock; the scheduler_slock + * is held, so a thread can't get in to do wakeup() before + * we do the switch. + * + * XXX We leave the code block here, after inserting ourselves + * on the sleep queue, because we might want a more clever + * data structure for the sleep queues at some point. + */ + if (interlock != NULL) + simple_unlock(interlock); + + /* * We put ourselves on the sleep queue and start our timeout * before calling CURSIG, as we could stop there, and a wakeup * or a SIGCONT (or both) could occur while we were stopped. @@ -421,6 +442,8 @@ resume: if (KTRPOINT(p, KTR_CSW)) ktrcsw(p, 0, 0); #endif + if (interlock != NULL && relock) + simple_lock(interlock); return (EWOULDBLOCK); } } else if (timo) @@ -430,6 +453,8 @@ resume: if (KTRPOINT(p, KTR_CSW)) ktrcsw(p, 0, 0); #endif + if (interlock != NULL && relock) + simple_lock(interlock); if (p->p_sigacts->ps_sigintr & sigmask(sig)) return (EINTR); return (ERESTART); @@ -438,6 +463,8 @@ resume: if (KTRPOINT(p, KTR_CSW)) ktrcsw(p, 0, 0); #endif + if (interlock != NULL && relock) + simple_lock(interlock); return (0); } diff --git a/sys/sys/param.h b/sys/sys/param.h index a13dc877ee4..7856b5e9591 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -1,4 +1,4 @@ -/* $OpenBSD: param.h,v 1.39 2001/07/26 20:40:11 millert Exp $ */ +/* $OpenBSD: param.h,v 1.40 2001/08/07 22:57:15 art Exp $ */ /* $NetBSD: param.h,v 1.23 1996/03/17 01:02:29 thorpej Exp $ */ /*- @@ -115,8 +115,10 @@ #define PUSER 50 #define MAXPRI 127 /* Priorities range from 0 through MAXPRI. */ -#define PRIMASK 0x0ff -#define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ +#define PRIMASK 0x0ff +#define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ +#define PNORELOCK 0x200 /* OR'd with pri for ltsleep to not relock + the interlock */ #define NBPW sizeof(int) /* number of bytes per word (integer) */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index e7a8c19b2c8..39a69ad5439 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.46 2001/08/02 11:06:38 art Exp $ */ +/* $OpenBSD: proc.h,v 1.47 2001/08/07 22:57:15 art Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -346,6 +346,8 @@ struct prochd { struct proc *ph_rlink; } qs[NQS]; +struct simplelock; + struct proc *pfind __P((pid_t)); /* Find process by id. */ struct pgrp *pgfind __P((pid_t)); /* Find process group by id. */ @@ -365,7 +367,9 @@ void setrunnable __P((struct proc *)); void setrunqueue __P((struct proc *)); void sleep __P((void *chan, int pri)); void uvm_swapin __P((struct proc *)); /* XXX: uvm_extern.h? */ -int tsleep __P((void *chan, int pri, char *wmesg, int timo)); +int ltsleep __P((void *chan, int pri, char *wmesg, int timo, + volatile struct simplelock *)); +#define tsleep(chan, pri, wmesg, timo) ltsleep(chan, pri, wmesg, timo, NULL) void unsleep __P((struct proc *)); void wakeup_n __P((void *chan, int)); void wakeup __P((void *chan)); |