1 /* $NetBSD: ltsleep.c,v 1.11 2009/03/18 10:22:44 cegger Exp $ */ 2 3 /* 4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved. 5 * 6 * Development of this software was supported by the 7 * Finnish Cultural Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.11 2009/03/18 10:22:44 cegger Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/proc.h> 36 #include <sys/queue.h> 37 #include <sys/simplelock.h> 38 39 #include <rump/rumpuser.h> 40 41 #include "rump_private.h" 42 43 struct ltsleeper { 44 wchan_t id; 45 kcondvar_t cv; 46 LIST_ENTRY(ltsleeper) entries; 47 }; 48 49 static LIST_HEAD(, ltsleeper) sleepers = LIST_HEAD_INITIALIZER(sleepers); 50 static kmutex_t sleepermtx; 51 52 kcondvar_t lbolt; /* Oh Kath Ra */ 53 54 int 55 ltsleep(wchan_t ident, pri_t prio, const char *wmesg, int timo, 56 volatile struct simplelock *slock) 57 { 58 struct ltsleeper lts; 59 60 if (__predict_false(slock)) 61 panic("simplelock not supported by rump, convert code"); 62 63 lts.id = ident; 64 cv_init(<s.cv, NULL); 65 66 mutex_enter(&sleepermtx); 67 LIST_INSERT_HEAD(&sleepers, <s, entries); 68 69 /* protected by sleepermtx */ 70 cv_wait(<s.cv, &sleepermtx); 71 72 LIST_REMOVE(<s, entries); 73 mutex_exit(&sleepermtx); 74 75 cv_destroy(<s.cv); 76 77 return 0; 78 } 79 80 int 81 mtsleep(wchan_t ident, pri_t prio, const char *wmesg, int timo, 82 kmutex_t *lock) 83 { 84 struct ltsleeper lts; 85 86 lts.id = ident; 87 cv_init(<s.cv, NULL); 88 89 mutex_enter(&sleepermtx); 90 LIST_INSERT_HEAD(&sleepers, <s, entries); 91 92 /* protected by sleepermtx */ 93 mutex_exit(lock); 94 cv_wait(<s.cv, &sleepermtx); 95 96 LIST_REMOVE(<s, entries); 97 mutex_exit(&sleepermtx); 98 99 cv_destroy(<s.cv); 100 101 if ((prio & PNORELOCK) == 0) 102 mutex_enter(lock); 103 104 return 0; 105 } 106 107 void 108 wakeup(wchan_t ident) 109 { 110 struct ltsleeper *ltsp; 111 112 mutex_enter(&sleepermtx); 113 LIST_FOREACH(ltsp, &sleepers, entries) 114 if (ltsp->id == ident) 115 cv_signal(<sp->cv); 116 mutex_exit(&sleepermtx); 117 } 118 119 void 120 rump_sleepers_init(void) 121 { 122 123 mutex_init(&sleepermtx, MUTEX_DEFAULT, 0); 124 } 125