mirror of
https://github.com/golang/go
synced 2024-11-23 12:40:11 -07:00
runtime: add fake time support back.
Revived from CL 15690048. Fixes #5356. LGTM=rsc R=adg, dvyukov, rsc CC=golang-codereviews https://golang.org/cl/101400043
This commit is contained in:
parent
2eb1b65830
commit
2fe9482343
@ -2758,6 +2758,8 @@ static void
|
|||||||
checkdead(void)
|
checkdead(void)
|
||||||
{
|
{
|
||||||
G *gp;
|
G *gp;
|
||||||
|
P *p;
|
||||||
|
M *mp;
|
||||||
int32 run, grunning, s;
|
int32 run, grunning, s;
|
||||||
uintptr i;
|
uintptr i;
|
||||||
|
|
||||||
@ -2799,6 +2801,24 @@ checkdead(void)
|
|||||||
runtime·unlock(&runtime·allglock);
|
runtime·unlock(&runtime·allglock);
|
||||||
if(grunning == 0) // possible if main goroutine calls runtime·Goexit()
|
if(grunning == 0) // possible if main goroutine calls runtime·Goexit()
|
||||||
runtime·throw("no goroutines (main called runtime.Goexit) - deadlock!");
|
runtime·throw("no goroutines (main called runtime.Goexit) - deadlock!");
|
||||||
|
|
||||||
|
// Maybe jump time forward for playground.
|
||||||
|
if((gp = runtime·timejump()) != nil) {
|
||||||
|
runtime·casgstatus(gp, Gwaiting, Grunnable);
|
||||||
|
globrunqput(gp);
|
||||||
|
p = pidleget();
|
||||||
|
if(p == nil)
|
||||||
|
runtime·throw("checkdead: no p for timer");
|
||||||
|
mp = mget();
|
||||||
|
if(mp == nil)
|
||||||
|
newm(nil, p);
|
||||||
|
else {
|
||||||
|
mp->nextp = p;
|
||||||
|
runtime·notewakeup(&mp->park);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g->m->throwing = -1; // do not dump full stacks
|
g->m->throwing = -1; // do not dump full stacks
|
||||||
runtime·throw("all goroutines are asleep - deadlock!");
|
runtime·throw("all goroutines are asleep - deadlock!");
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,6 @@ TEXT _rt0_amd64p32_nacl(SB),NOSPLIT,$16
|
|||||||
|
|
||||||
TEXT main(SB),NOSPLIT,$0
|
TEXT main(SB),NOSPLIT,$0
|
||||||
// Uncomment for fake time like on Go Playground.
|
// Uncomment for fake time like on Go Playground.
|
||||||
//MOVQ $1257894000000000000, AX
|
MOVQ $1257894000000000000, AX
|
||||||
//MOVQ AX, runtime·timens(SB)
|
MOVQ AX, runtime·faketime(SB)
|
||||||
JMP runtime·rt0_go(SB)
|
JMP runtime·rt0_go(SB)
|
||||||
|
@ -60,7 +60,7 @@ TEXT syscall·naclWrite(SB), NOSPLIT, $24-20
|
|||||||
TEXT runtime·write(SB),NOSPLIT,$16-20
|
TEXT runtime·write(SB),NOSPLIT,$16-20
|
||||||
// If using fake time and writing to stdout or stderr,
|
// If using fake time and writing to stdout or stderr,
|
||||||
// emit playback header before actual data.
|
// emit playback header before actual data.
|
||||||
MOVQ runtime·timens(SB), AX
|
MOVQ runtime·faketime(SB), AX
|
||||||
CMPQ AX, $0
|
CMPQ AX, $0
|
||||||
JEQ write
|
JEQ write
|
||||||
MOVL fd+0(FP), DI
|
MOVL fd+0(FP), DI
|
||||||
@ -242,7 +242,7 @@ TEXT runtime·mmap(SB),NOSPLIT,$8
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT time·now(SB),NOSPLIT,$16
|
TEXT time·now(SB),NOSPLIT,$16
|
||||||
MOVQ runtime·timens(SB), AX
|
MOVQ runtime·faketime(SB), AX
|
||||||
CMPQ AX, $0
|
CMPQ AX, $0
|
||||||
JEQ realtime
|
JEQ realtime
|
||||||
MOVQ $0, DX
|
MOVQ $0, DX
|
||||||
@ -277,7 +277,7 @@ TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·nanotime(SB),NOSPLIT,$16
|
TEXT runtime·nanotime(SB),NOSPLIT,$16
|
||||||
MOVQ runtime·timens(SB), AX
|
MOVQ runtime·faketime(SB), AX
|
||||||
CMPQ AX, $0
|
CMPQ AX, $0
|
||||||
JEQ 3(PC)
|
JEQ 3(PC)
|
||||||
MOVQ AX, ret+0(FP)
|
MOVQ AX, ret+0(FP)
|
||||||
|
@ -35,8 +35,8 @@ var timers struct {
|
|||||||
t []*timer
|
t []*timer
|
||||||
}
|
}
|
||||||
|
|
||||||
// nacl fake time support.
|
// nacl fake time support - time in nanoseconds since 1970
|
||||||
var timens int64
|
var faketime int64
|
||||||
|
|
||||||
// Package time APIs.
|
// Package time APIs.
|
||||||
// Godoc uses the comments in package time, not these.
|
// Godoc uses the comments in package time, not these.
|
||||||
@ -194,7 +194,7 @@ func timerproc() {
|
|||||||
f(arg, seq)
|
f(arg, seq)
|
||||||
lock(&timers.lock)
|
lock(&timers.lock)
|
||||||
}
|
}
|
||||||
if delta < 0 {
|
if delta < 0 || faketime > 0 {
|
||||||
// No timers left - put goroutine to sleep.
|
// No timers left - put goroutine to sleep.
|
||||||
timers.rescheduling = true
|
timers.rescheduling = true
|
||||||
goparkunlock(&timers.lock, "timer goroutine (idle)")
|
goparkunlock(&timers.lock, "timer goroutine (idle)")
|
||||||
@ -208,6 +208,29 @@ func timerproc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func timejump() *g {
|
||||||
|
if faketime == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
lock(&timers.lock)
|
||||||
|
if !timers.created || len(timers.t) == 0 {
|
||||||
|
unlock(&timers.lock)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var gp *g
|
||||||
|
if faketime < timers.t[0].when {
|
||||||
|
faketime = timers.t[0].when
|
||||||
|
if timers.rescheduling {
|
||||||
|
timers.rescheduling = false
|
||||||
|
gp = timers.gp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlock(&timers.lock)
|
||||||
|
return gp
|
||||||
|
}
|
||||||
|
|
||||||
// Heap maintenance algorithms.
|
// Heap maintenance algorithms.
|
||||||
|
|
||||||
func siftupTimer(i int) {
|
func siftupTimer(i int) {
|
||||||
|
Loading…
Reference in New Issue
Block a user