rustmatic icon indicating copy to clipboard operation
rustmatic copied to clipboard

Process Execution Model

Open Michael-F-Bryan opened this issue 5 years ago • 4 comments

Looking at the Overview diagram, it sounds like the core of the PLC runtime would be something like this:

while running {
  read_inputs();
  poll_waiting_processes();
  write_outputs();
  do_background_tasks_until_next_tick();
}

Yet it mentions event- and time-driven interrupts.

Would "triggering" an interrupt just be a case of registering that interrupt's readiness so it can be polled as part of the next poll_waiting_processes()? Or were you thinking along the lines of the true preemptive interrupts you see in embedded systems or in unix signals?

Michael-F-Bryan avatar Nov 19 '19 10:11 Michael-F-Bryan

 read_inputs();
 poll_waiting_processes();
 write_outputs();
 do_background_tasks_until_next_tick();
}

Yes, thats's what I had in mind when I drew the diagram at least.

Regarding the interrupts, I had preemption in mind, since i.e. Siemens and Codesys support this. This might be unrealistic with limited resources...maybe async has some feature for this?

NOP0 avatar Nov 19 '19 11:11 NOP0

Regarding the interrupts, I had preemption in mind, since i.e. Siemens and Codesys support this. This >might be unrealistic with limited resources...maybe async has some feature for this?

That said, I think the interrupt routines share the same global address space, would it be possible to interrupt the bytecode vm?

NOP0 avatar Nov 19 '19 12:11 NOP0

That'd depend on what system you're running on. If it's an embedded system (i.e. no OS) then interrupts can interrupt pretty much anything, as long as you aren't in a critical section (e.g. you disabled interrupts to access a mutex).

On the other hand, I'm not sure if a "normal" OS would give you access to the raw interrupt handlers. I know Linux lets you create a per-process timer with timer_create() then register a listener for the SIGALRM signal using sigaction(). Although signal handlers have some pretty tight restrictions (e.g. no locks or blocking), so they're not ideal.


Also, I'm not sure I'd like a program (doesn't necessarily need to be something running on a bytecode VM) to be interrupted midway through. What if my program was reading an input (Device::digital_read()) at the time? My Device object needs to use locks because it's already shared with multiple things, but the system will deadlock if we're running programs in response to a timer/event and that program tries to use that device.

I guess if we take the event-driven approach later, this sort of "interrupt" system for working with timers and events would solve itself. You'd create a priority system or special high-priority queue and handling a timer/event is just a case of adding the handler to the front of the event queue so it's handled straight away. Most JavaScript runtimes have something similar in the form of microtasks.

Michael-F-Bryan avatar Nov 19 '19 15:11 Michael-F-Bryan

Yeah, I'm guessing for MVP it's probably not necessary to interrupt a program, the interrupt is queued.

NOP0 avatar Nov 23 '19 21:11 NOP0