Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2541)

Side by Side Diff: src/pkg/runtime/time.goc

Issue 6892048: runtime: synthetic time
Patch Set: diff -r f7c125983d99 https://code.google.com/p/go Created 11 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/runtime/runtime.h ('k') | src/pkg/time/sleep.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "race.h"
15 15
16 static Timers timers; 16 static Timers timers;
17 static void addtimer(Timer*); 17 static void addtimer(Timer*);
18 static bool deltimer(Timer*); 18 static bool deltimer(Timer*);
19 static int64 fakeNanotime = 1257894000000000000ll; // go epoch
19 20
20 // Package time APIs. 21 // Package time APIs.
21 // Godoc uses the comments in package time, not these. 22 // Godoc uses the comments in package time, not these.
22 23
23 // time.now is implemented in assembly. 24 // time.now is implemented in assembly.
24 25
26 func fakeNow() (sec int64, nsec int32) {
27 runtime·lock(&timers);
28 sec = (int32)(fakeNanotime/1000000000);
29 nsec = (int32)(fakeNanotime%1000000000);
30 runtime·unlock(&timers);
31 }
32
25 // Sleep puts the current goroutine to sleep for at least ns nanoseconds. 33 // Sleep puts the current goroutine to sleep for at least ns nanoseconds.
26 func Sleep(ns int64) { 34 func Sleep(ns int64) {
27 runtime·tsleep(ns, "sleep"); 35 runtime·tsleep(ns, "sleep");
28 } 36 }
29 37
30 // startTimer adds t to the timer heap. 38 // startTimer adds t to the timer heap.
31 func startTimer(t *Timer) { 39 func startTimer(t *Timer) {
32 if(raceenabled) 40 if(raceenabled)
33 runtime·racerelease(t); 41 runtime·racerelease(t);
34 runtime·lock(&timers); 42 runtime·lock(&timers);
(...skipping 24 matching lines...) Expand all
59 67
60 // Put the current goroutine to sleep for ns nanoseconds. 68 // Put the current goroutine to sleep for ns nanoseconds.
61 void 69 void
62 runtime·tsleep(int64 ns, int8 *reason) 70 runtime·tsleep(int64 ns, int8 *reason)
63 { 71 {
64 Timer t; 72 Timer t;
65 73
66 if(ns <= 0) 74 if(ns <= 0)
67 return; 75 return;
68 76
69 » t.when = runtime·nanotime() + ns; 77 » t.when = fakeNanotime + ns;
70 t.period = 0; 78 t.period = 0;
71 t.f = ready; 79 t.f = ready;
72 t.arg.data = g; 80 t.arg.data = g;
73 runtime·lock(&timers); 81 runtime·lock(&timers);
74 addtimer(&t); 82 addtimer(&t);
75 runtime·park(runtime·unlock, &timers, reason); 83 runtime·park(runtime·unlock, &timers, reason);
76 } 84 }
77 85
78 // Add a timer to the heap and start or kick the timer proc 86 // Add a timer to the heap and start or kick the timer proc
79 // if the new timer is earlier than any of the others. 87 // if the new timer is earlier than any of the others.
(...skipping 12 matching lines...) Expand all
92 runtime·memmove(nt, timers.t, timers.len*sizeof nt[0]); 100 runtime·memmove(nt, timers.t, timers.len*sizeof nt[0]);
93 runtime·free(timers.t); 101 runtime·free(timers.t);
94 timers.t = nt; 102 timers.t = nt;
95 timers.cap = n; 103 timers.cap = n;
96 } 104 }
97 t->i = timers.len++; 105 t->i = timers.len++;
98 timers.t[t->i] = t; 106 timers.t[t->i] = t;
99 siftup(t->i); 107 siftup(t->i);
100 if(t->i == 0) { 108 if(t->i == 0) {
101 // siftup moved to top: new earliest deadline. 109 // siftup moved to top: new earliest deadline.
102 if(timers.sleeping) {
103 timers.sleeping = false;
104 runtime·notewakeup(&timers.waitnote);
105 }
106 if(timers.rescheduling) { 110 if(timers.rescheduling) {
107 timers.rescheduling = false; 111 timers.rescheduling = false;
108 runtime·ready(timers.timerproc); 112 runtime·ready(timers.timerproc);
109 } 113 }
110 } 114 }
111 if(timers.timerproc == nil) 115 if(timers.timerproc == nil)
112 timers.timerproc = runtime·newproc1((byte*)timerproc, nil, 0, 0, addtimer); 116 timers.timerproc = runtime·newproc1((byte*)timerproc, nil, 0, 0, addtimer);
113 } 117 }
114 118
115 // Delete timer t from the heap. 119 // Delete timer t from the heap.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 // wakes timerproc early. 155 // wakes timerproc early.
152 static void 156 static void
153 timerproc(void) 157 timerproc(void)
154 { 158 {
155 int64 delta, now; 159 int64 delta, now;
156 Timer *t; 160 Timer *t;
157 void (*f)(int64, Eface); 161 void (*f)(int64, Eface);
158 Eface arg; 162 Eface arg;
159 163
160 for(;;) { 164 for(;;) {
165 // At least one timer pending. Wait until goroutines are idle.
166 runtime·waitidle();
161 runtime·lock(&timers); 167 runtime·lock(&timers);
162 » » now = runtime·nanotime(); 168 » » // Update the fake time with the next timer.
169 » » if(timers.len > 0) {
170 » » » fakeNanotime = timers.t[0]->when;
171 » » }
172 » » now = fakeNanotime;
163 for(;;) { 173 for(;;) {
164 if(timers.len == 0) { 174 if(timers.len == 0) {
165 delta = -1; 175 delta = -1;
166 break; 176 break;
167 } 177 }
168 t = timers.t[0]; 178 t = timers.t[0];
169 delta = t->when - now; 179 delta = t->when - now;
170 if(delta > 0) 180 if(delta > 0)
171 break; 181 break;
172 if(t->period > 0) { 182 if(t->period > 0) {
(...skipping 14 matching lines...) Expand all
187 runtime·raceacquire(t); 197 runtime·raceacquire(t);
188 f(now, arg); 198 f(now, arg);
189 runtime·lock(&timers); 199 runtime·lock(&timers);
190 } 200 }
191 if(delta < 0) { 201 if(delta < 0) {
192 // No timers left - put goroutine to sleep. 202 // No timers left - put goroutine to sleep.
193 timers.rescheduling = true; 203 timers.rescheduling = true;
194 runtime·park(runtime·unlock, &timers, "timer goroutine ( idle)"); 204 runtime·park(runtime·unlock, &timers, "timer goroutine ( idle)");
195 continue; 205 continue;
196 } 206 }
197 // At least one timer pending. Sleep until then.
198 timers.sleeping = true;
199 runtime·noteclear(&timers.waitnote);
200 runtime·unlock(&timers); 207 runtime·unlock(&timers);
201 runtime·entersyscall();
202 runtime·notetsleep(&timers.waitnote, delta);
203 runtime·exitsyscall();
204 } 208 }
205 } 209 }
206 210
207 // heap maintenance algorithms. 211 // heap maintenance algorithms.
208 212
209 static void 213 static void
210 siftup(int32 i) 214 siftup(int32 i)
211 { 215 {
212 int32 p; 216 int32 p;
213 Timer **t, *tmp; 217 Timer **t, *tmp;
(...skipping 30 matching lines...) Expand all
244 if(t[c]->when >= t[i]->when) 248 if(t[c]->when >= t[i]->when)
245 break; 249 break;
246 tmp = t[i]; 250 tmp = t[i];
247 t[i] = t[c]; 251 t[i] = t[c];
248 t[c] = tmp; 252 t[c] = tmp;
249 t[i]->i = i; 253 t[i]->i = i;
250 t[c]->i = c; 254 t[c]->i = c;
251 i = c; 255 i = c;
252 } 256 }
253 } 257 }
OLDNEW
« no previous file with comments | « src/pkg/runtime/runtime.h ('k') | src/pkg/time/sleep.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b