diff options
Diffstat (limited to 'libgo/runtime/time.goc')
-rw-r--r-- | libgo/runtime/time.goc | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/libgo/runtime/time.goc b/libgo/runtime/time.goc index b3f0fb0278f..5077b719fcf 100644 --- a/libgo/runtime/time.goc +++ b/libgo/runtime/time.goc @@ -10,6 +10,7 @@ package time #include "defs.h" #include "arch.h" #include "malloc.h" +#include "race.h" static Timers timers; static void addtimer(Timer*); @@ -22,17 +23,16 @@ static bool deltimer(Timer*); // Sleep puts the current goroutine to sleep for at least ns nanoseconds. func Sleep(ns int64) { - G *g; - - g = runtime_g(); - g->status = Gwaiting; - g->waitreason = "sleep"; - runtime_tsleep(ns); + 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. @@ -57,27 +57,24 @@ ready(int64 now, Eface e) } // Put the current goroutine to sleep for ns nanoseconds. -// The caller must have set g->status and g->waitreason. void -runtime_tsleep(int64 ns) +runtime_tsleep(int64 ns, const char *reason) { G* g; Timer t; g = runtime_g(); - if(ns <= 0) { - g->status = Grunning; - g->waitreason = nil; + 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_gosched(); + runtime_park(runtime_unlock, &timers, reason); } // Add a timer to the heap and start or kick the timer proc @@ -88,7 +85,6 @@ addtimer(Timer *t) int32 n; Timer **nt; - runtime_lock(&timers); if(timers.len >= timers.cap) { // Grow slice. n = 16; @@ -116,7 +112,6 @@ addtimer(Timer *t) } if(timers.timerproc == nil) timers.timerproc = __go_go(timerproc, nil); - runtime_unlock(&timers); } // Delete timer t from the heap. @@ -159,13 +154,11 @@ deltimer(Timer *t) static void timerproc(void* dummy __attribute__ ((unused))) { - G *g; int64 delta, now; Timer *t; void (*f)(int64, Eface); Eface arg; - g = runtime_g(); for(;;) { runtime_lock(&timers); now = runtime_nanotime(); @@ -192,16 +185,15 @@ timerproc(void* dummy __attribute__ ((unused))) 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; - g->status = Gwaiting; - g->waitreason = "timer goroutine (idle)"; - runtime_unlock(&timers); - runtime_gosched(); + runtime_park(runtime_unlock, &timers, "timer goroutine (idle)"); continue; } // At least one timer pending. Sleep until then. @@ -263,7 +255,7 @@ siftdown(int32 i) } void -runtime_time_scan(void (*scan)(byte*, int64)) +runtime_time_scan(void (*addroot)(byte*, uintptr)) { - scan((byte*)&timers, sizeof timers); + addroot((byte*)&timers, sizeof timers); } |