mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-26 16:51:01 +08:00
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
This commit is contained in:
parent
f38162977e
commit
e73d9fcafb
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user