One minor correction about Erlang is that that scheduler doesn't get invoked just on function calls. It will be invoked as soon as the lightweight process consumes a certain number of allowed operations. So even if you have one huge function that never calls others, just computes something, it will still consume operations and will be preempted. Some internal C utility functions also consume some virtual number of ops as well and may yield.