diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index df32e90fda8..a54ca110e53 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -597,7 +597,7 @@ CALLFN(·call268435456, 268435456) CALLFN(·call536870912, 536870912) CALLFN(·call1073741824, 1073741824) -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0 MOVL cycles+0(FP), AX again: PAUSE diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s index 525df96f002..dbf54487a7f 100644 --- a/src/runtime/asm_amd64.s +++ b/src/runtime/asm_amd64.s @@ -815,7 +815,7 @@ CALLFN(·call268435456, 268435456) CALLFN(·call536870912, 536870912) CALLFN(·call1073741824, 1073741824) -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0 MOVL cycles+0(FP), AX again: PAUSE diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s index d371e80d848..9373846c74a 100644 --- a/src/runtime/asm_arm.s +++ b/src/runtime/asm_arm.s @@ -839,7 +839,7 @@ TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-12 TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-12 JMP runtime·memhash64Fallback(SB) -TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0 +TEXT runtime·procyieldAsm(SB),NOSPLIT|NOFRAME,$0 MOVW cycles+0(FP), R1 MOVW $0, R0 yieldloop: diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s index a0e82ec830f..94a5b9ee6c8 100644 --- a/src/runtime/asm_arm64.s +++ b/src/runtime/asm_arm64.s @@ -1036,7 +1036,7 @@ aesloop: VMOV V0.D[0], R0 RET -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0 MOVWU cycles+0(FP), R0 again: YIELD diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s index 586bf89a5d3..a6a5519afb6 100644 --- a/src/runtime/asm_loong64.s +++ b/src/runtime/asm_loong64.s @@ -505,7 +505,7 @@ CALLFN(·call268435456, 268435456) CALLFN(·call536870912, 536870912) CALLFN(·call1073741824, 1073741824) -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0 RET // Save state of caller into g->sched. diff --git a/src/runtime/asm_mips64x.s b/src/runtime/asm_mips64x.s index d4523b4a74c..532eca752ff 100644 --- a/src/runtime/asm_mips64x.s +++ b/src/runtime/asm_mips64x.s @@ -408,7 +408,7 @@ CALLFN(·call268435456, 268435456) CALLFN(·call536870912, 536870912) CALLFN(·call1073741824, 1073741824) -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0 RET // Save state of caller into g->sched, diff --git a/src/runtime/asm_mipsx.s b/src/runtime/asm_mipsx.s index ec352f58289..2dc3f1c3ad7 100644 --- a/src/runtime/asm_mipsx.s +++ b/src/runtime/asm_mipsx.s @@ -406,7 +406,7 @@ CALLFN(·call268435456, 268435456) CALLFN(·call536870912, 536870912) CALLFN(·call1073741824, 1073741824) -TEXT runtime·procyield(SB),NOSPLIT,$0-4 +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-4 RET // Save state of caller into g->sched, diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s index 127010ef971..e461764e55d 100644 --- a/src/runtime/asm_ppc64x.s +++ b/src/runtime/asm_ppc64x.s @@ -612,7 +612,7 @@ CALLFN(·call268435456, 268435456) CALLFN(·call536870912, 536870912) CALLFN(·call1073741824, 1073741824) -TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0-4 +TEXT runtime·procyieldAsm(SB),NOSPLIT|NOFRAME,$0-4 MOVW cycles+0(FP), R7 // POWER does not have a pause/yield instruction equivalent. // Instead, we can lower the program priority by setting the diff --git a/src/runtime/asm_riscv64.s b/src/runtime/asm_riscv64.s index efe6047419e..5bd16181ee2 100644 --- a/src/runtime/asm_riscv64.s +++ b/src/runtime/asm_riscv64.s @@ -367,8 +367,8 @@ TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0 MOV gobuf_pc(T0), T0 JALR ZERO, T0 -// func procyield(cycles uint32) -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +// func procyieldAsm(cycles uint32) +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0 RET // Switch to m->g0's stack, call fn(g). diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s index 4cc1c0eb104..bb29845f583 100644 --- a/src/runtime/asm_s390x.s +++ b/src/runtime/asm_s390x.s @@ -506,7 +506,7 @@ CALLFN(·call1073741824, 1073741824) TEXT callfnMVC<>(SB),NOSPLIT|NOFRAME,$0-0 MVC $1, 0(R4), 0(R6) -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0 RET // Save state of caller into g->sched, diff --git a/src/runtime/asm_wasm.s b/src/runtime/asm_wasm.s index 85aa52e0f79..c46cb4ae464 100644 --- a/src/runtime/asm_wasm.s +++ b/src/runtime/asm_wasm.s @@ -200,7 +200,7 @@ TEXT runtime·asminit(SB), NOSPLIT, $0-0 TEXT ·publicationBarrier(SB), NOSPLIT, $0-0 RET -TEXT runtime·procyield(SB), NOSPLIT, $0-0 // FIXME +TEXT runtime·procyieldAsm(SB), NOSPLIT, $0-0 // FIXME RET TEXT runtime·breakpoint(SB), NOSPLIT, $0-0 diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go index 20fc1c59ad9..16922835413 100644 --- a/src/runtime/stubs.go +++ b/src/runtime/stubs.go @@ -274,7 +274,23 @@ func reflectcall(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSi // See go.dev/issue/67401. // //go:linkname procyield -func procyield(cycles uint32) +//go:nosplit +func procyield(cycles uint32) { + if cycles == 0 { + return + } + procyieldAsm(cycles) +} + +// procyieldAsm is the assembly implementation of procyield. +// +// It may loop infinitely if called with cycles == 0. Prefer +// procyield, which will compile down to nothing in such cases, +// instead. +// +// FIXME: The implementation really should not loop infinitely if +// the number of cycles is 0. +func procyieldAsm(cycles uint32) type neverCallThisFunction struct{}