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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 111 |
112 // Harder case: | 112 // Harder case: |
113 // increment waiter count | 113 // increment waiter count |
114 // try cansemacquire one more time, return if succeeded | 114 // try cansemacquire one more time, return if succeeded |
115 // enqueue itself as a waiter | 115 // enqueue itself as a waiter |
116 // sleep | 116 // sleep |
117 // (waiter descriptor is dequeued by signaler) | 117 // (waiter descriptor is dequeued by signaler) |
118 root = semroot(addr); | 118 root = semroot(addr); |
119 t0 = 0; | 119 t0 = 0; |
120 s.releasetime = 0; | 120 s.releasetime = 0; |
121 » if(profile && runtime·BlockProfileRate > 0) { | 121 » if(profile && runtime·blockprofilerate > 0) { |
122 t0 = runtime·cputicks(); | 122 t0 = runtime·cputicks(); |
123 s.releasetime = -1; | 123 s.releasetime = -1; |
124 } | 124 } |
125 for(;;) { | 125 for(;;) { |
126 runtime·lock(root); | 126 runtime·lock(root); |
127 // Add ourselves to nwait to disable "easy case" in semrelease. | 127 // Add ourselves to nwait to disable "easy case" in semrelease. |
128 runtime·xadd(&root->nwait, 1); | 128 runtime·xadd(&root->nwait, 1); |
129 // Check cansemacquire to avoid missed wakeup. | 129 // Check cansemacquire to avoid missed wakeup. |
130 if(cansemacquire(addr)) { | 130 if(cansemacquire(addr)) { |
131 runtime·xadd(&root->nwait, -1); | 131 runtime·xadd(&root->nwait, -1); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 } | 188 } |
189 } | 189 } |
190 | 190 |
191 func runtime_Semacquire(addr *uint32) { | 191 func runtime_Semacquire(addr *uint32) { |
192 semacquireimpl(addr, 1); | 192 semacquireimpl(addr, 1); |
193 } | 193 } |
194 | 194 |
195 func runtime_Semrelease(addr *uint32) { | 195 func runtime_Semrelease(addr *uint32) { |
196 runtime·semrelease(addr); | 196 runtime·semrelease(addr); |
197 } | 197 } |
LEFT | RIGHT |