<i>All</i> coroutine libraries are non-preemptive and cooperative. E.g. in Haskell, threads will switch only on GC allocations. In Go, they only switch on I&#x2F;O (and maybe function returns). In theory, the compiler could automatically add `yield` statements into non-allocating, non-I&#x2F;O loops. But nevertheless, <i>all</i> user-space threading is cooperative.