Lukas' Notes

operating-systems concurrency computer-architecture

Definition

Spinlock

A spinlock is a mutual exclusion primitive in which a thread repeatedly checks an atomic lock variable until it can set the variable and enter the critical section.

The waiting thread does not block; it spins in a loop.

Mechanism

Atomic acquisition

A spinlock requires an atomic operation for acquisition. Ordinary loads and stores are insufficient, because the read of the lock variable and the write to it are not indivisible.

A typical implementation uses atomic exchange:

void lock(std::atomic<int>* lockvar) {
    while (lockvar->exchange(1, std::memory_order_acquire) == 1) {
        // busy-wait
    }
}
 
void unlock(std::atomic<int>* lockvar) {
    lockvar->store(0, std::memory_order_release);
}

The exchange operation returns the old value. If it was already 1, some other thread holds the lock; otherwise the current thread has acquired it.

RISC-V

RISC-V code

On RISC-V, the acquire operation compiles to an atomic swap with acquire ordering:

li a1, 1
.LBB0_1:
amoswap.w.aq a2, a1, (a0)
beq a2, a1, .LBB0_1
ret

Release compiles to a store preceded by a fence:

fence rw, w
sw zero, 0(a0)
ret

Limitation

Busy waiting

A spinlock wastes CPU time while a thread waits. It is suitable only when the critical section is short and contention is low.