oc2 icon indicating copy to clipboard operation
oc2 copied to clipboard

Interrupt/notification/event mechanism

Open Hawk777 opened this issue 2 years ago • 2 comments

In original OC, we had computer.pullSignal, which would sleep until something happened and then tell you not just that something happened, but also what happened. It would be nice to have something similar in OC2. Imagine you’re trying to monitor a few dozen redstone signals for changes; it would be nice if you could just be notified when a signal changes, rather than having to repeatedly poll every signal just to find out if any of them have changed. If implemented sanely, this would presumably both improve performance (you’d learn about the change sooner than the time it takes to poll all the signals) and also reduce real-world CPU usage (your emulated computer could be asleep, and therefore not taking up real-world CPU time, while awaiting a signal state change).

Hawk777 avatar May 07 '22 15:05 Hawk777

The only problem in my opinion with pullSignal is that it is blocking, and stops execution until an event occurs.

I have no experience working with this system, but I think it might be more valuable to be able to register callback functions to be called when an event or a specific event occurs instead.

The only problem would be that this would likely require asynchronous code unless there was something somewhere that specifically told the program "ok you can handle events now" and then return control to a main loop or something. Basically event loops.

Maybe this is crazy though, or not related. Just throwing out ideas. Have a nice day.

CoolCat467 avatar May 09 '22 02:05 CoolCat467

The only problem in my opinion with pullSignal is that it is blocking, and stops execution until an event occurs.

Not if you pass it a timeout, which can be zero if you’re running computationally intensive code but still want to check for events from time to time.

I think it makes sense to distinguish between what interface the hardware provides for delivering events and what interface the Linux kernel drivers use to pass those events to userspace.

I’ve heard the RPC interface looks something like a serial port, but I don’t know what it looks like on the hardware side, or whether that’s just the abstraction that the kernel provides. Assuming it’s somewhat like a serial port at the hardware level (which I would expect to mean either it generates a hardware interrupt when data is ready and the kernel reads the data into a memory buffer, or else there’s a DMA system which writes the data directly into a memory buffer and a hardware interrupt is generated when the transfer is finished for the kernel to dispose of the data), maybe there could just be a second one, but read-only: notification events are delivered as JSON objects that arrive on that interface spontaneously (it might be best not to include them in the existing interface as that would break consumers that expect to only ever read the result of the call they just made).

In userspace, there are lots of options for how to notify the userspace process, but they already exist as part of regular Linux, and OC2 doesn’t need to invent them: if you expose that byte stream as another /dev node, userspace can just open that node if it wants to receive these events and use all the existing I/O multiplexing and notification systems: you can choose between select, poll, epoll, a thread blocking in read, SIGIO, just calling a non-blocking read from time to time to see if there’s data there, or probably a few other options I’ve forgotten now. Many of these are totally compatible with running CPU-intensive code and just checking for readability once in a while.

Some kind of queue-length limiting mechanism would need to be introduced at each level (both in the hardware to limit the number of events the kernel hasn’t read yet, particularly important in the case someone in your world experiments with a custom kernel, and also in the Linux kernel driver for the more common case of someone writing a userspace program that opens the /dev node and then neglects to read from it), but that’s simple and there’s already precedent for it in OC1 (IIRC the limit was a hundred events or something like that).

Hawk777 avatar May 09 '22 14:05 Hawk777