From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40943) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cCNHU-0002OL-KZ for qemu-devel@nongnu.org; Thu, 01 Dec 2016 04:03:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cCNHQ-0005nC-Io for qemu-devel@nongnu.org; Thu, 01 Dec 2016 04:03:52 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:33095) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cCNHQ-0005mx-Bt for qemu-devel@nongnu.org; Thu, 01 Dec 2016 04:03:48 -0500 Received: by mail-wm0-x244.google.com with SMTP id u144so33010438wmu.0 for ; Thu, 01 Dec 2016 01:03:47 -0800 (PST) Sender: Paolo Bonzini From: Paolo Bonzini Date: Thu, 1 Dec 2016 10:03:43 +0100 Message-Id: <20161201090343.16448-1-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH] qemu-timer: check active_timers outside lock/event List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: stefanha@redhat.com, famz@redhat.com This avoids taking the active_timers_lock or resetting/setting the timers_done_ev if there are no active timers. This removes a small (2-3%) source of overhead for dataplane. The list is then checked again inside the lock, or a NULL pointer could be dereferenced. Signed-off-by: Paolo Bonzini --- qemu-timer.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index 9299cdc..ff620ec 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -174,7 +174,7 @@ void qemu_clock_enable(QEMUClockType type, bool enabled) bool timerlist_has_timers(QEMUTimerList *timer_list) { - return !!timer_list->active_timers; + return !!atomic_read(&timer_list->active_timers); } bool qemu_clock_has_timers(QEMUClockType type) @@ -187,6 +187,10 @@ bool timerlist_expired(QEMUTimerList *timer_list) { int64_t expire_time; + if (!atomic_read(&timer_list->active_timers)) { + return false; + } + qemu_mutex_lock(&timer_list->active_timers_lock); if (!timer_list->active_timers) { qemu_mutex_unlock(&timer_list->active_timers_lock); @@ -214,6 +218,10 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) int64_t delta; int64_t expire_time; + if (!atomic_read(&timer_list->active_timers)) { + return -1; + } + if (!timer_list->clock->enabled) { return -1; } @@ -363,7 +371,7 @@ static void timer_del_locked(QEMUTimerList *timer_list, QEMUTimer *ts) if (!t) break; if (t == ts) { - *pt = t->next; + atomic_set(pt, t->next); break; } pt = &t->next; @@ -386,7 +394,7 @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list, } ts->expire_time = MAX(expire_time, 0); ts->next = *pt; - *pt = ts; + atomic_set(pt, ts); return pt == &timer_list->active_timers; } @@ -481,8 +489,12 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) QEMUTimerCB *cb; void *opaque; + if (!atomic_read(&timer_list->active_timers)) { + return false; + } + qemu_event_reset(&timer_list->timers_done_ev); - if (!timer_list->clock->enabled || !timer_list->active_timers) { + if (!timer_list->clock->enabled) { goto out; } -- 2.9.3