From 4e3a26930218d35cf08d85d517f7552adc8cb07d Mon Sep 17 00:00:00 2001 From: Owain Ainsworth Date: Wed, 28 Nov 2007 20:07:37 +0000 Subject: Add msleep. This is identical to tsleep but it takes a mutex as a parameter. The mutex is unlocked just before sleep and relocked after unless P_NORELOCK is in flags, in which case it is left unlocked. ok art@. --- sys/kern/kern_synch.c | 39 ++++++++++++++++++++++++++++++++++++++- sys/sys/proc.h | 4 +++- 2 files changed, 41 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 8cd4a4285e1..209883c59b4 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.81 2007/10/10 15:53:53 art Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.82 2007/11/28 20:07:36 oga Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* @@ -136,6 +136,43 @@ tsleep(void *ident, int priority, const char *wmesg, int timo) return (error); } +/* + * Same as tsleep, but if we have a mutex provided, then once we've + * entered the sleep queue we drop the mutex. After sleeping we re-lock. + */ +int +msleep(void *ident, struct mutex *mtx, int priority, const char *wmesg, int timo) +{ + struct sleep_state sls; + int error, error1; + + sleep_setup(&sls, ident, priority, wmesg); + sleep_setup_timeout(&sls, timo); + sleep_setup_signal(&sls, priority); + + if (mtx) { + /* XXX - We need to make sure that the mutex doesn't + * unblock splsched. This can be made a bit more + * correct when the sched_lock is a mutex. + */ + MUTEX_OLDIPL(mtx) = splsched(); + mtx_leave(mtx); + } + + sleep_finish(&sls, 1); + error1 = sleep_finish_timeout(&sls); + error = sleep_finish_signal(&sls); + + if (mtx && (priority & PNORELOCK) == 0) + mtx_enter(mtx); + + /* Signal errors are higher priority than timeouts. */ + if (error == 0 && error1 != 0) + error = error1; + + return (error); +} + void sleep_setup(struct sleep_state *sls, void *ident, int prio, const char *wmesg) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index a4d4a12fa62..29389bb5e6a 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.101 2007/10/10 15:53:53 art Exp $ */ +/* $OpenBSD: proc.h,v 1.102 2007/11/28 20:07:36 oga Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -45,6 +45,7 @@ #include #include /* For struct timeout. */ #include /* For struct klist */ +#include /* For struct mutex */ #include #define curproc curcpu()->ci_curproc @@ -454,6 +455,7 @@ int sleep_finish_signal(struct sleep_state *); void sleep_queue_init(void); int tsleep(void *, int, const char *, int); +int msleep(void *, struct mutex *, int, const char*, int); #define ltsleep(c, p, w, t, l) tsleep(c, p, w, t) #if defined(MULTIPROCESSOR) -- cgit v1.2.3