summaryrefslogtreecommitdiff
path: root/simulator/opendc-utils/src/main/kotlin/org
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-03-27 12:52:47 +0100
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-04-07 16:31:47 +0200
commit95a0ed6911f136fb25bb76d6b6e010bf66b8ba5b (patch)
treef9653f6467432df49c36e1429b9fcd8770be643f /simulator/opendc-utils/src/main/kotlin/org
parent519141f9af525a853b40eb821e70ca209bc104bf (diff)
utils: Cache variables in TimerScheduler's hot paths
This change updates the TimerScheduler implementation to cache several variables in the hot paths of the implementation.
Diffstat (limited to 'simulator/opendc-utils/src/main/kotlin/org')
-rw-r--r--simulator/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt16
1 files changed, 10 insertions, 6 deletions
diff --git a/simulator/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt b/simulator/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt
index d4bc7b5c..175c2b51 100644
--- a/simulator/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt
+++ b/simulator/opendc-utils/src/main/kotlin/org/opendc/utils/TimerScheduler.kt
@@ -34,8 +34,8 @@ import kotlin.math.max
/**
* A TimerScheduler facilitates scheduled execution of future tasks.
*
- * @property context The [CoroutineContext] to run the tasks with.
- * @property clock The clock to keep track of the time.
+ * @param context The [CoroutineContext] to run the tasks with.
+ * @param clock The clock to keep track of the time.
*/
@OptIn(ExperimentalCoroutinesApi::class)
public class TimerScheduler<T>(context: CoroutineContext, private val clock: Clock) : AutoCloseable {
@@ -66,6 +66,8 @@ public class TimerScheduler<T>(context: CoroutineContext, private val clock: Clo
val timers = timers
val queue = queue
val clock = clock
+ val job = requireNotNull(coroutineContext[Job])
+ val exceptionHandler = coroutineContext[CoroutineExceptionHandler]
var next: Long? = channel.receive()
while (true) {
@@ -75,7 +77,7 @@ public class TimerScheduler<T>(context: CoroutineContext, private val clock: Clo
val delay = next?.let { max(0L, it - clock.millis()) } ?: return@select
onTimeout(delay) {
- while (queue.isNotEmpty() && isActive) {
+ while (queue.isNotEmpty() && job.isActive) {
val timer = queue.peek()
val timestamp = clock.millis()
@@ -93,7 +95,7 @@ public class TimerScheduler<T>(context: CoroutineContext, private val clock: Clo
try {
timer()
} catch (e: Throwable) {
- coroutineContext[CoroutineExceptionHandler]?.handleException(coroutineContext, e)
+ exceptionHandler?.handleException(coroutineContext, e)
}
}
}
@@ -131,11 +133,13 @@ public class TimerScheduler<T>(context: CoroutineContext, private val clock: Clo
timer?.isCancelled = true
// Optimization: check whether we are the head of the queue
- if (queue.peek() == timer) {
+ val queue = queue
+ val peek = queue.peek()
+ if (peek == timer) {
queue.poll()
if (queue.isNotEmpty()) {
- channel.sendBlocking(queue.peek().timestamp)
+ channel.sendBlocking(peek.timestamp)
} else {
channel.sendBlocking(null)
}