Hacker News new | ask | show | jobs
by duped 1470 days ago
I have no idea what GPOS stands for, but the analogy isn't really necessary.

The high level algorithm you describe is basically how async programs work. Glossing over the low level details, you usually implement things in terms of polling. Interrupts and their analogs are far too slow at scale (switching async tasks is in the nanoseconds, these days).

The problem is when there is logic downstream of the task that needs its results and mixed with the results of some synchronous code in between. This is the "function coloring" problem.

Async semantics are designed to insert the logic for handling this (merging of async task results) seamlessly. There are two issues with this, the first is that synchronous code has no way of knowing what to do with asynchronous results (meaningfully), and the second that there has to exist some executor program that handles the merging and scheduling logic.

The thing that makes async "hard" in a language like Rust is that dealing with this problem is extremely difficult when you have no GC, lifetimes, call-by-move, closures that capture by move, and ownership semantics - it makes it verbose to write sound, non-trivial async code. For example, you're forced to introduce the notion of "pinned" data in memory to prevent it from being moved while tasks are switched. Lifetimes become a lot less clear. "Async destructors" don't really exist (what other languages would call finalizers that don't run at the end of lexical scope).

As for the mixing of sync/async code, that's not actually an issue if everything is async. It's trivial to write an executor that makes async calls blocking anyway.

2 comments

What you are talking about has been resolved since there is a system with interrupts and an OS with a scheduler. It's nothing new. Async Rust (or whatever async) is just an autogenerated state machine that for years has been being implemented by hand.

> you usually implement things in terms of polling

Like a busy loop? If so, this approach is the worst, IMO. When done in an OS you keep your application thread always alive. In an embedded system it drains your battery.

The most common model is that in which an application should be sleeping all the time, and processing external stimulus when required.

> Interrupts and their analogs are far too slow at scale (switching async tasks is in the nanoseconds, these days).

Are you saying that whatever async system (like async Rust) is faster than a HW interrupt?

HW interrupts is what makes your system responsive as it is now. Stopping and jumping to an interrupt handler is hardwired in the silicon. What is faster than that?

I think GPOS in this context stands for General-Purpose OS (as opposed to embedded).