| 39 | extern bool cellPad_NotifyStateChange(usz index, u64 state, bool lock = true, bool is_blocking = true); |
| 40 | |
| 41 | void config_event_entry(ppu_thread& ppu) |
| 42 | { |
| 43 | ppu.state += cpu_flag::wait; |
| 44 | |
| 45 | auto& cfg = *ensure(g_fxo->try_get<libio_sys_config>()); |
| 46 | |
| 47 | if (!ppu.loaded_from_savestate) |
| 48 | { |
| 49 | // Ensure awake |
| 50 | ppu.check_state(); |
| 51 | } |
| 52 | |
| 53 | const u32 queue_id = cfg.queue_id; |
| 54 | auto queue = idm::get_unlocked<lv2_obj, lv2_event_queue>(queue_id); |
| 55 | |
| 56 | while (queue && sys_event_queue_receive(ppu, queue_id, vm::null, 0) == CELL_OK) |
| 57 | { |
| 58 | if (ppu.is_stopped()) |
| 59 | { |
| 60 | ppu.state += cpu_flag::again; |
| 61 | return; |
| 62 | } |
| 63 | |
| 64 | // Some delay |
| 65 | thread_ctrl::wait_for(10000); |
| 66 | |
| 67 | // Wakeup |
| 68 | ppu.check_state(); |
| 69 | ppu.state += cpu_flag::wait; |
| 70 | |
| 71 | const u64 arg1 = ppu.gpr[5]; |
| 72 | const u64 arg2 = ppu.gpr[6]; |
| 73 | const u64 arg3 = ppu.gpr[7]; |
| 74 | |
| 75 | // TODO: Reverse-engineer proper event system |
| 76 | |
| 77 | if (arg1 == 1) |
| 78 | { |
| 79 | while (!cellPad_NotifyStateChange(arg2, arg3, false)) |
| 80 | { |
| 81 | if (!queue->exists) |
| 82 | { |
| 83 | // Exit condition |
| 84 | queue = null_ptr; |
| 85 | break; |
| 86 | } |
| 87 | |
| 88 | thread_ctrl::wait_for(100); |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | sys_io.notice("config_event_entry(): Exited with the following error code: %s", CellError{static_cast<u32>(ppu.gpr[3])}); |
| 94 | |
| 95 | ppu_execute<&sys_ppu_thread_exit>(ppu, 0); |
| 96 | } |
| 97 | |
| 98 | std::unique_lock<shared_mutex> lock_lv2_mutex_alike(shared_mutex& mtx, ppu_thread* ppu) |
nothing calls this directly
no test coverage detected