summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2001-08-07 22:57:16 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2001-08-07 22:57:16 +0000
commit4f88a0c9663039f11796f655f37fbadef8132949 (patch)
treecfc9bd25537c4c8bd52662cd713c4d1273c95c10
parent554ced2812aefc9196d6374d548a3d0b91cd4526 (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.c39
-rw-r--r--sys/sys/param.h8
-rw-r--r--sys/sys/proc.h8
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));