The problem is as follows.
Given a POD object that has two parts: index and data. I want to perform an atomic conditional exchange operation over it with a condition that checks equality for the index only.
Something like this:
struct Data { size_t m_index; char m_data; };
std::atomic<Data> dd; // some initialization
Data zz; // some initialization
// so I want something like this
dd.exchange_if_equals<&Data::m_index>(10,zz);
So this is a sort of "partial-compare-and-full-swap" operation. Maybe this will require an appropriate alignment for Data::m_index
.
Obviously std::atomic
doesn't support this, but can one implement this by his own, or maybe there is another library that supports this?
I think you have to do a load, then your custom condition, then a compare-and-swap, where the comparison is that the current value is totally equal to the read value. If the last step fails, loop.
template<class T, class F>
bool swap_if(std::atomic<T>& atomic, T desired, F&& condition) {
for (;;) {
T data = atomic.load();
if (!condition(data)) break;
if (atomic.compare_exchange_weak(data, desired)) return true;
}
return false;
}
http://coliru.stacked-crooked.com/a/a394e336628246a9
Due to the complexity, you should probably just use a mutex.
Separately, std::atomic<Data>
may already be using a mutex under the covers, since Data
is so big.