1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Time-related runtime and pieces of package time.
20 static void addtimer(Timer*);
21 static void dumptimers(const char*);
24 // Godoc uses the comments in package time, not these.
26 // time.now is implemented in assembly.
28 // Sleep puts the current goroutine to sleep for at least ns nanoseconds.
29 func Sleep(ns int64) {
30 runtime_tsleep(ns, "sleep");
33 // startTimer adds t to the timer heap.
34 func startTimer(t *Timer) {
36 runtime_racerelease(t);
40 // stopTimer removes t from the timer heap if it is there.
41 // It returns true if t was removed, false if t wasn't even there.
42 func stopTimer(t *Timer) (stopped bool) {
43 stopped = runtime_deltimer(t);
48 static void timerproc(void*);
49 static void siftup(int32);
50 static void siftdown(int32);
52 // Ready the goroutine e.data.
54 ready(int64 now, Eface e)
58 runtime_ready(e.__object);
61 static FuncVal readyv = {(void(*)(void))ready};
63 // Put the current goroutine to sleep for ns nanoseconds.
65 runtime_tsleep(int64 ns, const char *reason)
75 t.when = runtime_nanotime() + ns;
79 runtime_lock(&timers);
81 runtime_park(runtime_unlock, &timers, reason);
85 runtime_addtimer(Timer *t)
87 runtime_lock(&timers);
89 runtime_unlock(&timers);
92 // Add a timer to the heap and start or kick the timer proc
93 // if the new timer is earlier than any of the others.
100 // when must never be negative; otherwise timerproc will overflow
101 // during its delta calculation and never expire other timers.
103 t->when = (int64)((1ULL<<63)-1);
105 if(timers.len >= timers.cap) {
109 n = timers.cap*3 / 2;
110 nt = runtime_malloc(n*sizeof nt[0]);
111 runtime_memmove(nt, timers.t, timers.len*sizeof nt[0]);
112 runtime_free(timers.t);
120 // siftup moved to top: new earliest deadline.
121 if(timers.sleeping) {
122 timers.sleeping = false;
123 runtime_notewakeup(&timers.waitnote);
125 if(timers.rescheduling) {
126 timers.rescheduling = false;
127 runtime_ready(timers.timerproc);
130 if(timers.timerproc == nil) {
131 timers.timerproc = __go_go(timerproc, nil);
132 timers.timerproc->issystem = true;
135 dumptimers("addtimer");
138 // Used to force a dereference before the lock is acquired.
141 // Delete timer t from the heap.
142 // Do not need to update the timerproc:
143 // if it wakes up early, no big deal.
145 runtime_deltimer(Timer *t)
149 // Dereference t so that any panic happens before the lock is held.
150 // Discard result, because t might be moving in the heap.
154 runtime_lock(&timers);
156 // t may not be registered anymore and may have
157 // a bogus i (typically 0, if generated by Go).
158 // Verify it before proceeding.
160 if(i < 0 || i >= timers.len || timers.t[i] != t) {
161 runtime_unlock(&timers);
166 if(i == timers.len) {
169 timers.t[i] = timers.t[timers.len];
170 timers.t[timers.len] = nil;
176 dumptimers("deltimer");
177 runtime_unlock(&timers);
181 // Timerproc runs the time-driven events.
182 // It sleeps until the next event in the timers heap.
183 // If addtimer inserts a new earlier event, addtimer
184 // wakes timerproc early.
186 timerproc(void* dummy __attribute__ ((unused)))
190 void (*f)(int64, Eface);
194 runtime_lock(&timers);
195 timers.sleeping = false;
196 now = runtime_nanotime();
198 if(timers.len == 0) {
203 delta = t->when - now;
207 // leave in heap but adjust next time to fire
208 t->when += t->period * (1 + -delta/t->period);
212 timers.t[0] = timers.t[--timers.len];
215 t->i = -1; // mark as removed
217 f = (void*)t->fv->fn;
219 runtime_unlock(&timers);
221 runtime_raceacquire(t);
222 __go_set_closure(t->fv);
224 runtime_lock(&timers);
227 // No timers left - put goroutine to sleep.
228 timers.rescheduling = true;
229 runtime_park(runtime_unlock, &timers, "timer goroutine (idle)");
232 // At least one timer pending. Sleep until then.
233 timers.sleeping = true;
234 runtime_noteclear(&timers.waitnote);
235 runtime_unlock(&timers);
236 runtime_notetsleepg(&timers.waitnote, delta);
240 // heap maintenance algorithms.
253 p = (i-1)/4; // parent
254 if(when >= t[p]->when)
276 c = i*4 + 1; // left child
277 c3 = c + 2; // mid child
282 if(c+1 < len && t[c+1]->when < w) {
288 if(c3+1 < len && t[c3+1]->when < w3) {
308 dumptimers(const char *msg)
313 runtime_printf("timers: %s\n", msg);
314 for(i = 0; i < timers.len; i++) {
316 runtime_printf("\t%d\t%p:\ti %d when %D period %D fn %p\n",
317 i, t, t->i, t->when, t->period, t->fv->fn);
319 runtime_printf("\n");
323 runtime_time_scan(void (*addroot)(Obj))
325 addroot((Obj){(byte*)&timers, sizeof timers, 0});