LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 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 // Semaphore implementation exposed to Go. | 5 // Semaphore implementation exposed to Go. |
6 // Intended use is provide a sleep and wakeup | 6 // Intended use is provide a sleep and wakeup |
7 // primitive that can be used in the contended case | 7 // primitive that can be used in the contended case |
8 // of other synchronization primitives. | 8 // of other synchronization primitives. |
9 // Thus it targets the same goal as Linux's futex, | 9 // Thus it targets the same goal as Linux's futex, |
10 // but it has much simpler semantics. | 10 // but it has much simpler semantics. |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 }; | 211 }; |
212 | 212 |
213 func runtime_Syncsemcheck(size uintptr) { | 213 func runtime_Syncsemcheck(size uintptr) { |
214 if(size != sizeof(SyncSema)) { | 214 if(size != sizeof(SyncSema)) { |
215 runtime·printf("bad SyncSema size: sync:%D runtime:%D\n", (int64
)size, (int64)sizeof(SyncSema)); | 215 runtime·printf("bad SyncSema size: sync:%D runtime:%D\n", (int64
)size, (int64)sizeof(SyncSema)); |
216 runtime·throw("bad SyncSema size"); | 216 runtime·throw("bad SyncSema size"); |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 // Syncsemacquire waits for a pairing Syncsemrelease on the same semaphore s. | 220 // Syncsemacquire waits for a pairing Syncsemrelease on the same semaphore s. |
221 // Returns false if the semaphore is corrupted. | 221 func runtime_Syncsemacquire(s *SyncSema) { |
222 func runtime_Syncsemacquire(s *SyncSema) (res bool) { | |
223 SemaWaiter w, *wake; | 222 SemaWaiter w, *wake; |
224 int64 t0; | 223 int64 t0; |
225 | 224 |
226 w.g = g; | 225 w.g = g; |
227 w.nrelease = -1; | 226 w.nrelease = -1; |
228 w.next = nil; | 227 w.next = nil; |
229 w.releasetime = 0; | 228 w.releasetime = 0; |
230 t0 = 0; | 229 t0 = 0; |
231 if(runtime·blockprofilerate > 0) { | 230 if(runtime·blockprofilerate > 0) { |
232 t0 = runtime·cputicks(); | 231 t0 = runtime·cputicks(); |
(...skipping 18 matching lines...) Expand all Loading... |
251 // enqueue itself | 250 // enqueue itself |
252 if(s->tail == nil) | 251 if(s->tail == nil) |
253 s->head = &w; | 252 s->head = &w; |
254 else | 253 else |
255 s->tail->next = &w; | 254 s->tail->next = &w; |
256 s->tail = &w; | 255 s->tail = &w; |
257 runtime·park(runtime·unlock, s, "semacquire"); | 256 runtime·park(runtime·unlock, s, "semacquire"); |
258 if(t0) | 257 if(t0) |
259 runtime·blockevent(w.releasetime - t0, 2); | 258 runtime·blockevent(w.releasetime - t0, 2); |
260 } | 259 } |
261 res = true; | |
262 } | 260 } |
263 | 261 |
264 // Syncsemrelease waits for n pairing Syncsemacquire on the same semaphore s. | 262 // Syncsemrelease waits for n pairing Syncsemacquire on the same semaphore s. |
265 // Returns false if the semaphore is corrupted. | 263 func runtime_Syncsemrelease(s *SyncSema, n uint32) { |
266 func runtime_Syncsemrelease(s *SyncSema, n uint32) (res bool) { | |
267 SemaWaiter w, *wake; | 264 SemaWaiter w, *wake; |
268 | 265 |
269 w.g = g; | 266 w.g = g; |
270 w.nrelease = (int32)n; | 267 w.nrelease = (int32)n; |
271 w.next = nil; | 268 w.next = nil; |
272 w.releasetime = 0; | 269 w.releasetime = 0; |
273 | 270 |
274 runtime·lock(s); | 271 runtime·lock(s); |
275 while(w.nrelease > 0 && s->head && s->head->nrelease < 0) { | 272 while(w.nrelease > 0 && s->head && s->head->nrelease < 0) { |
276 // have pending acquire, satisfy it | 273 // have pending acquire, satisfy it |
277 wake = s->head; | 274 wake = s->head; |
278 s->head = wake->next; | 275 s->head = wake->next; |
279 if(s->head == nil) | 276 if(s->head == nil) |
280 s->tail = nil; | 277 s->tail = nil; |
281 if(wake->releasetime) | 278 if(wake->releasetime) |
282 wake->releasetime = runtime·cputicks(); | 279 wake->releasetime = runtime·cputicks(); |
283 runtime·ready(wake->g); | 280 runtime·ready(wake->g); |
284 w.nrelease--; | 281 w.nrelease--; |
285 } | 282 } |
286 if(w.nrelease > 0) { | 283 if(w.nrelease > 0) { |
287 // enqueue itself | 284 // enqueue itself |
288 if(s->tail == nil) | 285 if(s->tail == nil) |
289 s->head = &w; | 286 s->head = &w; |
290 else | 287 else |
291 s->tail->next = &w; | 288 s->tail->next = &w; |
292 s->tail = &w; | 289 s->tail = &w; |
293 runtime·park(runtime·unlock, s, "semarelease"); | 290 runtime·park(runtime·unlock, s, "semarelease"); |
294 } else | 291 } else |
295 runtime·unlock(s); | 292 runtime·unlock(s); |
296 » res = true; | 293 } |
297 } | |
LEFT | RIGHT |