| 61 | } |
| 62 | |
| 63 | void Threading::WorkSema::WaitForWorkWithSpin() |
| 64 | { |
| 65 | s32 value = m_state.load(std::memory_order_relaxed); |
| 66 | pxAssert(!IsDead(value)); |
| 67 | while (IsReadyForSleep(value)) |
| 68 | { |
| 69 | if (m_state.compare_exchange_weak(value, STATE_SPINNING, std::memory_order_release, std::memory_order_relaxed)) |
| 70 | { |
| 71 | if (value & STATE_FLAG_WAITING_EMPTY) |
| 72 | m_empty_sema.Post(); |
| 73 | value = STATE_SPINNING; |
| 74 | break; |
| 75 | } |
| 76 | } |
| 77 | u32 waited = 0; |
| 78 | while (value < 0) |
| 79 | { |
| 80 | if (waited > SPIN_TIME_NS) |
| 81 | { |
| 82 | if (!m_state.compare_exchange_weak(value, STATE_SLEEPING, std::memory_order_relaxed)) |
| 83 | continue; |
| 84 | m_sema.Wait(); |
| 85 | break; |
| 86 | } |
| 87 | waited += ShortSpin(); |
| 88 | value = m_state.load(std::memory_order_relaxed); |
| 89 | } |
| 90 | // Clear back to STATE_RUNNING_0 (but preserve waiting empty flag) |
| 91 | m_state.fetch_and(STATE_FLAG_WAITING_EMPTY, std::memory_order_acquire); |
| 92 | } |
| 93 | |
| 94 | bool Threading::WorkSema::WaitForEmpty() |
| 95 | { |
no test coverage detected