Opinions on scheduler (C++ coroutines and NodeJS)
Posted: Sun Mar 19, 2023 9:17 am
I am professionally a web developer (ewwwww) and quite like JS' async/await and its event loop. I am modelling my scheduler with the NodeJS event loop as inspiration. I also use C++23 coroutines heavily. So far it has been working quite well.
Say, I want to read from an AHCI device, the flow goes kind of like this
And this is happening for key events as well (IRQ handled on a different CPU).
Currently my scheduler runs on only 1 CPU which listens to the HPET IRQ and does this
I am going to make the timer IRQ broadcast to all CPUs. Linux, according to my current understanding, maintains a task queue for each CPU. I however don't want to do that and think the current model of centralized task and event queue should work fine.
Do you guys foresee any problems I might run into?
One problem I can think of is CPU affinity but even that can be navigated (I guess).
Say, I want to read from an AHCI device, the flow goes kind of like this
Code: Select all
device::readFile(...) {
// Control will be yielded to the caller as soon as co_await happens
auto result = co_await Command(this, freeSlot);
}
Command::setResult(bool result) noexcept {
// Called within the context of IRQ handler
scheduler.queueEvent(<whoever issued the AHCI command>);
}
Command::await_resume() {
// IRETQ has been already done and running in the context of scheduler event loop
return commandResultToTheAwaiter;
}
Currently my scheduler runs on only 1 CPU which listens to the HPET IRQ and does this
Code: Select all
void Kernel::Scheduler::timerLoop() {
// Dispatch events synchronously until the queue has dispatchable events and < SCHEDULER_EVENT_DISPATCH_LIMIT in 1 loop
// FIXME: should lock the event queue once all CPUs get timer broadcast IRQ
size_t dispatchedEventsCount = 0;
while (!eventQueue.empty() && dispatchedEventsCount < SCHEDULER_EVENT_DISPATCH_LIMIT) {
std::coroutine_handle<> x = eventQueue.front();
if (x && !x.done()) {
x.resume();
}
eventQueue.pop();
++dispatchedEventsCount;
}
// TODO: do rest of scheduling/context switching
}
Do you guys foresee any problems I might run into?
One problem I can think of is CPU affinity but even that can be navigated (I guess).