CS537 10/21
Brief Concurrency Atomicity (Data) OS Support + hardware support Ordering (Control - When code runs) New primitive: condition variable What makes a good lock? Correctness Overhead Fairness (extreme: starvation - never get lock) Problems: (Focus on overhead) Spin lock (xchg-based) T1 enter critical section, T2 spin How to reduce waste of spinning OS Support yield() System Call when thread calls yield moves calling thread from RUNNING to READY (Push to back of scheduling queue) while (AtomicExchange(&m->lock, 1) == 1) { yield(); } Worst case w/o yield $waste = num;of;threads \times length;of;time;slice$ $T_1$ in middle of critical section -> timer interrupt -> switch to $T_2$ spin -> $T_3$ spin … With yield $waste = num;of;threads \times context;switch;cost$ Worst case with yield is much faster than just spinning Using Queue with Spin-lock typedef struct __lock_t { int flag; // state of lock: 1=held, 0=free int guard; // use to protect flag, queue queue_t *q; // explicit queue of waiters } lock_t; void lock_init(lock_t *lock) { lock->flag = lock->guard = 0; lock->q = queue_init(); } void lock(lock_t *lock) { while (xchg(&lock->guard, 1) == 1) ; // spin if (lock->flag == 0) { // lock is free: grab it!...