ltsleep.c revision 1.19 1 /* $NetBSD: ltsleep.c,v 1.19 2009/10/15 00:28:46 pooka 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.19 2009/10/15 00:28:46 pooka 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 struct rumpuser_cv *cv;
46 LIST_ENTRY(ltsleeper) entries;
47 };
48
49 static LIST_HEAD(, ltsleeper) sleepers = LIST_HEAD_INITIALIZER(sleepers);
50
51 kcondvar_t lbolt; /* Oh Kath Ra */
52
53 int
54 ltsleep(wchan_t ident, pri_t prio, const char *wmesg, int timo,
55 volatile struct simplelock *slock)
56 {
57 struct ltsleeper lts;
58 int nlocks;
59
60 lts.id = ident;
61 rumpuser_cv_init(<s.cv);
62
63 if (slock)
64 simple_unlock(slock);
65 LIST_INSERT_HEAD(&sleepers, <s, entries);
66 kernel_unlock_allbutone(&nlocks);
67
68 /* protected by biglock */
69 rumpuser_cv_wait(lts.cv, rump_giantlock);
70
71 LIST_REMOVE(<s, entries);
72 rumpuser_cv_destroy(lts.cv);
73 kernel_ununlock_allbutone(nlocks);
74
75 if (slock && (prio & PNORELOCK) == 0)
76 simple_lock(slock);
77
78 return 0;
79 }
80
81 int
82 mtsleep(wchan_t ident, pri_t prio, const char *wmesg, int timo,
83 kmutex_t *lock)
84 {
85 struct ltsleeper lts;
86 int nlocks;
87
88 lts.id = ident;
89 rumpuser_cv_init(<s.cv);
90
91 mutex_exit(lock);
92 LIST_INSERT_HEAD(&sleepers, <s, entries);
93 kernel_unlock_allbutone(&nlocks);
94
95 /* protected by biglock */
96 rumpuser_cv_wait(lts.cv, rump_giantlock);
97
98 LIST_REMOVE(<s, entries);
99 rumpuser_cv_destroy(lts.cv);
100 kernel_ununlock_allbutone(nlocks);
101
102 if ((prio & PNORELOCK) == 0)
103 mutex_enter(lock);
104
105 return 0;
106 }
107
108 static void
109 do_wakeup(wchan_t ident, void (*wakeupfn)(struct rumpuser_cv *))
110 {
111 struct ltsleeper *ltsp;
112
113 KASSERT(kernel_biglocked());
114 LIST_FOREACH(ltsp, &sleepers, entries) {
115 if (ltsp->id == ident) {
116 wakeupfn(ltsp->cv);
117 }
118 }
119 }
120
121 void
122 wakeup(wchan_t ident)
123 {
124
125 do_wakeup(ident, rumpuser_cv_broadcast);
126 }
127
128 void
129 wakeup_one(wchan_t ident)
130 {
131
132 do_wakeup(ident, rumpuser_cv_signal);
133 }
134
135 void
136 rump_sleepers_init(void)
137 {
138
139 }
140