From f0791a47b78904d6514f21b0f488a03e911e140b Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 26 Oct 2023 00:34:06 +0700 Subject: [PATCH] Make mailbox be lightweight as possible --- .../kstarbound/util/MailboxExecutorService.kt | 94 +++++++++---------- 1 file changed, 43 insertions(+), 51 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/util/MailboxExecutorService.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/util/MailboxExecutorService.kt index b38ed14e..31c4bd9c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/util/MailboxExecutorService.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/util/MailboxExecutorService.kt @@ -38,10 +38,7 @@ private fun > LinkedList.enqueue(value: E) { } class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : ScheduledExecutorService { - private val executeQueue = ConcurrentLinkedQueue() private val futureQueue = ConcurrentLinkedQueue>() - private val timerBacklog = ConcurrentLinkedQueue>() - private val repeatableTimersBacklog = ConcurrentLinkedQueue() private val timers = LinkedList>() private val repeatableTimers = LinkedList() @@ -116,51 +113,13 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche } executionLock.withLock { - var next = executeQueue.poll() + var next = futureQueue.poll() while (next != null) { if (isTerminated) return next.run() - next = executeQueue.poll() - } - - var next2 = futureQueue.poll() - - while (next2 != null) { - if (isTerminated) return - next2.run() Thread.interrupted() - next2 = futureQueue.poll() - } - - var next3 = timerBacklog.poll() - - while (next3 != null) { - if (isTerminated) return - if (next3.isCancelled) { - // do nothing - } else if (next3.executeAt <= timeOrigin.nanos) { - next3.run() - Thread.interrupted() - } else { - timers.enqueue(next3) - } - - next3 = timerBacklog.poll() - } - - var next4 = repeatableTimersBacklog.poll() - - while (next4 != null) { - if (isTerminated) return - - if (next4.isCancelled) { - // do nothing - } else { - repeatableTimers.enqueue(next4) - } - - next4 = repeatableTimersBacklog.poll() + next = futureQueue.poll() } while (!timers.isEmpty()) { @@ -207,7 +166,7 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche if (isSameThread()) { command.run() } else { - executeQueue.add(command) + futureQueue.add(FutureTask(command, Unit)) LockSupport.unpark(thread) } } @@ -223,9 +182,6 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche val result = ArrayList() executionLock.withLock { - executeQueue.forEach { result.add(it) } - executeQueue.clear() - futureQueue.forEach { it.cancel(false) result.add(it) @@ -347,7 +303,16 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche } else if (isSameThread()) { timers.enqueue(timer) } else { - timerBacklog.add(timer) + execute { + if (timer.isCancelled) { + // do nothing + } else if (timer.executeAt <= timeOrigin.nanos) { + timer.run() + Thread.interrupted() + } else { + timers.enqueue(timer) + } + } } return timer @@ -364,7 +329,16 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche } else if (isSameThread()) { timers.enqueue(timer) } else { - timerBacklog.add(timer) + execute { + if (timer.isCancelled) { + // do nothing + } else if (timer.executeAt <= timeOrigin.nanos) { + timer.run() + Thread.interrupted() + } else { + timers.enqueue(timer) + } + } } return timer @@ -381,7 +355,16 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche return RepeatableTimer( command, timeOrigin.nanos + TimeUnit.NANOSECONDS.convert(initialDelay, unit), - TimeUnit.NANOSECONDS.convert(period, unit), true).also { repeatableTimersBacklog.add(it) } + TimeUnit.NANOSECONDS.convert(period, unit), true) + .also { + execute { + if (it.isCancelled) { + // do nothing + } else { + repeatableTimers.enqueue(it) + } + } + } } override fun scheduleWithFixedDelay( @@ -395,6 +378,15 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche return RepeatableTimer( command, timeOrigin.nanos + TimeUnit.NANOSECONDS.convert(initialDelay, unit), - TimeUnit.NANOSECONDS.convert(delay, unit), false).also { repeatableTimersBacklog.add(it) } + TimeUnit.NANOSECONDS.convert(delay, unit), false) + .also { + execute { + if (it.isCancelled) { + // do nothing + } else { + repeatableTimers.enqueue(it) + } + } + } } }