aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul E. Murphy <murp@ibm.com>2022-10-20 17:01:01 -0500
committerMichael Knyszek <mknyszek@google.com>2022-11-08 18:43:38 +0000
commit23fd10b3780e44da5fa019a7bd712729e6acfef7 (patch)
tree6ba84947ebf450cce22bfd65ce4815c7089877c4
parent6109c07ec4cf2b26eba9441ad5148f8dcb8c6497 (diff)
downloadgo-23fd10b3780e44da5fa019a7bd712729e6acfef7.tar.gz
go-23fd10b3780e44da5fa019a7bd712729e6acfef7.zip
[release-branch.go1.19] 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 #56397 Change-Id: I2e37ec218b9027efab6db4634eed1504c0c1b3c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/444735 Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Run-TryBot: Paul Murphy <murp@ibm.com> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/445157
-rw-r--r--src/runtime/sys_linux_ppc64x.s23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index 6e9d8f56f1..73edf1b0f9 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -111,16 +111,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