Spinlock is a lock where a thread that fails to acquire it busy-waits in a tight loop, repeatedly retrying an atomic test-and-set, instead of yielding to the OS scheduler. Spinning avoids context-switch overhead, making spinlocks cheap when the critical section is short, but burns CPU cycles when contention is high.
Spinlocks are efficient only when expected wait time is shorter than the cost of two context switches; they are typically used in kernels and low-level runtimes.
This example compares naive spinlock with test-and-test-and-set optimization.
// compile: gcc -std=c11 -pthread -O2 -o spinlock spinlock.c // run: ./spinlock // description: naive spinlock vs test-and-test-and-set variant #include <stdio.h> #include <pthread.h> #include <stdatomic.h> atomic_flag lock_naive = ATOMIC_FLAG_INIT; atomic_flag lock_ttas = ATOMIC_FLAG_INIT; void spin_lock_naive(atomic_flag* lock) { while (atomic_flag_test_and_set(lock)) { } } void spin_lock_ttas(atomic_flag* lock) { while (atomic_flag_test_and_set(lock)) { while (atomic_flag_test(lock)) { } } } void* worker_naive(void* arg) { for (int i = 0; i < 100000; i++) { spin_lock_naive(&lock_naive); atomic_flag_clear(&lock_naive); } return NULL; } int main() { pthread_t t1, t2; pthread_create(&t1, NULL, worker_naive, NULL); pthread_create(&t2, NULL, worker_naive, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("Spinlock test complete\n"); return 0; }