|
|
@ -97,7 +97,7 @@ public: |
|
|
|
|
|
|
|
// Check if we jumped the fence |
|
|
|
if(fence_v <= new_offset && fence_v > old_offset) { |
|
|
|
return std::nullopt; |
|
|
|
goto handle_fence; |
|
|
|
} |
|
|
|
|
|
|
|
// Check if we jumped the fence while overflowing |
|
|
@ -108,9 +108,25 @@ public: |
|
|
|
new_offset %= max_offset; |
|
|
|
} |
|
|
|
if(fence_v <= new_offset) { |
|
|
|
goto handle_fence; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
goto handle_fence_end; |
|
|
|
handle_fence: |
|
|
|
if constexpr (OverflowStrategy::on_overflow == overflow_response_t::must_wait) { |
|
|
|
return std::nullopt; |
|
|
|
} else if constexpr (OverflowStrategy::on_overflow == overflow_response_t::must_overflow) { |
|
|
|
if(!fence.compare_exchange_weak(fence_v, new_offset, std::memory_order_release, std::memory_order_relaxed)) { |
|
|
|
return std::nullopt; |
|
|
|
} |
|
|
|
} else { |
|
|
|
static_assert( |
|
|
|
OverflowStrategy::on_overflow == overflow_response_t::must_wait |
|
|
|
|| OverflowStrategy::on_overflow == overflow_response_t::must_overflow |
|
|
|
); |
|
|
|
} |
|
|
|
handle_fence_end: |
|
|
|
|
|
|
|
if(!lead.compare_exchange_weak(old_offset, new_offset, std::memory_order_acquire, std::memory_order_relaxed)) { |
|
|
|
return std::nullopt; |
|
|
|