pub enum AtomicOp {
Load,
LoadInto,
Store,
Fence,
CompareExchange,
SwapBool,
SwapValue,
Exchange,
ExchangeInto,
TestAndSet,
Fetch(Rmw),
Update(Rmw),
}Expand description
Which of the atomic shapes a call is, once the family it came from stops mattering.
Fewer of these than there are names, because __sync_synchronize() and
__atomic_thread_fence(__ATOMIC_SEQ_CST) are the same node with the same ordering, and the
only difference between the two families is which orderings a name can be written with.
The three compare and exchange shapes are three rather than one because they differ in what they answer and in where they were handed the value to compare against, and those are the two things the walk to the IR has to know. What they do to the object is the same in all three.
Variants§
Load
A read of the object the first operand points at.
LoadInto
The same read, written into the object the second operand points at rather than answered.
The unsuffixed __atomic_load, which is the form for an object too big to come back in a
register. A separate shape rather than the same one with an operand on the end, because what
the walk to the IR does with it differs: this one answers nothing and writes twice.
Store
A write of the second operand into the object the first points at.
Fence
A barrier, which touches no object and is the ordering by itself.
CompareExchange
A compare and exchange whose second operand is a pointer to the value expected, which is where what was found is written back when the two did not match. Answers whether they did.
SwapBool
A compare and exchange whose second operand is the expected value itself, answering whether
it matched. The older family’s __sync_bool_compare_and_swap.
SwapValue
The same, answering what was found rather than whether it matched.
Exchange
The second operand goes into the object and what was there comes back.
One shape rather than two, because an exchange is the one read modify write whose answer afterwards is a value the caller already has, so no name in the family asks for it.
ExchangeInto
The same exchange, with what was there written into the object the third operand points at
rather than answered. The unsuffixed __atomic_exchange.
TestAndSet
An exchange of a one into the byte the first operand points at, answering whether that byte held anything before.
__atomic_test_and_set, which is the one name in the family whose object is a byte whatever
the pointer it was handed points at. It is a shape of its own rather than an exchange with
the comparison written around it because the value that goes in is the implementation’s to
choose, and choosing it in one place is what keeps it the same value __atomic_clear puts
back.
Fetch(Rmw)
A read, an operation on what was read, and a write back, answering what was there before.
Update(Rmw)
The same, answering what is there afterwards.
A separate shape rather than the arithmetic written around a AtomicOp::Fetch by whatever
checked the call, because the two are one instruction on most machines and the one that
answers afterwards is the one that is a subtraction away from it. Which of the two a machine
has is the back end’s business, and this is where the difference is written down until it
gets there.