From e54e808d781745e12b0f7ce471934735750e7015 Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Thu, 20 Oct 2022 17:01:01 -0500 Subject: [release-branch.go1.18] runtime: fix usleep on linux/PPC64 The existing implementation fails to convert the remainder microseconds to nanoseconds. This causes sysmon to consume much more cpu, and generate lots of context switches. We can also do a little better here to avoid division by a constant. I used go to determine the magic numbers. Fixes #56396 Change-Id: I2e37ec218b9027efab6db4634eed1504c0c1b3c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/444735 Reviewed-by: Lynn Boger Run-TryBot: Paul Murphy Reviewed-by: David Chase TryBot-Result: Gopher Robot Reviewed-by: Bryan Mills Reviewed-on: https://go-review.googlesource.com/c/go/+/445156 --- src/runtime/sys_linux_ppc64x.s | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s index 01d6c85597..b86a820ab2 100644 --- a/src/runtime/sys_linux_ppc64x.s +++ b/src/runtime/sys_linux_ppc64x.s @@ -119,16 +119,23 @@ TEXT runtimeĀ·pipe2(SB),NOSPLIT|NOFRAME,$0-20 MOVW R3, errno+16(FP) RET +// func usleep(usec uint32) TEXT runtimeĀ·usleep(SB),NOSPLIT,$16-4 MOVW usec+0(FP), R3 - MOVD R3, R5 - MOVW $1000000, R4 - DIVD R4, R3 - MOVD R3, 8(R1) - MOVW $1000, R4 - MULLD R3, R4 - SUB R4, R5 - MOVD R5, 16(R1) + + // Use magic constant 0x8637bd06 and shift right 51 + // to perform usec/1000000. + ORIS $0x8637, R0, R4 // Note, R0 always contains 0 here. + OR $0xbd06, R4, R4 + MULLD R3, R4, R4 // Convert usec to S. + SRD $51, R4, R4 + MOVD R4, 8(R1) // Store to tv_sec + + MOVD $1000000, R5 + MULLW R4, R5, R5 // Convert tv_sec back into uS + SUB R5, R3, R5 // Compute remainder uS. + MULLD $1000, R5, R5 // Convert to nsec + MOVD R5, 16(R1) // Store to tv_nsec // nanosleep(&ts, 0) ADD $8, R1, R3 -- cgit v1.2.3-54-g00ecf