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
+9 -20
View File
@@ -55,33 +55,22 @@ void* IOP::iop_alloc(int size) {
return mem;
}
void IOP::wait_run_iop() {
std::unique_lock<std::mutex> lk(iters_mutex);
if (iop_iters_des > iop_iters_act) {
iop_iters_act++;
return;
}
iop_run_cv.wait(lk, [&] { return iop_iters_des > iop_iters_act; });
iop_iters_act++;
void IOP::wait_run_iop(
std::chrono::time_point<std::chrono::steady_clock, std::chrono::microseconds> wakeup) {
std::unique_lock<std::mutex> lk(run_cv_mutex);
iop_run_cv.wait_until(lk, wakeup);
}
void IOP::kill_from_ee() {
want_exit = true;
signal_run_iop(true);
signal_run_iop();
}
void IOP::signal_run_iop(bool force) {
std::unique_lock<std::mutex> lk(iters_mutex);
if (iop_iters_act == iop_iters_des || force) {
iop_iters_des++; // todo, tune this
if (iop_iters_des - iop_iters_act > 500) {
iop_iters_des = iop_iters_act + 500;
}
iop_run_cv.notify_all();
}
void IOP::signal_run_iop() {
std::unique_lock<std::mutex> lk(run_cv_mutex);
iop_run_cv.notify_all();
}
IOP::~IOP() {
reset_allocator();
}
}