From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from magnesium.8pit.net (magnesium.8pit.net [45.76.88.171]) by sourceware.org (Postfix) with ESMTPS id 50C623858C52; Fri, 23 Sep 2022 13:59:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 50C623858C52 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=soeren-tempel.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=soeren-tempel.net DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; s=opensmtpd; bh=4oCfZ5j7ah cUiZSyk6v5oWFgyItzL0sdoJhV/1XpHdc=; h=references:in-reply-to:date: subject:cc:to:from; d=soeren-tempel.net; b=h7UlAc94ylvFklB1xx85F0U3JQ4 rLVpLGL3Szen/hjj7M61uRI4e9t6AHTRzsSFCL9IZEO1xLGx4y4nS4/1UjoAVsXkRwsqGB cZTK6fVPv28LLi5Etcoo97QMV81F2MWHDdGMBOd269AHloTrYt8PRSXfOewI83PjIbuEqk 2/Us= Received: from localhost ( [2a02:8109:3b40:22d0:38b7:218:15f1:f8c6]) by magnesium.8pit.net (OpenSMTPD) with ESMTPSA id 02f8c784 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:YES); Fri, 23 Sep 2022 15:59:25 +0200 (CEST) From: soeren@soeren-tempel.net To: iant@golang.org Cc: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: [PATCH v2] libgo: Portable access to thread ID in struct sigevent Date: Fri, 23 Sep 2022 15:59:14 +0200 Message-Id: <20220923135914.24219-1-soeren@soeren-tempel.net> X-Mailer: git-send-email 2.37.3 In-Reply-To: <2D7KNXY512R77.2ELCGV3AMTY0A@8pit.net> References: <2D7KNXY512R77.2ELCGV3AMTY0A@8pit.net> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Sören Tempel Tested on x86_64 Arch Linux (glibc) and Alpine Linux (musl libc). 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. This makes go_signal compatible with musl libc. See: https://sourceware.org/bugzilla/show_bug.cgi?id=27417 Signed-off-by: Sören Tempel --- Changes since v1: Add workaround for glibc. libgo/go/runtime/os_linux.go | 4 +++- libgo/runtime/go-signal.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go index 96fb1788..6653d85e 100644 --- a/libgo/go/runtime/os_linux.go +++ b/libgo/go/runtime/os_linux.go @@ -22,6 +22,8 @@ type mOS struct { profileTimerValid uint32 } +func setProcID(uintptr, int32) + func getProcID() uint64 { return uint64(gettid()) } @@ -365,7 +367,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) + setProcID(uintptr(unsafe.Pointer(&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 diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c index 528d9b6d..c56350cc 100644 --- a/libgo/runtime/go-signal.c +++ b/libgo/runtime/go-signal.c @@ -16,6 +16,11 @@ #define SA_RESTART 0 #endif +// Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=27417 +#if __linux__ && !defined(sigev_notify_thread_id) + #define sigev_notify_thread_id _sigev_un._tid +#endif + #ifdef USING_SPLIT_STACK extern void __splitstack_getcontext(void *context[10]); @@ -183,6 +188,16 @@ setSigactionHandler(struct sigaction* sa, uintptr handler) sa->sa_sigaction = (void*)(handler); } +void setProcID(uintptr_t, int32_t) + __asm__ (GOSYM_PREFIX "runtime.setProcID"); + +void +setProcID(uintptr_t ptr, int32_t v) +{ + struct sigevent *s = (void *)ptr; + s->sigev_notify_thread_id = v; +} + // C code to fetch values from the siginfo_t and ucontext_t pointers // passed to a signal handler.