From 1caa06299c9a29f5009c92ffd82bc888d5a50f36 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Seo Date: Tue, 29 May 2018 16:00:38 -0300 Subject: [PATCH] runtime: implement procyield properly for ppc64x The procyield() function should yield the processor as in other architectures. On ppc64x, this is achieved by setting the Program Priority Register to 'low priority' prior to the spin loop, and setting it back to 'medium-low priority' afterwards. benchmark old ns/op new ns/op delta BenchmarkMakeChan/Byte-8 87.7 86.6 -1.25% BenchmarkMakeChan/Int-8 107 106 -0.93% BenchmarkMakeChan/Ptr-8 201 204 +1.49% BenchmarkMakeChan/Struct/0-8 78.2 79.7 +1.92% BenchmarkMakeChan/Struct/32-8 196 200 +2.04% BenchmarkMakeChan/Struct/40-8 236 230 -2.54% BenchmarkChanNonblocking-8 8.64 8.85 +2.43% BenchmarkChanUncontended-8 5577 5598 +0.38% BenchmarkChanContended-8 66106 51529 -22.05% BenchmarkChanSync-8 451 441 -2.22% BenchmarkChanSyncWork-8 9155 9170 +0.16% BenchmarkChanProdCons0-8 1585 1083 -31.67% BenchmarkChanProdCons10-8 1094 838 -23.40% BenchmarkChanProdCons100-8 831 657 -20.94% BenchmarkChanProdConsWork0-8 1471 941 -36.03% BenchmarkChanProdConsWork10-8 1033 721 -30.20% BenchmarkChanProdConsWork100-8 730 511 -30.00% BenchmarkChanCreation-8 135 128 -5.19% BenchmarkChanSem-8 602 463 -23.09% BenchmarkChanPopular-8 3017466 2188441 -27.47% Fixes #25625 Change-Id: Iacb1c888d3c066902152b8367500348fb631c5f9 Reviewed-on: https://go-review.googlesource.com/115376 Run-TryBot: Lynn Boger TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/vet/all/whitelist/linux_ppc64x.txt | 1 - src/runtime/asm_ppc64x.s | 14 +++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/cmd/vet/all/whitelist/linux_ppc64x.txt b/src/cmd/vet/all/whitelist/linux_ppc64x.txt index 21e87e37d8c836..0091d97110b2d1 100644 --- a/src/cmd/vet/all/whitelist/linux_ppc64x.txt +++ b/src/cmd/vet/all/whitelist/linux_ppc64x.txt @@ -2,4 +2,3 @@ runtime/sys_linux_ppc64x.s: [GOARCH] _sigtramp: function _sigtramp missing Go declaration runtime/sys_linux_ppc64x.s: [GOARCH] _cgoSigtramp: function _cgoSigtramp missing Go declaration -runtime/asm_ppc64x.s: [GOARCH] procyield: use of 24(R1) points beyond argument frame diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s index b6a797640df217..0886de9f2ba7c7 100644 --- a/src/runtime/asm_ppc64x.s +++ b/src/runtime/asm_ppc64x.s @@ -457,7 +457,19 @@ CALLFN(·call268435456, 268435456) CALLFN(·call536870912, 536870912) CALLFN(·call1073741824, 1073741824) -TEXT runtime·procyield(SB),NOSPLIT,$0-0 +TEXT runtime·procyield(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 + // Program Priority Register prior to the wait loop and set it + // back to default afterwards. On Linux, the default priority is + // medium-low. For details, see page 837 of the ISA 3.0. + OR R1, R1, R1 // Set PPR priority to low +again: + SUB $1, R7 + CMP $0, R7 + BNE again + OR R6, R6, R6 // Set PPR priority back to medium-low RET // void jmpdefer(fv, sp);