Atomic Hardware Instructions: Test-and-Set (TSL) vs Compare-and-Swap (CAS)
Every beginner systems programmer eventually attempts to build a mutual exclusion lock using a simple global boolean flag:
volatile int lock = 0;
void acquire() {
while (lock == 1); // 1. Spin until lock is free
lock = 1; // 2. Set the lock
}
void release() {
lock = 0;
}
On paper, this looks intuitive. In production silicon, it fails catastrophically.
⚡ The Disastrous Race Condition
The fundamental flaw is that testing the lock and setting the lock are two separate, interruptible assembly instructions:
[ Core 1: Thread A ] [ Core 2: Thread B ]
│ │
├─ 1. Reads lock (0: Free) │
│ (Preempted / Interrupted!) │
│ ├─ 2. Reads lock (0: Free)
│ ├─ 3. Writes lock = 1
│ ├─ 4. Enters Critical Section!
├─ 5. Resumes! Writes lock = 1 │
├─ 6. Enters Critical Section! (💥 DUPLICATE ENTRY)
Both threads enter the critical section concurrently, corrupting shared memory.
🛡️ Atomic Hardware Instructions
To solve this, CPU chip designers introduced hardware-level instructions that perform read-modify-write operations atomically in a single indivisible bus transaction:
1. Test-and-Set Lock (TSL)
On x86 architectures (via BTS or XCHG with the LOCK prefix):
TSL Register, LockVar
In a single clock cycle, the CPU:
- Locks the shared memory bus (or asserts cache line exclusivity via MESI protocol).
- Copies the current value of
LockVarinto the CPU register. - Overwrites
LockVarwith1. - Releases the bus.
Because no other CPU core can access the memory address between the read and the write, mutual exclusion is physically guaranteed!
2. Compare-and-Swap (CAS)
Represented by CMPXCHG on x86, CAS is the universal primitive behind all modern lock-free programming:
bool CAS(int *addr, int expected, int new_value) {
if (*addr == expected) {
*addr = new_value;
return true;
}
return false;
}
If another core modified the variable in the background, CAS fails safely without locking, allowing the caller to retry in a lock-free loop.
Trace atomic memory bus locks on Binary Dose.
Top comments (0)