]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: switch to os stack in windows osyield and usleep
authorAlex Brainman <alex.brainman@gmail.com>
Tue, 16 Jul 2013 02:36:05 +0000 (12:36 +1000)
committerAlex Brainman <alex.brainman@gmail.com>
Tue, 16 Jul 2013 02:36:05 +0000 (12:36 +1000)
Fixes #5831

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/11266043

src/pkg/runtime/os_windows.c
src/pkg/runtime/sys_windows_386.s
src/pkg/runtime/sys_windows_amd64.s

index 60160c3e16a3fd5b4a9d64086454e59ccf0945e9..5dcbd2c1e1cdf616f244c9b6843a3835e0a83b38 100644 (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)
 {
index d232bd115d52dd1f4168bca531419485315b82fb..d6f125981850a57c1abb6f28b81177927e5c5e6e 100644 (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
index 4837a02a5a16c01268447d136482abb8a2e25104..a8953d53905d0c8fa4fe0883e4d86bd4b27ae2f3 100644 (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