Implement scheduling of IOP threads. (#1689)

* Use sleepthread in RPC loop

* Keep a pointer to current IOP thread

* Implement IOP thread scheduling based on priority

And implement DelayThread as an actual delay.

* Run IOP flat out

* Use information from scheduler in wait_run_iop

* Lock sif mutex in set_rpc_queue

* always use kernel dispatch with wait_run

* Loop in dispatch until no thread is ready

* Use timestamp for next wakeup

instead of duration

* Wrap IOP thread entrypoints for safety

Libco threads are not supposed to return from their entrypoint

* Use a queue for IOP thread wakeups from EE thread
This commit is contained in:
Ziemas
2022-07-27 03:15:37 +02:00
committed by GitHub
parent 7d5901aa95
commit f8bc883d48
8 changed files with 215 additions and 85 deletions
+4 -5
View File
@@ -244,7 +244,7 @@ void iop_runner(SystemThreadInterface& iface) {
bool complete = false;
start_overlord_wrapper(iop.overlord_argc, iop.overlord_argv, &complete); // todo!
while (complete == false) {
iop.kernel.dispatchAll();
iop.wait_run_iop(iop.kernel.dispatch());
}
// unblock the EE, the overlord is set up!
@@ -252,10 +252,9 @@ void iop_runner(SystemThreadInterface& iface) {
// IOP Kernel loop
while (!iface.get_want_exit() && !iop.want_exit) {
// the IOP kernel just runs at full blast, so we only run the IOP when the EE is waiting on the
// IOP. Each time the EE is waiting on the IOP, it will run an iteration of the IOP kernel.
iop.wait_run_iop();
iop.kernel.dispatchAll();
// The IOP scheduler informs us of how many microseconds are left until it has something to do.
// So we can wait for that long or until something else needs it to wake up.
iop.wait_run_iop(iop.kernel.dispatch());
}
}
} // namespace