| 108 | } |
| 109 | |
| 110 | bool Threading::WorkSema::WaitForEmptyWithSpin() |
| 111 | { |
| 112 | s32 value = m_state.load(std::memory_order_acquire); |
| 113 | u32 waited = 0; |
| 114 | while (true) |
| 115 | { |
| 116 | if (value < 0) |
| 117 | return !IsDead(value); // STATE_SLEEPING or STATE_SPINNING, queue is empty! |
| 118 | if (waited > SPIN_TIME_NS && m_state.compare_exchange_weak(value, value | STATE_FLAG_WAITING_EMPTY, std::memory_order_acquire)) |
| 119 | break; |
| 120 | waited += ShortSpin(); |
| 121 | value = m_state.load(std::memory_order_acquire); |
| 122 | } |
| 123 | pxAssertMsg(!(value & STATE_FLAG_WAITING_EMPTY), "Multiple threads attempted to wait for empty (not currently supported)"); |
| 124 | m_empty_sema.Wait(); |
| 125 | return !IsDead(m_state.load(std::memory_order_relaxed)); |
| 126 | } |
| 127 | |
| 128 | void Threading::WorkSema::Kill() |
| 129 | { |