]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.19] runtime: fix usleep on linux/PPC64
authorPaul E. Murphy <murp@ibm.com>
Thu, 20 Oct 2022 22:01:01 +0000 (17:01 -0500)
committerMichael Knyszek <mknyszek@google.com>
Tue, 8 Nov 2022 18:43:38 +0000 (18:43 +0000)
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

src/runtime/sys_linux_ppc64x.s

index 6e9d8f56f1dd035b9f94223a62bf15fb6031668d..73edf1b0f94849f18e39f713ccbde7a2c0ee321f 100644 (file)
@@ -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