4.2.15 · HinglishOperating Systems

Mutex — implementation using hardware atomics (test-and-set, CAS)

2,143 words10 min readRead in English

4.2.15 · Coding › Operating Systems


WHY kyu hume hardware ki zarurat hai?

Fix yeh hai: ek single CPU instruction jo old value read kare AUR new value ek atomic, uninterruptible step mein likhe, bus lock ke saath taaki koi aur core beech mein ghus na sake.


WHAT hai ek atomic instruction?


test-and-set: lock ko scratch se derive karo

HOW TAS se spinlock banao

WHY yeh correct hai. test_and_set hamesha lock = 1 set karta hai. Return value batati hai ki woh pehle kya tha:

  • Agar old value 0 thi → lock free tha, aur humne abhi ise claim kar liya. Loop exit karta hai → humara hai.
  • Agar old value 1 thi → koi pehle se hold kar raha tha; humne ise phir se 1 set kar diya (harmless, woh already 1 tha) aur spin karte rahe.

"Check" (read old) aur "claim" (write 1) ab ek indivisible action hain, toh upar wali race ho hi nahi sakti. Read aur write ke beech koi window nahi hai jahan koi doosra thread ghus sake.


compare-and-swap (CAS): zyada powerful primitive

WHY CAS > TAS. TAS sirf ek boolean manipulate kar sakta hai. CAS tumhe kehne deta hai "X ko tabhi change karo jab woh wahi value ho jo maine last dekhi thi." Yeh lock-free data structures (counters, stacks, queues) enable karta hai, sirf mutexes nahi. Yeh AtomicInteger.compareAndSet, std::atomic::compare_exchange, etc. ki foundation hai.

Figure — Mutex — implementation using hardware atomics (test-and-set, CAS)

Worked examples



Flashcards

Why can't a plain while(lock){} lock=1 implement a mutex?
lock ka read aur write do alag instructions hain; beech mein context switch do threads ko dono "free" dekhne deta hai aur dono andar aa jaate hain — mutual exclusion toot jaati hai.
What does test_and_set(addr) do atomically?
addr par old value read karta hai, *addr = 1 set karta hai, old value return karta hai — sab ek indivisible step mein.
In a TAS spinlock, what does a returned old value of 0 mean?
Lock free tha aur tumne abhi ise acquire kar liya; spin loop se bahar niklo.
What does compare_and_swap(addr, expected, new) do?
Atomically: agar *addr == expected ho, toh *addr = new set karo aur true return karo; warna chhod do aur false return karo.
Why is CAS more powerful than test-and-set?
CAS write ko current value ke expected value se match hone par condition karta hai, lock-free data structures enable karta hai; TAS sirf ek boolean flip karta hai.
What is the ABA problem?
Ek CAS succeed ho jaati hai kyunki value expected ke barabar hai, lekin woh actually beech mein A→B→A change ho chuki thi; CAS intermediate change detect nahi kar sakta. Version tags se fix karo.
Why does Test-and-Test-and-Set reduce bus traffic?
Yeh saste cached read par spin karta hai aur expensive atomic RMW sirf tab karta hai jab lock free lagta ho, cache-line bouncing se bachata hai.
Is busy-wait spinning always bad?
Nahi — bahut chote critical sections ke liye multi-core par, spinning context-switch overhead se bachata hai aur sleeping se tez hota hai.
Why is volatile insufficient for a lock flag?
Yeh compiler caching toh rok deta hai lekin atomic read-modify-write ya memory-ordering guarantees nahi deta.
What memory ordering does acquire/release need?
Acquire ko acquire barrier chahiye (koi baad wala op usse pehle na move ho); release ko release barrier chahiye (koi pehle wala op uske baad na move ho) taaki critical-section writes unlock se pehle visible hon.

Recall Feynman: 12-saal ke bacche ko explain karo

Socho ek bathroom hai aur darwaze par ek sign hai jo kehta hai FREE ya BUSY. Agar do bacche sign ko ek hi pal dekhein, dono FREE dekhte hain aur dono barge in karte hain — chaos. Trick: ek jadui darwaze ka handle jo, ek snap mein, sign dekhta bhi hai AUR use BUSY kar deta hai, phir batata hai sign pehle kya keh raha tha. Agar FREE keh raha tha, tum andar aa gaye. Agar BUSY keh raha tha, koi tumse pehle aa gaya — bahar ruko. Kyunki dekhna aur flip karna ek saath hota hai bina kisi gap ke, do bacche kabhi dono nahi jeet sakte. Woh jadui handle "test-and-set" hai. Ek fancier handle ("CAS") sign ko BUSY tabhi karta hai jab woh exactly FREE ho — jo tumhe bina full lock ke shared cheezein safely change karne deta hai.

Connections

  • Critical Section Problem — woh race jise yeh solve karta hai
  • Spinlock vs Blocking Mutex — wait karte waqt kya karna hai
  • Memory Barriers and Ordering — lock ko cores ke across visible banana
  • Lock-Free Data Structures — CAS par built
  • Semaphores — higher-level counting synchronization
  • Cache Coherence (MESI) — kyun atomics cache-line bouncing cause karte hain
  • Deadlock — mutual exclusion kya lead kar sakta hai

Concept Map

read then write splits into

breaks

glues read+write into one step

locks cache line / bus

type of

type of

sets flag to 1, returns old value

provides

tells thread if it won lock

spin while old was 1

guarantees

Naive boolean lock

Race condition

Mutual exclusion

Atomic RMW instruction

No intermediate state

test-and-set

compare-and-swap

TAS spinlock

Old return value