diff options
-rw-r--r-- | sys/kern/kern_synch.c | 39 | ||||
-rw-r--r-- | sys/sys/proc.h | 4 |
2 files changed, 41 insertions, 2 deletions
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 <sys/queue.h> #include <sys/timeout.h> /* For struct timeout. */ #include <sys/event.h> /* For struct klist */ +#include <sys/mutex.h> /* For struct mutex */ #include <machine/atomic.h> #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) |