During code review of my demo, reviewer suggested to use atomic_fetch_max compatible with the proposal Atomic maximum/minimum:
template<typename T> T atomic_fetch_max(std::atomic<T>* obj, typename std::atomic<T>::value_type arg) noexcept { auto prev = *obj; while (prev < arg && !obj->compare_exchange_weak(prev, arg)) {} return prev; } instead of my code
template<typename T> void update_max(std::atomic<T>& max_value, T const& value) noexcept { T prev_value = max_value; while (prev_value < value && !max_value.compare_exchange_weak(prev_value, value)) {} } I tried to incorporate it into my demo and can't make it compiled. Please see the demo.
Two questions here related to the problem:
- Why the suggested version fails to compile? I can't get the reason from compiler messages (they are too long and I am not sure how to include them here, please update the question if you know the format, I will follow).
- What is the reason the updated version uses
typename std::atomic<T>::value_type arginstead of plainTor even betterT const &which makes arg referenced value const?
Tby value makes sense for any(?)Tthat's worth using withstd::atomic<>: trivially-copyable and small enough to be lock-free also means it can easily be passed in registers. You normally want this to inline anyway, but if not, pass by value should be efficient. Except maybe for objects the size of 2 pointers in some calling conventions. But most objects you're likely to wantmaxon are single numbers, where passing by value is more efficient if there ever is a non-inline function call.*objproduces astd::atomic<T> &which is whatautopicks. godbolt.org/z/P4hhTTaYz They should have usedobj->load()or betterobj->load(std::memory_order_relaxed). All the other changes, like returning the old value and takingT(orvalue_type) by value make sense and seem like improvements to me. Except for using...::value_typeinstead ofT, that seems over-complicated especially when they're still just returning aTT(by value) orconst T &(by reference).Tinstead ofT const&.)Tinstead ofT const &. (Orvalue_typeinstead ofvalue_type const&). Instead of editing the duplicate list twice for this question, I waited until I'd found that Q&A as well as the one about P0558R1.