mirror of
https://github.com/golang/go
synced 2024-11-18 10:14:45 -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:
parent
2254785c3e
commit
45cff65502
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user