]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
runtime: portable access to sigev_notify_thread_id
authorIan Lance Taylor <iant@golang.org>
Mon, 26 Sep 2022 19:03:53 +0000 (15:03 -0400)
committerIan Lance Taylor <iant@golang.org>
Tue, 27 Sep 2022 16:30:23 +0000 (09:30 -0700)
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

gcc/go/gofrontend/MERGE
libgo/go/runtime/os_linux.go
libgo/runtime/go-signal.c

index 73aa712dbdf8434fc9d481287d32156406e5ecda..4793c821eba855647f7840ab084044961ac88e65 100644 (file)
@@ -1,4 +1,4 @@
-0140cca9bc0fad1108c7ed369376ac71cc4bfecf
+8f1a91aeff400d572857895b7f5e863ec5a4d93e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 96fb178870e674ead97b4ee4c00f4d567952ca1f..2b2d827cee89322531005e707fc3850ed8dbb3a5 100644 (file)
@@ -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
index 528d9b6d9fe239e1519ac6138b10fc62e388d8f7..aa1b6305ad09d90e6938330b5fda679d7b61becf 100644 (file)
@@ -183,6 +183,24 @@ setSigactionHandler(struct sigaction* sa, uintptr handler)
        sa->sa_sigaction = (void*)(handler);
 }
 
+#ifdef __linux__
+
+// Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=27417
+#ifndef sigev_notify_thread_id
+  #define sigev_notify_thread_id _sigev_un._tid
+#endif
+
+void setSigeventTID(struct sigevent*, int32_t)
+       __asm__ (GOSYM_PREFIX "runtime.setSigeventTID");
+
+void
+setSigeventTID(struct sigevent *sev, int32_t v)
+{
+       sev->sigev_notify_thread_id = v;
+}
+
+#endif // defined(__linux__)
+
 // C code to fetch values from the siginfo_t and ucontext_t pointers
 // passed to a signal handler.