In serial code, updating a maximum could be accomplished simply by
template<typename T> void update_maximum(T& maximum_value, T const& value) noexcept { if(value > maximum_value) maximum_value = value; }
However, how should this be done for an atomic<T>
variable holding the maximum value:
template<typename T> void update_maximum(std::atomic<T>& maximum_value, T const& value) noexcept { // want a lock-free, thread-safe implementation }
Obviously, the code from the serial version doesn't work, as another thread may alter maximum_value
between the load and the store. Can one use the compare_exchange
(which compares ==
rather than >
) to implement this? how?
Note that explicit locks are not allowed (the only lock allowed is that which may come with the implementation of std::atomic<T>
).
It doesn't seem to be possible in a single operation, but you can make a loop, that tries to do this, until it finally succeeds or value in atomic variable becomes bigger than value
:
template<typename T> void update_maximum(std::atomic<T>& maximum_value, T const& value) noexcept { T prev_value = maximum_value; while(prev_value < value && !maximum_value.compare_exchange_weak(prev_value, value)) {} }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With