| 298 | } |
| 299 | |
| 300 | error_code sys_mutex_unlock(ppu_thread &ppu, u32 mutex_id) { |
| 301 | ppu.state += cpu_flag::wait; |
| 302 | |
| 303 | sys_mutex.trace("sys_mutex_unlock(mutex_id=0x%x)", mutex_id); |
| 304 | |
| 305 | const auto mutex = idm::check<lv2_obj, lv2_mutex>( |
| 306 | mutex_id, |
| 307 | [&, notify = lv2_obj::notify_all_t()](lv2_mutex &mutex) -> CellError { |
| 308 | auto result = mutex.try_unlock(ppu); |
| 309 | |
| 310 | if (result == CELL_EBUSY) { |
| 311 | std::lock_guard lock(mutex.mutex); |
| 312 | |
| 313 | if (auto cpu = mutex.reown<ppu_thread>()) { |
| 314 | if (cpu->state & cpu_flag::again) { |
| 315 | ppu.state += cpu_flag::again; |
| 316 | return {}; |
| 317 | } |
| 318 | |
| 319 | mutex.awake(cpu); |
| 320 | } |
| 321 | |
| 322 | result = {}; |
| 323 | } |
| 324 | |
| 325 | notify.cleanup(); |
| 326 | return result; |
| 327 | }); |
| 328 | |
| 329 | if (!mutex) { |
| 330 | return CELL_ESRCH; |
| 331 | } |
| 332 | |
| 333 | if (mutex.ret) { |
| 334 | return mutex.ret; |
| 335 | } |
| 336 | |
| 337 | return CELL_OK; |
| 338 | } |
no test coverage detected