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 // Time-related runtime and pieces of package time. | 5 // Time-related runtime and pieces of package time. |
6 | 6 |
7 package time | 7 package time |
8 | 8 |
9 #include "runtime.h" | 9 #include "runtime.h" |
10 #include "defs_GOOS_GOARCH.h" | 10 #include "defs_GOOS_GOARCH.h" |
11 #include "os_GOOS.h" | 11 #include "os_GOOS.h" |
12 #include "arch_GOARCH.h" | 12 #include "arch_GOARCH.h" |
13 #include "malloc.h" | 13 #include "malloc.h" |
| 14 #include "race.h" |
14 | 15 |
15 static Timers timers; | 16 static Timers timers; |
16 static void addtimer(Timer *t); | 17 static void addtimer(Timer *t); |
17 | 18 |
18 // Package time APIs. | 19 // Package time APIs. |
19 // Godoc uses the comments in package time, not these. | 20 // Godoc uses the comments in package time, not these. |
20 | 21 |
21 // time.now is implemented in assembly. | 22 // time.now is implemented in assembly. |
22 | 23 |
23 // Sleep puts the current goroutine to sleep for at least ns nanoseconds. | 24 // Sleep puts the current goroutine to sleep for at least ns nanoseconds. |
24 func Sleep(ns int64) { | 25 func Sleep(ns int64) { |
25 runtime·tsleep(ns, "sleep"); | 26 runtime·tsleep(ns, "sleep"); |
26 } | 27 } |
27 | 28 |
28 // startTimer adds t to the timer heap. | 29 // startTimer adds t to the timer heap. |
29 func startTimer(t *Timer) { | 30 func startTimer(t *Timer) { |
30 » runtime·addtimer(t); | 31 » if(raceenabled) |
| 32 » » runtime·racerelease(t); |
| 33 » runtime·lock(&timers); |
| 34 » addtimer(t); |
| 35 » runtime·unlock(&timers); |
31 } | 36 } |
32 | 37 |
33 // stopTimer removes t from the timer heap if it is there. | 38 // stopTimer removes t from the timer heap if it is there. |
34 // It returns true if t was removed, false if t wasn't even there. | 39 // It returns true if t was removed, false if t wasn't even there. |
35 func stopTimer(t *Timer) (stopped bool) { | 40 func stopTimer(t *Timer) (stopped bool) { |
36 stopped = runtime·deltimer(t); | 41 stopped = runtime·deltimer(t); |
37 } | 42 } |
38 | 43 |
39 // C runtime. | 44 // C runtime. |
40 | 45 |
(...skipping 18 matching lines...) Expand all Loading... |
59 | 64 |
60 if(ns <= 0) | 65 if(ns <= 0) |
61 return; | 66 return; |
62 | 67 |
63 t.when = runtime·nanotime() + ns; | 68 t.when = runtime·nanotime() + ns; |
64 t.period = 0; | 69 t.period = 0; |
65 t.f = ready; | 70 t.f = ready; |
66 t.arg.data = g; | 71 t.arg.data = g; |
67 runtime·lock(&timers); | 72 runtime·lock(&timers); |
68 addtimer(&t); | 73 addtimer(&t); |
69 » runtime·park(&timers.Lock, (void(*)(void*))runtime·unlock, reason); | 74 » runtime·park(runtime·unlock, &timers, reason); |
70 } | 75 } |
71 | 76 |
72 // Add a timer to the heap and start or kick the timer proc | 77 // Add a timer to the heap and start or kick the timer proc |
73 // if the new timer is earlier than any of the others. | 78 // if the new timer is earlier than any of the others. |
74 static void | 79 static void |
75 addtimer(Timer *t) | 80 addtimer(Timer *t) |
76 { | 81 { |
77 int32 n; | 82 int32 n; |
78 Timer **nt; | 83 Timer **nt; |
79 | 84 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 } else { | 184 } else { |
180 // remove from heap | 185 // remove from heap |
181 timers.t[0] = timers.t[--timers.len]; | 186 timers.t[0] = timers.t[--timers.len]; |
182 timers.t[0]->i = 0; | 187 timers.t[0]->i = 0; |
183 siftdown(0); | 188 siftdown(0); |
184 t->i = -1; // mark as removed | 189 t->i = -1; // mark as removed |
185 } | 190 } |
186 f = t->f; | 191 f = t->f; |
187 arg = t->arg; | 192 arg = t->arg; |
188 runtime·unlock(&timers); | 193 runtime·unlock(&timers); |
| 194 if(raceenabled) |
| 195 runtime·raceacquire(t); |
189 f(now, arg); | 196 f(now, arg); |
190 runtime·lock(&timers); | 197 runtime·lock(&timers); |
191 } | 198 } |
192 if(delta < 0) { | 199 if(delta < 0) { |
193 // No timers left - put goroutine to sleep. | 200 // No timers left - put goroutine to sleep. |
194 timers.rescheduling = true; | 201 timers.rescheduling = true; |
195 » » » runtime·park(&timers.Lock, (void(*)(void*))runtime·unloc
k, "timer goroutine (idle)"); | 202 » » » runtime·park(runtime·unlock, &timers, "timer goroutine (
idle)"); |
196 continue; | 203 continue; |
197 } | 204 } |
198 // At least one timer pending. Sleep until then. | 205 // At least one timer pending. Sleep until then. |
199 timers.sleeping = true; | 206 timers.sleeping = true; |
200 runtime·noteclear(&timers.waitnote); | 207 runtime·noteclear(&timers.waitnote); |
201 runtime·unlock(&timers); | 208 runtime·unlock(&timers); |
202 » » runtime·entersyscall(); | 209 » » runtime·entersyscallblock(); |
203 runtime·notetsleep(&timers.waitnote, delta); | 210 runtime·notetsleep(&timers.waitnote, delta); |
204 runtime·exitsyscall(); | 211 runtime·exitsyscall(); |
205 } | 212 } |
206 } | 213 } |
207 | 214 |
208 // heap maintenance algorithms. | 215 // heap maintenance algorithms. |
209 | 216 |
210 static void | 217 static void |
211 siftup(int32 i) | 218 siftup(int32 i) |
212 { | 219 { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 if(t[c]->when >= t[i]->when) | 252 if(t[c]->when >= t[i]->when) |
246 break; | 253 break; |
247 tmp = t[i]; | 254 tmp = t[i]; |
248 t[i] = t[c]; | 255 t[i] = t[c]; |
249 t[c] = tmp; | 256 t[c] = tmp; |
250 t[i]->i = i; | 257 t[i]->i = i; |
251 t[c]->i = c; | 258 t[c]->i = c; |
252 i = c; | 259 i = c; |
253 } | 260 } |
254 } | 261 } |
LEFT | RIGHT |