| 75 | constexpr u32 c_max_ppu_name_size = 28; |
| 76 | |
| 77 | void _sys_ppu_thread_exit(ppu_thread &ppu, u64 errorcode) { |
| 78 | ppu.state += cpu_flag::wait; |
| 79 | u64 writer_mask = 0; |
| 80 | |
| 81 | sys_ppu_thread.trace("_sys_ppu_thread_exit(errorcode=0x%llx)", errorcode); |
| 82 | |
| 83 | ppu_join_status old_status; |
| 84 | |
| 85 | // Avoid cases where cleaning causes the destructor to be called inside IDM |
| 86 | // lock scope (for performance) |
| 87 | shared_ptr<named_thread<ppu_thread>> old_ppu; |
| 88 | { |
| 89 | lv2_obj::notify_all_t notify; |
| 90 | lv2_obj::prepare_for_sleep(ppu); |
| 91 | |
| 92 | std::lock_guard lock(id_manager::g_mutex); |
| 93 | |
| 94 | // Get joiner ID |
| 95 | old_status = ppu.joiner.fetch_op([](ppu_join_status &status) { |
| 96 | if (status == ppu_join_status::joinable) { |
| 97 | // Joinable, not joined |
| 98 | status = ppu_join_status::zombie; |
| 99 | return; |
| 100 | } |
| 101 | |
| 102 | // Set deleted thread status |
| 103 | status = ppu_join_status::exited; |
| 104 | }); |
| 105 | |
| 106 | if (old_status >= ppu_join_status::max) { |
| 107 | lv2_obj::append(idm::check_unlocked<named_thread<ppu_thread>>( |
| 108 | static_cast<u32>(old_status))); |
| 109 | } |
| 110 | |
| 111 | if (old_status != ppu_join_status::joinable) { |
| 112 | // Remove self ID from IDM, move owning ptr |
| 113 | old_ppu = g_fxo->get<ppu_thread_cleaner>().clean( |
| 114 | idm::withdraw<named_thread<ppu_thread>>(ppu.id, 0, |
| 115 | std::false_type{})); |
| 116 | } |
| 117 | |
| 118 | // Get writers mask (wait for all current writers to quit) |
| 119 | writer_mask = vm::g_range_lock_bits[1]; |
| 120 | |
| 121 | // Unqueue |
| 122 | lv2_obj::sleep(ppu); |
| 123 | notify.cleanup(); |
| 124 | |
| 125 | // Remove suspend state (TODO) |
| 126 | ppu.state -= cpu_flag::suspend; |
| 127 | } |
| 128 | |
| 129 | while (ppu.joiner == ppu_join_status::zombie) { |
| 130 | if (ppu.is_stopped() && |
| 131 | ppu.joiner.compare_and_swap_test(ppu_join_status::zombie, |
| 132 | ppu_join_status::joinable)) { |
| 133 | // Abort |
| 134 | ppu.state += cpu_flag::again; |
no test coverage detected