Reputation: 165
I need to atomically assign a = b
if condition c
holds, and do not assign if the condition does not hold. Is there a way to do this in C/C++?
Clarification: I meant atomically "test and assign", rather than "atomically assign".
Upvotes: 6
Views: 5341
Reputation: 275585
If c
is some property of a
itself, then compare-exchange atomic operations can solve your problems. You have indicated in comments that this is not the case.
Failing that, wrap all access of c
(anything that reads its state or modifies its state) and a
within a locks of a common std::mutex
.
Test c
and assign to a
within a lock of that std::mutex
.
Failing that, write a single-threaded program.
Failing that, use OS-level APIs to suspend every thread in your process except yourself, then test c
and possibly assign to a
. Note that this could see c
or a
in a state where it is half-written (ie, in an incoherant state), and with the thread suspension plan there really tends not to be a practical way to avoid it, unless both c
and a
are lock-free atomic themselves.
Note that this plan is extremely dangerous and fragile.
Failing that, describe your problem less abstractly and ask another question. The odds are a less abstract version of your problem will have solutions is reasonable.
Upvotes: 2
Reputation: 10326
There isn't a single operation that accomplishes what you require in general. The common case that is covered if is the case where your condition c
tests if a
is already set to some particular value. In this case, the operation you need is a compare-and-exchange, for example:
std::atomic<int> value;
...
int expected = 9;
bool result = std::atomic_compare_exchange_strong(&value, &expected, 10);
Here value
is set to 10 only if the condition value == 9
holds true, the whole operation being atomic.
If your condition doesn't take this form, then you would have to uses mutexes (or some other multiple-operation mechanism) to achieve atomicity.
Upvotes: 16