Hacker News new | ask | show | jobs
by kgeist 1475 days ago
IIRC in earlier versions, an infinite loop without function calls could freeze the entire runtime: GC's stop the world event is triggered => goroutines are being suspended cooperatively => but this one goroutine never enters a function prolog and thus never suspends => all goroutines except one are suspended and there's no progress. Preemptive scheduling is much more robust. Although it's solvable in cooperative scheduling with an additional suspension check at the end of each loop, but it adds overhead for all loops. If I remember correctly, .NET or JVM implement safe points for GC (which can be used to switch contexts cooperatively as well) by simply reading a pointer from a special preallocated virtual memory page which is remapped to nothing when a stop-the-world event is triggered, so such a read traps into an invalid memory handler where you can park your thread. But I'm not sure how costly it is for thousands/millions of coroutines.
1 comments

> But I'm not sure how costly it is for thousands/millions of coroutines.

Still cheap: you only need to preempt the threads which are actively running user code. If a coroutine is ready to run, but not actually running, you don't have to do anything with it (as long as you check for safepoints before entering user code.) That means your safepoints cost is `O(os threads currently running user code)` which in most runtimes is `O(num cores)`