| 291 | return do_lock_normal(thread, m, flags, ut, mode); |
| 292 | } |
| 293 | static ErrorCode do_unlock_normal(Thread *thread, ptr<umutex> m, uint flags) { |
| 294 | ORBIS_LOG_TRACE(__FUNCTION__, thread->tid, m, flags); |
| 295 | |
| 296 | auto [chain, key, lock] = umtxStorage->getUmtxChain1(thread, flags, m); |
| 297 | |
| 298 | int owner = m->owner.load(std::memory_order_acquire); |
| 299 | if ((owner & ~kUmutexContested) != thread->tid) |
| 300 | return ErrorCode::PERM; |
| 301 | |
| 302 | if ((owner & kUmtxContested) == 0) { |
| 303 | if (m->owner.compare_exchange_strong(owner, kUmutexUnowned)) |
| 304 | return {}; |
| 305 | } |
| 306 | |
| 307 | std::size_t count = chain.sleep_queue.count(key); |
| 308 | bool ok; |
| 309 | if (key.pid == 0) { |
| 310 | ok = m->owner.compare_exchange_strong(owner, kUmutexUnowned); |
| 311 | // IPC workaround (TODO) |
| 312 | chain.notify_all(key); |
| 313 | if (!ok) |
| 314 | return ErrorCode::INVAL; |
| 315 | return {}; |
| 316 | } |
| 317 | |
| 318 | ok = m->owner.compare_exchange_strong(owner, count <= 1 ? kUmutexUnowned |
| 319 | : kUmutexContested); |
| 320 | chain.notify_one(key); |
| 321 | |
| 322 | if (!ok) |
| 323 | return ErrorCode::INVAL; |
| 324 | return {}; |
| 325 | } |
| 326 | static ErrorCode do_unlock_pi(Thread *thread, ptr<umutex> m, uint flags) { |
| 327 | return do_unlock_normal(thread, m, flags); |
| 328 | } |
no test coverage detected