diff options
Diffstat (limited to 'gcc-4.8.1/libgo/runtime/time.goc')
-rw-r--r-- | gcc-4.8.1/libgo/runtime/time.goc | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/gcc-4.8.1/libgo/runtime/time.goc b/gcc-4.8.1/libgo/runtime/time.goc deleted file mode 100644 index 9a5cbdfed..000000000 --- a/gcc-4.8.1/libgo/runtime/time.goc +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Time-related runtime and pieces of package time. - -package time - -#include "runtime.h" -#include "defs.h" -#include "arch.h" -#include "malloc.h" -#include "race.h" - -static Timers timers; -static void addtimer(Timer*); -static bool deltimer(Timer*); - -// Package time APIs. -// Godoc uses the comments in package time, not these. - -// time.now is implemented in assembly. - -// Sleep puts the current goroutine to sleep for at least ns nanoseconds. -func Sleep(ns int64) { - runtime_tsleep(ns, "sleep"); -} - -// startTimer adds t to the timer heap. -func startTimer(t *Timer) { - if(raceenabled) - runtime_racerelease(t); - runtime_lock(&timers); - addtimer(t); - runtime_unlock(&timers); -} - -// stopTimer removes t from the timer heap if it is there. -// It returns true if t was removed, false if t wasn't even there. -func stopTimer(t *Timer) (stopped bool) { - stopped = deltimer(t); -} - -// C runtime. - -static void timerproc(void*); -static void siftup(int32); -static void siftdown(int32); - -// Ready the goroutine e.data. -static void -ready(int64 now, Eface e) -{ - USED(now); - - runtime_ready(e.__object); -} - -// Put the current goroutine to sleep for ns nanoseconds. -void -runtime_tsleep(int64 ns, const char *reason) -{ - G* g; - Timer t; - - g = runtime_g(); - - if(ns <= 0) - return; - - t.when = runtime_nanotime() + ns; - t.period = 0; - t.f = ready; - t.arg.__object = g; - runtime_lock(&timers); - addtimer(&t); - runtime_park(runtime_unlock, &timers, reason); -} - -// Add a timer to the heap and start or kick the timer proc -// if the new timer is earlier than any of the others. -static void -addtimer(Timer *t) -{ - int32 n; - Timer **nt; - - if(timers.len >= timers.cap) { - // Grow slice. - n = 16; - if(n <= timers.cap) - n = timers.cap*3 / 2; - nt = runtime_malloc(n*sizeof nt[0]); - runtime_memmove(nt, timers.t, timers.len*sizeof nt[0]); - runtime_free(timers.t); - timers.t = nt; - timers.cap = n; - } - t->i = timers.len++; - timers.t[t->i] = t; - siftup(t->i); - if(t->i == 0) { - // siftup moved to top: new earliest deadline. - if(timers.sleeping) { - timers.sleeping = false; - runtime_notewakeup(&timers.waitnote); - } - if(timers.rescheduling) { - timers.rescheduling = false; - runtime_ready(timers.timerproc); - } - } - if(timers.timerproc == nil) { - timers.timerproc = __go_go(timerproc, nil); - timers.timerproc->issystem = true; - } -} - -// Delete timer t from the heap. -// Do not need to update the timerproc: -// if it wakes up early, no big deal. -static bool -deltimer(Timer *t) -{ - int32 i; - - runtime_lock(&timers); - - // t may not be registered anymore and may have - // a bogus i (typically 0, if generated by Go). - // Verify it before proceeding. - i = t->i; - if(i < 0 || i >= timers.len || timers.t[i] != t) { - runtime_unlock(&timers); - return false; - } - - timers.len--; - if(i == timers.len) { - timers.t[i] = nil; - } else { - timers.t[i] = timers.t[timers.len]; - timers.t[timers.len] = nil; - timers.t[i]->i = i; - siftup(i); - siftdown(i); - } - runtime_unlock(&timers); - return true; -} - -// Timerproc runs the time-driven events. -// It sleeps until the next event in the timers heap. -// If addtimer inserts a new earlier event, addtimer -// wakes timerproc early. -static void -timerproc(void* dummy __attribute__ ((unused))) -{ - int64 delta, now; - Timer *t; - void (*f)(int64, Eface); - Eface arg; - - for(;;) { - runtime_lock(&timers); - now = runtime_nanotime(); - for(;;) { - if(timers.len == 0) { - delta = -1; - break; - } - t = timers.t[0]; - delta = t->when - now; - if(delta > 0) - break; - if(t->period > 0) { - // leave in heap but adjust next time to fire - t->when += t->period * (1 + -delta/t->period); - siftdown(0); - } else { - // remove from heap - timers.t[0] = timers.t[--timers.len]; - timers.t[0]->i = 0; - siftdown(0); - t->i = -1; // mark as removed - } - f = t->f; - arg = t->arg; - runtime_unlock(&timers); - if(raceenabled) - runtime_raceacquire(t); - f(now, arg); - runtime_lock(&timers); - } - if(delta < 0) { - // No timers left - put goroutine to sleep. - timers.rescheduling = true; - runtime_park(runtime_unlock, &timers, "timer goroutine (idle)"); - continue; - } - // At least one timer pending. Sleep until then. - timers.sleeping = true; - runtime_noteclear(&timers.waitnote); - runtime_unlock(&timers); - runtime_entersyscall(); - runtime_notetsleep(&timers.waitnote, delta); - runtime_exitsyscall(); - } -} - -// heap maintenance algorithms. - -static void -siftup(int32 i) -{ - int32 p; - Timer **t, *tmp; - - t = timers.t; - while(i > 0) { - p = (i-1)/2; // parent - if(t[i]->when >= t[p]->when) - break; - tmp = t[i]; - t[i] = t[p]; - t[p] = tmp; - t[i]->i = i; - t[p]->i = p; - i = p; - } -} - -static void -siftdown(int32 i) -{ - int32 c, len; - Timer **t, *tmp; - - t = timers.t; - len = timers.len; - for(;;) { - c = i*2 + 1; // left child - if(c >= len) { - break; - } - if(c+1 < len && t[c+1]->when < t[c]->when) - c++; - if(t[c]->when >= t[i]->when) - break; - tmp = t[i]; - t[i] = t[c]; - t[c] = tmp; - t[i]->i = i; - t[c]->i = c; - i = c; - } -} - -void -runtime_time_scan(void (*addroot)(Obj)) -{ - addroot((Obj){(byte*)&timers, sizeof timers, 0}); -} |