1
0
mirror of https://github.com/golang/go synced 2024-11-18 12:24:48 -07:00

runtime: switch to os stack in windows osyield and usleep

Fixes #5831

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/11266043
This commit is contained in:
Alex Brainman 2013-07-16 12:36:05 +10:00
parent 2254785c3e
commit 45cff65502
3 changed files with 79 additions and 49 deletions

View File

@ -275,6 +275,23 @@ runtime·stdcall(void *fn, int32 count, ...)
return (void*)c.r1;
}
extern void runtime·usleep1(uint32);
#pragma textflag 7
void
runtime·osyield(void)
{
runtime·usleep1(1);
}
#pragma textflag 7
void
runtime·usleep(uint32 us)
{
// Have 1us units; want 100ns units.
runtime·usleep1(10*us);
}
uint32
runtime·issigpanic(uint32 code)
{

View File

@ -327,28 +327,39 @@ TEXT runtime·remove_exception_handler(SB),7,$0
RET
TEXT runtime·osyield(SB),7,$20
// Tried NtYieldExecution but it doesn't yield hard enough.
// NtWaitForSingleObject being used here as Sleep(0).
MOVL runtime·NtWaitForSingleObject(SB), AX
MOVL $-1, hi-4(SP)
MOVL $-1, lo-8(SP)
LEAL lo-8(SP), BX
MOVL BX, ptime-12(SP)
MOVL $0, alertable-16(SP)
MOVL $-1, handle-20(SP)
MOVL SP, BP
CALL checkstack4<>(SB)
// Sleep duration is in 100ns units.
TEXT runtime·usleep1(SB),7,$0
MOVL duration+0(FP), BX
MOVL $runtime·usleep2(SB), AX // to hide from 8l
// Execute call on m->g0 stack, in case we are not actually
// calling a system call wrapper, like when running under WINE.
get_tls(CX)
CMPL CX, $0
JNE 3(PC)
// Not a Go-managed thread. Do not switch stack.
CALL AX
MOVL BP, SP
RET
TEXT runtime·usleep(SB),7,$20
MOVL runtime·NtWaitForSingleObject(SB), AX
// Have 1us units; need negative 100ns units.
// Assume multiply by 10 will not overflow 32-bit word.
MOVL usec+0(FP), BX
IMULL $10, BX
MOVL m(CX), BP
MOVL m_g0(BP), SI
CMPL g(CX), SI
JNE 3(PC)
// executing on m->g0 already
CALL AX
RET
// Switch to m->g0 stack and back.
MOVL (g_sched+gobuf_sp)(SI), SI
MOVL SP, -4(SI)
LEAL -4(SI), SP
CALL AX
MOVL 0(SP), SP
RET
// Runs on OS stack. duration (in 100ns units) is in BX.
TEXT runtime·usleep2(SB),7,$20
// Want negative 100ns units.
NEGL BX
MOVL $-1, hi-4(SP)
MOVL BX, lo-8(SP)
@ -357,15 +368,7 @@ TEXT runtime·usleep(SB),7,$20
MOVL $0, alertable-16(SP)
MOVL $-1, handle-20(SP)
MOVL SP, BP
CALL checkstack4<>(SB)
MOVL runtime·NtWaitForSingleObject(SB), AX
CALL AX
MOVL BP, SP
RET
// This function requires 4 bytes of stack,
// to simulate what calling NtWaitForSingleObject will use.
// (It is just a CALL to the system call dispatch.)
// If the linker okays the call to checkstack4 (a NOSPLIT function)
// then the call to NtWaitForSingleObject is okay too.
TEXT checkstack4<>(SB),7,$4
RET

View File

@ -322,34 +322,44 @@ TEXT runtime·install_exception_handler(SB),7,$0
TEXT runtime·remove_exception_handler(SB),7,$0
RET
TEXT runtime·osyield(SB),7,$8
// Tried NtYieldExecution but it doesn't yield hard enough.
// NtWaitForSingleObject being used here as Sleep(0).
// The CALL is safe because NtXxx is a system call wrapper:
// it puts the right system call number in AX, then does
// a SYSENTER and a RET.
MOVQ runtime·NtWaitForSingleObject(SB), AX
MOVQ $1, BX
NEGQ BX
MOVQ SP, R8 // ptime
MOVQ BX, (R8)
MOVQ $-1, CX // handle
MOVQ $0, DX // alertable
// Sleep duration is in 100ns units.
TEXT runtime·usleep1(SB),7,$0
MOVL duration+0(FP), BX
MOVQ $runtime·usleep2(SB), AX // to hide from 6l
// Execute call on m->g0 stack, in case we are not actually
// calling a system call wrapper, like when running under WINE.
get_tls(R15)
CMPQ R15, $0
JNE 3(PC)
// Not a Go-managed thread. Do not switch stack.
CALL AX
RET
TEXT runtime·usleep(SB),7,$8
// The CALL is safe because NtXxx is a system call wrapper:
// it puts the right system call number in AX, then does
// a SYSENTER and a RET.
MOVQ runtime·NtWaitForSingleObject(SB), AX
// Have 1us units; want negative 100ns units.
MOVL usec+0(FP), BX
IMULQ $10, BX
MOVQ m(R15), R14
MOVQ m_g0(R14), R14
CMPQ g(R15), R14
JNE 3(PC)
// executing on m->g0 already
CALL AX
RET
// Switch to m->g0 stack and back.
MOVQ (g_sched+gobuf_sp)(R14), R14
MOVQ SP, -8(R14)
LEAQ -8(R14), SP
CALL AX
MOVQ 0(SP), SP
RET
// Runs on OS stack. duration (in 100ns units) is in BX.
TEXT runtime·usleep2(SB),7,$8
// Want negative 100ns units.
NEGQ BX
MOVQ SP, R8 // ptime
MOVQ BX, (R8)
MOVQ $-1, CX // handle
MOVQ $0, DX // alertable
MOVQ runtime·NtWaitForSingleObject(SB), AX
CALL AX
RET