To either of you, whenever you are doing something new from scratch, it can be useful to consider the granularity of provided abstractions & services which khaledh seems to be doing. I see fusion only has like 8 syscalls presently. It's not in Nim, but along these lines ("how much" individual calls do), you might want to consider an approach like this: https://github.com/c-blake/batch to amortize costs of crossing expensive call boundaries.
Batching syscalls is on my mind. The architecture of Fusion will revolve around channel-based ipc (both sync and async), including between user mode and kernel mode. The end state I'm aiming for is an async channel for syscalls, where the user task issues syscalls, which get buffered in a queue, where the kernel processes the queue asynchronously.
For this to work properly, user tasks need to be able to respond to completed syscalls async as well. That's why my idea of user tasks is that they should be modeled as state machines, with channel-based events as the core mechanism by which code gets executed in a deterministic manner. The equivalent of signals in Unix (which many find one of the bad aspects of Unix design) would be receiving events on one or more channels for various purposes (e.g. IO completion, timers, abort, interrupt, GUI events, etc.).
To either of you, whenever you are doing something new from scratch, it can be useful to consider the granularity of provided abstractions & services which khaledh seems to be doing. I see fusion only has like 8 syscalls presently. It's not in Nim, but along these lines ("how much" individual calls do), you might want to consider an approach like this: https://github.com/c-blake/batch to amortize costs of crossing expensive call boundaries.
Batching syscalls is on my mind. The architecture of Fusion will revolve around channel-based ipc (both sync and async), including between user mode and kernel mode. The end state I'm aiming for is an async channel for syscalls, where the user task issues syscalls, which get buffered in a queue, where the kernel processes the queue asynchronously.
For this to work properly, user tasks need to be able to respond to completed syscalls async as well. That's why my idea of user tasks is that they should be modeled as state machines, with channel-based events as the core mechanism by which code gets executed in a deterministic manner. The equivalent of signals in Unix (which many find one of the bad aspects of Unix design) would be receiving events on one or more channels for various purposes (e.g. IO completion, timers, abort, interrupt, GUI events, etc.).
Ack! I was just about to write a blog post on this idea!
Good minds think alike, I guess.
But as a sibling comment says, this is essentially what io_uring is. Read Lord of the io_uring [1] if you want to know more. Polling mode is the key.
[1]: https://unixism.net/loti/index.html
1 reply →
Sounds interesting - kind of like microkernels meet io_uring (in Elevator-pitch-ese).