diff options
| author | Nikhil Benesch <nikhil.benesch@gmail.com> | 2018-06-23 01:15:19 -0400 |
|---|---|---|
| committer | Josh Bleecher Snyder <josharian@gmail.com> | 2018-06-25 02:22:05 +0000 |
| commit | 6fdbed0543cf8f4e21ab45938f5b04028877e861 (patch) | |
| tree | c90fc20c61c1221caadec468a0510f65c5fd7a5b /src/runtime/sys_darwin.go | |
| parent | 291e57f057c480889be3cc7abf83698f8c6646ba (diff) | |
| download | go-6fdbed0543cf8f4e21ab45938f5b04028877e861.tar.xz | |
runtime: respect timeout in semasleep on Darwin
semasleep on Darwin was refactored in https://golang.org/cl/118736 to
use the pthread_cond_timedwait function from libc. The new code
incorrectly assumed that pthread_cond_timedwait took a timeout relative
to the current time, when it in fact it takes a timeout specified in
absolute time. semasleep thus specified a timeout well in the past,
causing it to immediately exceed the timeout and spin hot. This was the
source of a large performance hit to CockroachDB (#26019).
Adjust semasleep to instead call pthread_cond_timedwait_relative_np,
which properly interprets its timeout parameter as relative to the
current time.
pthread_cond_timedwait_relative_np is non-portable, but using
pthread_cond_timedwait correctly would require two calls to
gettimeofday: one in the runtime package to convert the relative timeout
to absolute time, then another in the pthread library to convert back to
a relative offset [0], as the Darwin kernel expects a relative offset.
[0]: https://opensource.apple.com/source/libpthread/libpthread-301.30.1/src/pthread_cond.c.auto.html
Fix #26019.
Change-Id: I1a8c2429f79513b43d2b256365cd9166d235af8b
Reviewed-on: https://go-review.googlesource.com/120635
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/runtime/sys_darwin.go')
| -rw-r--r-- | src/runtime/sys_darwin.go | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go index ef5aef1929..f0d0815903 100644 --- a/src/runtime/sys_darwin.go +++ b/src/runtime/sys_darwin.go @@ -287,10 +287,10 @@ func pthread_cond_wait_trampoline() //go:nosplit //go:cgo_unsafe_args -func pthread_cond_timedwait(c *pthreadcond, m *pthreadmutex, t *timespec) int32 { - return libcCall(unsafe.Pointer(funcPC(pthread_cond_timedwait_trampoline)), unsafe.Pointer(&c)) +func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 { + return libcCall(unsafe.Pointer(funcPC(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c)) } -func pthread_cond_timedwait_trampoline() +func pthread_cond_timedwait_relative_np_trampoline() //go:nosplit //go:cgo_unsafe_args @@ -348,7 +348,7 @@ func closeonexec(fd int32) { //go:cgo_import_dynamic libc_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_pthread_cond_init pthread_cond_init "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib" -//go:cgo_import_dynamic libc_pthread_cond_timedwait pthread_cond_timedwait "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib" // Magic incantation to get libSystem actually dynamically linked. |
