Skip to content

Commit 65f8635

Browse files
committed
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 #56374 Change-Id: I2e37ec218b9027efab6db4634eed1504c0c1b3c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/444735 Reviewed-by: Lynn Boger <[email protected]> Run-TryBot: Paul Murphy <[email protected]> Reviewed-by: David Chase <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Bryan Mills <[email protected]>
1 parent decdad3 commit 65f8635

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

src/runtime/sys_linux_ppc64x.s

+15-8
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,23 @@ TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
106106
MOVW R3, errno+16(FP)
107107
RET
108108

109+
// func usleep(usec uint32)
109110
TEXT runtime·usleep(SB),NOSPLIT,$16-4
110111
MOVW usec+0(FP), R3
111-
MOVD R3, R5
112-
MOVW $1000000, R4
113-
DIVD R4, R3
114-
MOVD R3, 8(R1)
115-
MOVW $1000, R4
116-
MULLD R3, R4
117-
SUB R4, R5
118-
MOVD R5, 16(R1)
112+
113+
// Use magic constant 0x8637bd06 and shift right 51
114+
// to perform usec/1000000.
115+
ORIS $0x8637, R0, R4 // Note, R0 always contains 0 here.
116+
OR $0xbd06, R4, R4
117+
MULLD R3, R4, R4 // Convert usec to S.
118+
SRD $51, R4, R4
119+
MOVD R4, 8(R1) // Store to tv_sec
120+
121+
MOVD $1000000, R5
122+
MULLW R4, R5, R5 // Convert tv_sec back into uS
123+
SUB R5, R3, R5 // Compute remainder uS.
124+
MULLD $1000, R5, R5 // Convert to nsec
125+
MOVD R5, 16(R1) // Store to tv_nsec
119126

120127
// nanosleep(&ts, 0)
121128
ADD $8, R1, R3

0 commit comments

Comments
 (0)