From d66f2571796bcf75c5ff49186ee85ba01cb5e918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Mon, 22 Oct 2018 21:18:37 +0200 Subject: [PATCH] Avoid GC allocations for LoopTimeoutTimerDriver.m_firedTimers. --- source/eventcore/drivers/timer.d | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/source/eventcore/drivers/timer.d b/source/eventcore/drivers/timer.d index 926400b..0f47f46 100644 --- a/source/eventcore/drivers/timer.d +++ b/source/eventcore/drivers/timer.d @@ -4,8 +4,9 @@ module eventcore.drivers.timer; import eventcore.driver; +import eventcore.internal.consumablequeue; import eventcore.internal.dlist; -import eventcore.internal.utils : nogc_assert; +import eventcore.internal.utils : mallocT, freeT, nogc_assert; final class LoopTimeoutTimerDriver : EventDriverTimers { @@ -24,7 +25,7 @@ final class LoopTimeoutTimerDriver : EventDriverTimers { TimerSlot*[TimerID] m_timers; StackDList!TimerSlot m_timerQueue; TimerID m_lastTimerID; - TimerSlot*[] m_firedTimers; + ConsumableQueue!(TimerSlot*) m_firedTimers; } static this() @@ -32,6 +33,17 @@ final class LoopTimeoutTimerDriver : EventDriverTimers { ms_allocator.parent = Mallocator.instance; } + this() + @nogc @safe nothrow { + m_firedTimers = mallocT!(ConsumableQueue!(TimerSlot*)); + } + + ~this() + @nogc @trusted nothrow { + try freeT(m_firedTimers); + catch (Exception e) assert(false, e.msg); + } + package @property size_t pendingCount() const @safe nothrow { return m_timerQueue.length; } final package Duration getNextTimeout(long stdtime) @@ -53,27 +65,24 @@ final class LoopTimeoutTimerDriver : EventDriverTimers { do tm.timeout += tm.repeatDuration; while (tm.timeout <= stdtime); } else tm.pending = false; - m_firedTimers ~= tm; + m_firedTimers.put(tm); } - foreach (tm; m_firedTimers) { + auto processed_timers = m_firedTimers.consume(); + + foreach (tm; processed_timers) { m_timerQueue.remove(tm); if (tm.repeatDuration > 0) enqueueTimer(tm); } - foreach (tm; m_firedTimers) { + foreach (tm; processed_timers) { auto cb = tm.callback; tm.callback = null; if (cb) cb(tm.id); } - bool any_fired = m_firedTimers.length > 0; - - m_firedTimers.length = 0; - m_firedTimers.assumeSafeAppend(); - - return any_fired; + return processed_timers.length > 0; } final override TimerID create()