Iofthetiger

Same here. It boggles my mind how the majority of the industry has gone the async / await route, as if it was an easy model to understand and implement. The Go (and I belive Erlang / Elixir) model is much more intuitive to me. You just define normal functions and send them off to do their thing concurrently. If you need to communicate with them, use channels. The simplicity lowers the barrier for many more developers to actually use concurrent tools in the language and thus finally makes efficient use of multi-core hardware.

4 Likes

Good coherent terminology never hurts. Ambiguities in terms are often the source of confusion and misunderstandings. Using read() syscall as an example we have 4 variants of program/OS kernel behavior in the case when there is no data to be read at the moment:

  • block (go to ‘wait/sleep’ state, OS will wake up us when data will be there)
  • return with errno = EAGAIN (this is what I am calling “non-blocking”)
  • use readiness notifications (poll, select, epoll/kqueue)
  • use completion notifications (IOCP/io_uring) - this is true async mode.

…couldn’t help myself from giving the link to Linus Torvalds reaction on AIO stuff back in 2016 :slight_smile:

to be fair, they all use a runtime (IIRC)

Hmm… novel? Coroutines (subroutines with multiple entry points) were invented in 1958…

As I see it… If a compiler when generating code for async/await based (async) I/O has to use specific system calls (which are different across OSes)… well, this is awful. This is ok for languages like python/tcl, but not for a language like C/Zig. Just let people use OS directly and they will someday come up with such an abstraction, but do not put this abstraction into compiler proper.

1 Like

True, but when you think about it, all these async / await implementations need an event loop to drive them and many times a worker thread pool to improve performance even more. So in the end, they end up having a runtime too. Take Rust for example; the language itself doesn’t have a runtime but does provide the async / await semantics (as syntax sugar over Futures). So you must add a runtime like Tokio or async-std to make it work.

2 Likes

I think we should add “for now” here:

1 Like

Thanks for the detailed explanation. I know this song, it was also very popular where I come from (they call it “the Rocky song” over there). But iofthetiger blocks my brain into interpreting the first two characters as I/O (as you mentioned), and I am left with fthetiger, which I can only read as… <expletive> the tiger. LOL.

3 Likes

This double interpretation only makes the pun spicier and jucier :slight_smile:

2 Likes

Was Linus foreshadowing io_uring in those thoughts, back in 2016?

ROTFL! Definitely a whole new meaning to the name. :joy_cat: And hey, I call it the Rocky song too.

2 Likes

This must be a bug. It’s supposed to be non-blocking. :stuck_out_tongue_closed_eyes:

7 Likes

I guess he was, look at this phrase.

If you want to do arbitrary asynchronous system calls…

There was/is libaio, which Linus did not like (charitably speaking).
Also there was a citation in man 2 open… it seems it has been removed from this manual page, but in older Linux distros (deb8 for instance) it’s still there (it’s about O_DIRECT flag).

As far as I could understand in that message Linus is saying that there must be
a single general mechanism for doing things asynchronously, but not scrappy “solutions” for every special case (libaio works only with file i/o).

2 Likes

The song is dull, no drive at all in it.
How about rock’n’roll dev ? :melting_face:

ReadOnly DevOps, why ain’t should be? :slight_smile:

1 Like

Hey man, Survivor was good, but you’re bringing in the heavy guns with AC/DC! :smile_cat:

P.S.: Now we’re going off-topic but hey, it’s AC/DC, so it’s allowed. lol

We are not:

Starting from go1.14, goroutines are asynchronously preemptible in order to avoid, as example, loops without function to deadlock the scheduler.

Does languages supporting async/await like Rust support this feature?

Thanks for pointing this out. I had only read the name in the overview of the posts and thought it was some strange german name starting with an ‘L’ ( lofthetiger ) that I hadn’t seen before.

That would depend on the async runtime you choose. I’m not sure if Tokio or async-std have this feature, but they could implement it at the runtime level without needing a change in the language.

Yeah, Discourse automatically capitalizes topic titles so it turned iofthetiger into Iofthetiger. :confused:

Sorry for bumping/off-topic/etc. I am just wondering how do timers and signals fit into io_uring mechanism/abstraction?

Both timers and signals are not I/O per se, no data transfer between peripherals of a “computer” and CPU, no data transfer between nodes in a network, it’s just some interaction
between user/kernel space inside a single “device”/“gadget”.

In Linux, after you got readiness notification concerning timers/signals you must read some data from underlying fds, otherwise you will be over-flooded with these notifications.

In FreeBSD, timers are different beasts, someone may like it, someone do not, I personally don’t - “everything in Unix is a file”, after all :slight_smile:

So, both with FreeBSD kqueue and with LInux epoll, both timers and signals more or less fit into “reactor pattern”. How do they fit into (really cool) io_uring facility?