aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compatfd.c11
-rw-r--r--compatfd.h1
-rw-r--r--qemu-timer.c8
3 files changed, 20 insertions, 0 deletions
diff --git a/compatfd.c b/compatfd.c
index 41586ceaea..31654c62a6 100644
--- a/compatfd.c
+++ b/compatfd.c
@@ -115,3 +115,14 @@ int qemu_signalfd(const sigset_t *mask)
return qemu_signalfd_compat(mask);
}
+
+bool qemu_signalfd_available(void)
+{
+#ifdef CONFIG_SIGNALFD
+ errno = 0;
+ syscall(SYS_signalfd, -1, NULL, _NSIG / 8);
+ return errno != ENOSYS;
+#else
+ return false;
+#endif
+}
diff --git a/compatfd.h b/compatfd.h
index fc3791520f..6b04877b97 100644
--- a/compatfd.h
+++ b/compatfd.h
@@ -39,5 +39,6 @@ struct qemu_signalfd_siginfo {
};
int qemu_signalfd(const sigset_t *mask);
+bool qemu_signalfd_available(void);
#endif
diff --git a/qemu-timer.c b/qemu-timer.c
index f95374c7c1..30e8f1272e 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -831,6 +831,8 @@ static int64_t qemu_next_alarm_deadline(void)
#if defined(__linux__)
+#include "compatfd.h"
+
static int dynticks_start_timer(struct qemu_alarm_timer *t)
{
struct sigevent ev;
@@ -850,6 +852,12 @@ static int dynticks_start_timer(struct qemu_alarm_timer *t)
memset(&ev, 0, sizeof(ev));
ev.sigev_value.sival_int = 0;
ev.sigev_notify = SIGEV_SIGNAL;
+#ifdef SIGEV_THREAD_ID
+ if (qemu_signalfd_available()) {
+ ev.sigev_notify = SIGEV_THREAD_ID;
+ ev._sigev_un._tid = qemu_get_thread_id();
+ }
+#endif /* SIGEV_THREAD_ID */
ev.sigev_signo = SIGALRM;
if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {