Skip to content

Commit 23d435b

Browse files
committed
Minor optimizations of UndispatchedEventLoop
1 parent faa4774 commit 23d435b

File tree

2 files changed

+21
-23
lines changed

2 files changed

+21
-23
lines changed

common/kotlinx-coroutines-core-common/src/Dispatched.kt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,53 +13,53 @@ private val UNDEFINED = Symbol("UNDEFINED")
1313

1414
@NativeThreadLocal
1515
internal object UndispatchedEventLoop {
16-
data class State(
16+
data class EventLoop(
1717
@JvmField var isActive: Boolean = false,
18-
@JvmField val threadLocalQueue: ArrayQueue<Runnable> = ArrayQueue()
18+
@JvmField val queue: ArrayQueue<Runnable> = ArrayQueue()
1919
)
2020

2121
@JvmField
22-
internal val state = CommonThreadLocal { State() }
22+
internal val threadLocalEventLoop = CommonThreadLocal { EventLoop() }
2323

2424
inline fun execute(continuation: DispatchedContinuation<*>, contState: Any?, mode: Int, block: () -> Unit) {
25-
val state = state.get()
26-
if (state.isActive) {
25+
val eventLoop = threadLocalEventLoop.get()
26+
if (eventLoop.isActive) {
2727
continuation._state = contState
2828
continuation.resumeMode = mode
29-
state.threadLocalQueue.addLast(continuation)
29+
eventLoop.queue.addLast(continuation)
3030
return
3131
}
3232

33-
runLoop(state, block)
33+
runEventLoop(eventLoop, block)
3434
}
3535

3636
fun resumeUndispatched(task: DispatchedTask<*>) {
37-
val state = state.get()
38-
if (state.isActive) {
39-
state.threadLocalQueue.addLast(task)
37+
val eventLoop = threadLocalEventLoop.get()
38+
if (eventLoop.isActive) {
39+
eventLoop.queue.addLast(task)
4040
return
4141
}
4242

43-
runLoop(state, { task.resume(task.delegate, MODE_UNDISPATCHED) })
43+
runEventLoop(eventLoop, { task.resume(task.delegate, MODE_UNDISPATCHED) })
4444
}
4545

46-
inline fun runLoop(state: State, block: () -> Unit) {
46+
inline fun runEventLoop(eventLoop: EventLoop, block: () -> Unit) {
4747
try {
48-
state.isActive = true
48+
eventLoop.isActive = true
4949
block()
50-
while (!state.threadLocalQueue.isEmpty) {
51-
val element = state.threadLocalQueue.removeFirst()
52-
element.run()
50+
while (true) {
51+
val nextEvent = eventLoop.queue.removeFirstOrNull() ?: return
52+
nextEvent.run()
5353
}
5454
} catch (e: Throwable) {
5555
/*
5656
* This exception doesn't happen normally, only if user either submitted throwing runnable
5757
* or if we have a bug in implementation. Anyway, reset state of the dispatcher to the initial.
5858
*/
59-
state.threadLocalQueue.clear()
59+
eventLoop.queue.clear()
6060
throw DispatchException("Unexpected exception in undispatched event loop, clearing pending tasks", e)
6161
} finally {
62-
state.isActive = false
62+
eventLoop.isActive = false
6363
}
6464
}
6565
}

common/kotlinx-coroutines-core-common/src/internal/ArrayQueue.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
package kotlinx.coroutines.internal
66

77
internal class ArrayQueue<T : Any> {
8-
public val isEmpty: Boolean get() = head == tail
9-
108
private var elements = arrayOfNulls<Any>(16)
119
private var head = 0
1210
private var tail = 0
@@ -18,12 +16,12 @@ internal class ArrayQueue<T : Any> {
1816
}
1917

2018
@Suppress("UNCHECKED_CAST")
21-
public fun removeFirst(): T {
22-
require(head != tail) { "Queue is empty" }
19+
public fun removeFirstOrNull(): T? {
20+
if (head == tail) return null
2321
val element = elements[head]
2422
elements[head] = null
2523
head = (head + 1) and elements.size - 1
26-
return element!! as T
24+
return element as T
2725
}
2826

2927
public fun clear() {

0 commit comments

Comments
 (0)