mirror of
https://github.com/golang/go
synced 2024-11-02 09:28:34 +00:00
runtime: implement osyield in Go instead of assembly on Windows
Windows APIs are normally not arch-specific, so it's better to implement them in Go instead of assembly. It was previously implemented in assembly because it was the only way to support calls without a valid g. This CL defines a new function, stdcall_no_g, that can be used in such cases. Change-Id: I26a223b918c6c462b06ac256bdacf9ddb78752bc Reviewed-on: https://go-review.googlesource.com/c/go/+/526476 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Run-TryBot: Quim Muntal <quimmuntal@gmail.com> Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
parent
c4af8abae1
commit
d73a33f1c3
5 changed files with 33 additions and 41 deletions
|
@ -955,6 +955,22 @@ func mdestroy(mp *m) {
|
|||
}
|
||||
}
|
||||
|
||||
// asmstdcall_trampoline calls asmstdcall converting from Go to C calling convention.
|
||||
func asmstdcall_trampoline(args unsafe.Pointer)
|
||||
|
||||
// stdcall_no_g calls asmstdcall on os stack without using g.
|
||||
//
|
||||
//go:nosplit
|
||||
func stdcall_no_g(fn stdFunction, n int, args uintptr) uintptr {
|
||||
libcall := libcall{
|
||||
fn: uintptr(unsafe.Pointer(fn)),
|
||||
n: uintptr(n),
|
||||
args: args,
|
||||
}
|
||||
asmstdcall_trampoline(noescape(unsafe.Pointer(&libcall)))
|
||||
return libcall.r1
|
||||
}
|
||||
|
||||
// Calling stdcall on os stack.
|
||||
// May run during STW, so write barriers are not allowed.
|
||||
//
|
||||
|
@ -1054,16 +1070,17 @@ func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
|
|||
|
||||
// These must run on the system stack only.
|
||||
func usleep2(dt int32)
|
||||
func switchtothread()
|
||||
|
||||
//go:nosplit
|
||||
func osyield_no_g() {
|
||||
switchtothread()
|
||||
stdcall_no_g(_SwitchToThread, 0, 0)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func osyield() {
|
||||
systemstack(switchtothread)
|
||||
systemstack(func() {
|
||||
stdcall0(_SwitchToThread)
|
||||
})
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#define TEB_TlsSlots 0xE10
|
||||
#define TEB_ArbitraryPtr 0x14
|
||||
|
||||
TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
|
||||
JMP runtime·asmstdcall(SB)
|
||||
|
||||
// void runtime·asmstdcall(void *c);
|
||||
TEXT runtime·asmstdcall(SB),NOSPLIT,$0
|
||||
MOVL fn+0(FP), BX
|
||||
|
@ -248,14 +251,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20-4
|
|||
MOVL BP, SP
|
||||
RET
|
||||
|
||||
// Runs on OS stack.
|
||||
TEXT runtime·switchtothread(SB),NOSPLIT,$0
|
||||
MOVL SP, BP
|
||||
MOVL runtime·_SwitchToThread(SB), AX
|
||||
CALL AX
|
||||
MOVL BP, SP
|
||||
RET
|
||||
|
||||
TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
|
||||
loop:
|
||||
MOVL (_INTERRUPT_TIME+time_hi1), AX
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
#define TEB_TlsSlots 0x1480
|
||||
#define TEB_ArbitraryPtr 0x28
|
||||
|
||||
TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
|
||||
MOVQ AX, CX
|
||||
JMP runtime·asmstdcall(SB)
|
||||
|
||||
// void runtime·asmstdcall(void *c);
|
||||
TEXT runtime·asmstdcall(SB),NOSPLIT,$16
|
||||
MOVQ SP, AX
|
||||
|
@ -258,18 +262,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$48-4
|
|||
MOVQ 40(SP), SP
|
||||
RET
|
||||
|
||||
// Runs on OS stack.
|
||||
TEXT runtime·switchtothread(SB),NOSPLIT,$0
|
||||
MOVQ SP, AX
|
||||
ANDQ $~15, SP // alignment as per Windows requirement
|
||||
SUBQ $(48), SP // room for SP and 4 args as per Windows requirement
|
||||
// plus one extra word to keep stack 16 bytes aligned
|
||||
MOVQ AX, 32(SP)
|
||||
MOVQ runtime·_SwitchToThread(SB), AX
|
||||
CALL AX
|
||||
MOVQ 32(SP), SP
|
||||
RET
|
||||
|
||||
TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
|
||||
MOVQ $_INTERRUPT_TIME, DI
|
||||
MOVQ time_lo(DI), AX
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
// Note: For system ABI, R0-R3 are args, R4-R11 are callee-save.
|
||||
|
||||
TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
|
||||
B runtime·asmstdcall(SB)
|
||||
|
||||
// void runtime·asmstdcall(void *c);
|
||||
TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVM.DB.W [R4, R5, R14], (R13) // push {r4, r5, lr}
|
||||
|
@ -211,16 +214,6 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$0-4
|
|||
MOVW R4, R13 // Restore SP
|
||||
MOVM.IA.W (R13), [R4, R15] // pop {R4, pc}
|
||||
|
||||
// Runs on OS stack.
|
||||
TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVM.DB.W [R4, R14], (R13) // push {R4, lr}
|
||||
MOVW R13, R4
|
||||
BIC $0x7, R13 // alignment for ABI
|
||||
MOVW runtime·_SwitchToThread(SB), R0
|
||||
BL (R0)
|
||||
MOVW R4, R13 // restore stack pointer
|
||||
MOVM.IA.W (R13), [R4, R15] // pop {R4, pc}
|
||||
|
||||
TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
|
||||
B runtime·armPublicationBarrier(SB)
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
//
|
||||
// load_g and save_g (in tls_arm64.s) clobber R27 (REGTMP) and R0.
|
||||
|
||||
TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
|
||||
B runtime·asmstdcall(SB)
|
||||
|
||||
// void runtime·asmstdcall(void *c);
|
||||
TEXT runtime·asmstdcall(SB),NOSPLIT,$16
|
||||
STP (R19, R20), 16(RSP) // save old R19, R20
|
||||
|
@ -240,14 +243,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$32-4
|
|||
ADD $16, RSP
|
||||
RET
|
||||
|
||||
// Runs on OS stack.
|
||||
TEXT runtime·switchtothread(SB),NOSPLIT,$16-0
|
||||
MOVD runtime·_SwitchToThread(SB), R0
|
||||
SUB $16, RSP // skip over saved frame pointer below RSP
|
||||
BL (R0)
|
||||
ADD $16, RSP
|
||||
RET
|
||||
|
||||
TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
|
||||
MOVD $_INTERRUPT_TIME, R3
|
||||
MOVD time_lo(R3), R0
|
||||
|
|
Loading…
Reference in a new issue