questionmark
questionmark

Reputation: 29

Does CAS operation has to lock cache lines with all 3 values?

If I have compare and swap operation

   void push(const T& data){
            node * newNode = new node{data};
            newNode->next = head.load();
            while(!head.compare_exchange_weak(newNode->next, newNode));
        }

Will such operation make cache lines with pointers head, newNode->next and newNode locked for the thread it's executing in?

P.S. If they are stored in different cache lines of course.

Upvotes: 1

Views: 522

Answers (1)

Jérôme Richard
Jérôme Richard

Reputation: 50298

This is dependent of the target architecture. Indeed, cache line locking is a strategy dependent of the target platform and not is thus not described in the C++ specification (the standard only say that the read-modify-write is done atomically).

On x86 platform, compilers generally use the lock cmpxchg instruction when the size of the data type is small (typically <= 64 bits on a 64 bit system). In such a context, the instruction takes always a memory operand and a register operand in parameter. The compared value is the one stored in the register rax/eax/ax/ah. As a result, expected and desired are directly stored in a register or loaded just before the operation from memory. Only the cache line storing the atomic value could be locked.

Moreover, you can find more information here about the instruction:

This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. To simplify the interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the comparison. The destination operand is written back if the comparison fails; otherwise, the source operand is written into the destination. (The processor never produces a locked read without also producing a locked write.)

Thus, the atomic operation can lock temporary the cache line for the time of the lock cmpxchg instruction.

As pointed out by @Frank, atomic CAS operation working on wide types can result in different assembly instructions. In that case, a lock may be used to ensure atomicity. One can use the function is_lock_free() to check either locks are used for one specific case.

For more information about the x86 instruction and x86 lock prefixes, please read:

Upvotes: 1

Related Questions