LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build darwin netbsd openbsd plan9 windows | 5 // +build darwin netbsd openbsd plan9 windows |
6 | 6 |
7 #include "runtime.h" | 7 #include "runtime.h" |
8 | 8 |
9 // This implementation depends on OS-specific implementations of | 9 // This implementation depends on OS-specific implementations of |
10 // | 10 // |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 runtime·notesleep(Note *n) | 147 runtime·notesleep(Note *n) |
148 { | 148 { |
149 if(m->waitsema == 0) | 149 if(m->waitsema == 0) |
150 m->waitsema = runtime·semacreate(); | 150 m->waitsema = runtime·semacreate(); |
151 if(!runtime·casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup) | 151 if(!runtime·casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup) |
152 if(n->waitm != (void*)LOCKED) | 152 if(n->waitm != (void*)LOCKED) |
153 runtime·throw("notesleep - waitm out of sync"); | 153 runtime·throw("notesleep - waitm out of sync"); |
154 return; | 154 return; |
155 } | 155 } |
156 // Queued. Sleep. | 156 // Queued. Sleep. |
| 157 if(m->profilehz > 0) |
| 158 runtime·setprof(false); |
157 runtime·semasleep(-1); | 159 runtime·semasleep(-1); |
| 160 if(m->profilehz > 0) |
| 161 runtime·setprof(true); |
158 } | 162 } |
159 | 163 |
160 void | 164 void |
161 runtime·notetsleep(Note *n, int64 ns) | 165 runtime·notetsleep(Note *n, int64 ns) |
162 { | 166 { |
163 M *mp; | 167 M *mp; |
164 int64 deadline, now; | 168 int64 deadline, now; |
165 | 169 |
166 if(ns < 0) { | 170 if(ns < 0) { |
167 runtime·notesleep(n); | 171 runtime·notesleep(n); |
168 return; | 172 return; |
169 } | 173 } |
170 | 174 |
171 if(m->waitsema == 0) | 175 if(m->waitsema == 0) |
172 m->waitsema = runtime·semacreate(); | 176 m->waitsema = runtime·semacreate(); |
173 | 177 |
174 // Register for wakeup on n->waitm. | 178 // Register for wakeup on n->waitm. |
175 if(!runtime·casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup al
ready) | 179 if(!runtime·casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup al
ready) |
176 if(n->waitm != (void*)LOCKED) | 180 if(n->waitm != (void*)LOCKED) |
177 runtime·throw("notetsleep - waitm out of sync"); | 181 runtime·throw("notetsleep - waitm out of sync"); |
178 return; | 182 return; |
179 } | 183 } |
180 | 184 |
| 185 if(m->profilehz > 0) |
| 186 runtime·setprof(false); |
181 deadline = runtime·nanotime() + ns; | 187 deadline = runtime·nanotime() + ns; |
182 for(;;) { | 188 for(;;) { |
183 // Registered. Sleep. | 189 // Registered. Sleep. |
184 if(runtime·semasleep(ns) >= 0) { | 190 if(runtime·semasleep(ns) >= 0) { |
185 // Acquired semaphore, semawakeup unregistered us. | 191 // Acquired semaphore, semawakeup unregistered us. |
186 // Done. | 192 // Done. |
| 193 if(m->profilehz > 0) |
| 194 runtime·setprof(true); |
187 return; | 195 return; |
188 } | 196 } |
189 | 197 |
190 // Interrupted or timed out. Still registered. Semaphore not a
cquired. | 198 // Interrupted or timed out. Still registered. Semaphore not a
cquired. |
191 now = runtime·nanotime(); | 199 now = runtime·nanotime(); |
192 if(now >= deadline) | 200 if(now >= deadline) |
193 break; | 201 break; |
194 | 202 |
195 // Deadline hasn't arrived. Keep sleeping. | 203 // Deadline hasn't arrived. Keep sleeping. |
196 ns = deadline - now; | 204 ns = deadline - now; |
197 } | 205 } |
| 206 |
| 207 if(m->profilehz > 0) |
| 208 runtime·setprof(true); |
198 | 209 |
199 // Deadline arrived. Still registered. Semaphore not acquired. | 210 // Deadline arrived. Still registered. Semaphore not acquired. |
200 // Want to give up and return, but have to unregister first, | 211 // Want to give up and return, but have to unregister first, |
201 // so that any notewakeup racing with the return does not | 212 // so that any notewakeup racing with the return does not |
202 // try to grant us the semaphore when we don't expect it. | 213 // try to grant us the semaphore when we don't expect it. |
203 for(;;) { | 214 for(;;) { |
204 mp = runtime·atomicloadp(&n->waitm); | 215 mp = runtime·atomicloadp(&n->waitm); |
205 if(mp == m) { | 216 if(mp == m) { |
206 // No wakeup yet; unregister if possible. | 217 // No wakeup yet; unregister if possible. |
207 if(runtime·casp(&n->waitm, mp, nil)) | 218 if(runtime·casp(&n->waitm, mp, nil)) |
208 return; | 219 return; |
209 } else if(mp == (M*)LOCKED) { | 220 } else if(mp == (M*)LOCKED) { |
210 // Wakeup happened so semaphore is available. | 221 // Wakeup happened so semaphore is available. |
211 // Grab it to avoid getting out of sync. | 222 // Grab it to avoid getting out of sync. |
212 if(runtime·semasleep(-1) < 0) | 223 if(runtime·semasleep(-1) < 0) |
213 runtime·throw("runtime: unable to acquire - sema
phore out of sync"); | 224 runtime·throw("runtime: unable to acquire - sema
phore out of sync"); |
214 return; | 225 return; |
215 } else { | 226 } else { |
216 runtime·throw("runtime: unexpected waitm - semaphore out
of sync"); | 227 runtime·throw("runtime: unexpected waitm - semaphore out
of sync"); |
217 } | 228 } |
218 } | 229 } |
219 } | 230 } |
LEFT | RIGHT |