Posts

Showing posts from February, 2021

The Ultimate Breakdown of Kotlin Coroutines. Part 4. Create, Start, Suspend, Intercept.

The previous parts mostly explained what the compiler does with coroutines. However, there is the other side of a coin - runtime support. In Kotlin's case, standard library functions, including intrinsic one, which are responsible for all the essential operations - creation, starting, suspension and interception. There is also a part responsible for resumption, but I already explained it in part 2. Coroutine Intrinsics Previous examples had an elementary coroutine builder. They used so-called empty continuation. Let us now recreate kotlinx.coroutines' async function, which runs a coroutine on another thread and then, upon its completion, returns the result to the main thread. First, we need a class which waits on the main thread: class Async < T > { suspend fun await (): T = TODO() } then the root continuation: class AsyncContinuation < T >: Continuation < T > { override val context = EmptyCoroutineContext override fun resumeWith (r

The Ultimate Breakdown of Kotlin Coroutines. Part 3. Variable Spilling.

In the previous parts of the breakdown I covered all the essential parts of coroutines, or, as I like to call them - three-headed hydra - suspension, resumption and state-machine. This time I will explain local variables spilling - a process of saving a coroutine state before suspension and restoring them after resumption. Variables Spilling All the previous examples did not have local variables, and there is a reason for it. When a coroutine suspends, we should save its local variables. Otherwise, when it resumes, the values of them are lost. So, before the suspension, which can be on each suspend call (more generally, on each suspension point), we save them, and after the resumption, we restore them. There is no reason to restore them right after the call if the call did not return COROUTINE_SUSPENDED : their values are still in local variable slots. Let us consider a simple example: import kotlin.coroutines.* data class A ( val i: Int ) var c: Continuation< Unit >?