summaryrefslogtreecommitdiff
path: root/libgo/runtime/time.goc
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/time.goc')
-rw-r--r--libgo/runtime/time.goc38
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);
}