{"id":2227793,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2227793/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260424-force_rcu-v4-2-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/1.1/projects/14/?format=json","name":"QEMU Development","link_name":"qemu-devel","list_id":"qemu-devel.nongnu.org","list_email":"qemu-devel@nongnu.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260424-force_rcu-v4-2-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>","date":"2026-04-24T09:27:07","name":"[v4,2/6] qemu-thread: Add qemu_event_timedwait()","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"e34964a4b641076df4c4ffd4ce6fed6556b6ae13","submitter":{"id":90980,"url":"http://patchwork.ozlabs.org/api/1.1/people/90980/?format=json","name":"Akihiko Odaki","email":"odaki@rsg.ci.i.u-tokyo.ac.jp"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260424-force_rcu-v4-2-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp/mbox/","series":[{"id":501326,"url":"http://patchwork.ozlabs.org/api/1.1/series/501326/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501326","date":"2026-04-24T09:27:07","name":"virtio-gpu: Force RCU when unmapping blob","version":4,"mbox":"http://patchwork.ozlabs.org/series/501326/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2227793/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2227793/checks/","tags":{},"headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=fail reason=\"key not found in DNS\" header.d=rsg.ci.i.u-tokyo.ac.jp\n header.i=@rsg.ci.i.u-tokyo.ac.jp header.a=rsa-sha256 header.s=rs20250326\n header.b=B77EdOnM;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g271c3Nmmz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 19:28:36 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wGCpV-0007ts-BK; Fri, 24 Apr 2026 05:28:10 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <odaki@rsg.ci.i.u-tokyo.ac.jp>)\n id 1wGCp3-0007Mt-Ck\n for qemu-devel@nongnu.org; Fri, 24 Apr 2026 05:27:41 -0400","from www3579.sakura.ne.jp ([49.212.243.89])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <odaki@rsg.ci.i.u-tokyo.ac.jp>)\n id 1wGCoz-0007aC-Nd\n for qemu-devel@nongnu.org; Fri, 24 Apr 2026 05:27:41 -0400","from h205.csg.ci.i.u-tokyo.ac.jp (h205.csg.ci.i.u-tokyo.ac.jp\n [133.11.54.205]) (authenticated bits=0)\n by www3579.sakura.ne.jp (8.16.1/8.16.1) with ESMTPSA id 63O9RHIe004358\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO);\n Fri, 24 Apr 2026 18:27:26 +0900 (JST)\n (envelope-from odaki@rsg.ci.i.u-tokyo.ac.jp)"],"DKIM-Signature":"a=rsa-sha256; bh=rXcv6yelvtBYoc9z4CKug8RC1XR4ObzkiQj9RjCrBck=;\n c=relaxed/relaxed; d=rsg.ci.i.u-tokyo.ac.jp;\n h=From:Message-Id:To:Subject:Date;\n s=rs20250326; t=1777022846; v=1;\n b=B77EdOnMQ1HS2uu106kSWucys2Esk9gh7mOrX4lQd6NT0nlqzTzOppyRWqk3zHf9\n OBXNYG/KoSips4ezNX/icSgIySNMeWMbbGNS4G2FJ9J9vPYcKNOD9iPCMuNTy8l1\n r0BcTLzD2ZoRO+eLIUbKZwEb2dm0CtlRsc1e4Y9jYBD7YvnfMqdta1CugDpWDbR/\n ya1x4uuvry2pQC1kRFdo6IppDtF4Gdrj3P18pdbgs4HmOfn7IJO1v/Uoh1MwxQO2\n 3yrTwkqO4lq6YuiQel8NScjkYnJhzGK9g93Q6tpWVcbtUAfORwg7OyI8nTb6d83A\n oVXY/hraHNxueb/9w07MPg==","From":"Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>","Date":"Fri, 24 Apr 2026 18:27:07 +0900","Subject":"[PATCH v4 2/6] qemu-thread: Add qemu_event_timedwait()","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"7bit","Message-Id":"<20260424-force_rcu-v4-2-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>","References":"<20260424-force_rcu-v4-0-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>","In-Reply-To":"<20260424-force_rcu-v4-0-feccfaca0568@rsg.ci.i.u-tokyo.ac.jp>","To":"qemu-devel@nongnu.org, Dmitry Osipenko <dmitry.osipenko@collabora.com>","Cc":"Paolo Bonzini <pbonzini@redhat.com>,\n \"Michael S. Tsirkin\" <mst@redhat.com>,\n =?utf-8?q?Alex_Benn=C3=A9e?= <alex.bennee@linaro.org>,\n Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>","X-Mailer":"b4 0.16-dev-16047","Received-SPF":"pass client-ip=49.212.243.89;\n envelope-from=odaki@rsg.ci.i.u-tokyo.ac.jp; helo=www3579.sakura.ne.jp","X-Spam_score_int":"-16","X-Spam_score":"-1.7","X-Spam_bar":"-","X-Spam_report":"(-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1,\n DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=no autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"qemu development <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"},"content":"qemu_event_timedwait() is equivalent to qemu_event_wait(), except it has\na relative timeout.\n\nSigned-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>\nTested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>\n---\n include/qemu/thread-posix.h | 11 +++++++++++\n include/qemu/thread.h       |  9 ++++++++-\n util/event.c                | 31 ++++++++++++++++++++++++++-----\n util/qemu-thread-posix.c    | 11 +----------\n 4 files changed, 46 insertions(+), 16 deletions(-)","diff":"diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h\nindex 758808b705e4..11193b1580f8 100644\n--- a/include/qemu/thread-posix.h\n+++ b/include/qemu/thread-posix.h\n@@ -36,4 +36,15 @@ struct QemuThread {\n     pthread_t thread;\n };\n \n+static inline clockid_t qemu_timedwait_clockid(void)\n+{\n+#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK\n+    return CLOCK_MONOTONIC;\n+#else\n+    return CLOCK_REALTIME;\n+#endif\n+}\n+\n+void compute_abs_deadline(struct timespec *ts, int ms);\n+\n #endif\ndiff --git a/include/qemu/thread.h b/include/qemu/thread.h\nindex 98cc5c41ac58..8536859bcb3a 100644\n--- a/include/qemu/thread.h\n+++ b/include/qemu/thread.h\n@@ -201,7 +201,14 @@ void qemu_sem_destroy(QemuSemaphore *sem);\n void qemu_event_init(QemuEvent *ev, bool init);\n void qemu_event_set(QemuEvent *ev);\n void qemu_event_reset(QemuEvent *ev);\n-void qemu_event_wait(QemuEvent *ev);\n+bool qemu_event_timedwait(QemuEvent *ev, int ms);\n+\n+static inline void qemu_event_wait(QemuEvent *ev)\n+{\n+    while (!qemu_event_timedwait(ev, INT_MAX)) {\n+    }\n+}\n+\n void qemu_event_destroy(QemuEvent *ev);\n \n void qemu_thread_create(QemuThread *thread, const char *name,\ndiff --git a/util/event.c b/util/event.c\nindex 5a8141cd0e46..a7a5ee0aa5f5 100644\n--- a/util/event.c\n+++ b/util/event.c\n@@ -33,7 +33,15 @@ void qemu_event_init(QemuEvent *ev, bool init)\n {\n #ifndef HAVE_FUTEX\n     pthread_mutex_init(&ev->lock, NULL);\n+#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK\n+    pthread_condattr_t attr;\n+    pthread_condattr_init(&attr);\n+    pthread_condattr_setclock(&attr, qemu_timedwait_clockid());\n+    pthread_cond_init(&ev->cond, &attr);\n+    pthread_condattr_destroy(&attr);\n+#else\n     pthread_cond_init(&ev->cond, NULL);\n+#endif\n #endif\n \n     ev->value = (init ? EV_SET : EV_FREE);\n@@ -121,15 +129,17 @@ void qemu_event_reset(QemuEvent *ev)\n #endif\n }\n \n-void qemu_event_wait(QemuEvent *ev)\n+bool qemu_event_timedwait(QemuEvent *ev, int ms)\n {\n     assert(ev->initialized);\n \n #ifdef HAVE_FUTEX\n+    int64_t deadline = get_clock() + (int64_t)ms * SCALE_MS;\n+\n     while (true) {\n         /*\n-         * qemu_event_wait must synchronize with qemu_event_set even if it does\n-         * not go down the slow path, so this load-acquire is needed that\n+         * qemu_event_timedwait must synchronize with qemu_event_set even if it\n+         * does not go down the slow path, so this load-acquire is needed that\n          * synchronizes with the first memory barrier in qemu_event_set().\n          */\n         unsigned value = qatomic_load_acquire(&ev->value);\n@@ -159,13 +169,24 @@ void qemu_event_wait(QemuEvent *ev)\n          * a smp_mb() pairing with the second barrier of qemu_event_set().\n          * The barrier is inside the FUTEX_WAIT system call.\n          */\n-        qemu_futex_wait(ev, EV_BUSY);\n+        if (!qemu_futex_timedwait(ev, EV_BUSY, deadline)) {\n+            return false;\n+        }\n     }\n #else\n+    struct timespec ts;\n+\n+    compute_abs_deadline(&ts, ms);\n+\n     pthread_mutex_lock(&ev->lock);\n     while (qatomic_read(&ev->value) != EV_SET) {\n-        pthread_cond_wait(&ev->cond, &ev->lock);\n+        if (pthread_cond_timedwait(&ev->cond, &ev->lock, &ts)) {\n+            pthread_mutex_unlock(&ev->lock);\n+            return false;\n+        }\n     }\n     pthread_mutex_unlock(&ev->lock);\n #endif\n+\n+    return true;\n }\ndiff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c\nindex bd1c2ad2a596..dc1125006ceb 100644\n--- a/util/qemu-thread-posix.c\n+++ b/util/qemu-thread-posix.c\n@@ -59,16 +59,7 @@ static void error_exit(int err, const char *msg)\n     abort();\n }\n \n-static inline clockid_t qemu_timedwait_clockid(void)\n-{\n-#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK\n-    return CLOCK_MONOTONIC;\n-#else\n-    return CLOCK_REALTIME;\n-#endif\n-}\n-\n-static void compute_abs_deadline(struct timespec *ts, int ms)\n+void compute_abs_deadline(struct timespec *ts, int ms)\n {\n     clock_gettime(qemu_timedwait_clockid(), ts);\n     ts->tv_nsec += (ms % 1000) * 1000000;\n","prefixes":["v4","2/6"]}