diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-09-26 15:03:53 -0400 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-09-27 09:30:23 -0700 |
commit | e73d9fcafbd07bc3714fbaf8a82db71d50015c92 (patch) | |
tree | 44d8382e7696a4aa4ecbc6e116b2654775215402 /libgo/go | |
parent | f38162977e2b7efaa75233a0cba2a30a2b7f5132 (diff) | |
download | gcc-e73d9fcafbd07bc3714fbaf8a82db71d50015c92.zip gcc-e73d9fcafbd07bc3714fbaf8a82db71d50015c92.tar.gz gcc-e73d9fcafbd07bc3714fbaf8a82db71d50015c92.tar.bz2 |
runtime: portable access to sigev_notify_thread_id
Previously, libgo relied on the _sigev_un implementation-specific
field in struct sigevent, which is only available on glibc.
This patch uses the sigev_notify_thread_id macro instead which is
mandated by timer_create(2). In theory, this should work with any libc
implementation for Linux. Unfortunately, there is an open glibc bug
as glibc does not define this macro. For this reason, a glibc-specific
workaround is required. Other libcs (such as musl) define the macro
and don't require the workaround.
See https://sourceware.org/bugzilla/show_bug.cgi?id=27417
This makes libgo compatible with musl libc.
Based on patch by Sören Tempel.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/434755
Diffstat (limited to 'libgo/go')
-rw-r--r-- | libgo/go/runtime/os_linux.go | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go index 96fb178..2b2d827 100644 --- a/libgo/go/runtime/os_linux.go +++ b/libgo/go/runtime/os_linux.go @@ -22,6 +22,12 @@ type mOS struct { profileTimerValid uint32 } +// setSigeventTID is written in C to set the sigev_notify_thread_id +// field of a sigevent struct. +// +//go:noescape +func setSigeventTID(*_sigevent, int32) + func getProcID() uint64 { return uint64(gettid()) } @@ -52,9 +58,12 @@ const ( ) // Atomically, +// // if(*addr == val) sleep +// // Might be woken up spuriously; that's allowed. // Don't sleep longer than ns; ns < 0 means forever. +// //go:nosplit func futexsleep(addr *uint32, val uint32, ns int64) { // Some Linux kernels have a bug where futex of @@ -73,6 +82,7 @@ func futexsleep(addr *uint32, val uint32, ns int64) { } // If any procs are sleeping on addr, wake up at most cnt. +// //go:nosplit func futexwakeup(addr *uint32, cnt uint32) { ret := futex(unsafe.Pointer(addr), _FUTEX_WAKE_PRIVATE, cnt, nil, nil, 0) @@ -365,7 +375,7 @@ func setThreadCPUProfiler(hz int32) { var sevp _sigevent sevp.sigev_notify = _SIGEV_THREAD_ID sevp.sigev_signo = _SIGPROF - *((*int32)(unsafe.Pointer(&sevp._sigev_un))) = int32(mp.procid) + setSigeventTID(&sevp, int32(mp.procid)) ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, &sevp, &timerid) if ret != 0 { // If we cannot create a timer for this M, leave profileTimerValid false |