News for hackers. Stuff that matters.
Re:I wrote the BEAM book (2025) by toast0 on Wednesday November 11, 2026 @11:40AM (#50455410)
> Cooperative scheduling is based on the programmer releasing control manually (much like manual memory management) or having yield points baked into the language, often at function calls or IO events. Processes on BEAM can be preempted, they're allotted a number of "reductions" and when those are exhausted, the process is preempted (the process may also yield earlier).

BEAM is actually cooperative. In userspace, function calls and IO (receive and !) are yield points, and reduction count is simply the number of function calls you're allowed. Something something Computer Sciencey reduction basically means function call.

It just feels preemptive because as a functional language, you have to call functions all the time. Your loop becomes

   loop(I) -> loop(I + 1).
And that will yield once it calls itself enough times.

Native code (NIFs, BIFs, and drivers) has to count reductions and/or yield explicitly.

You can easily hog scheduler threads in native code that does significant computation or does i/o without using the runtime facilities; most people who write NIFs will mess it up at least once, I certainly have. It's much harder to do in userspace code, but if you fully unroll a very large loop that does not call functions or anything else that can yield, you can do it; I don't see how this would happen without specific intent, I've never run into it, but it's possible.

A blocked scheduler can be vaguely fine or terrible depending on how long it stays blocked and what the system is up to. Often it won't be terrible until you do something that needs all schedulers to synchronize, such as operations around code loading, but you can probably wedge the whole BEAM if you try.

There are no comments on this comment yet.