1. Using TAS tas y, sd return y; // Returns 1 if request failed; 0 otherwise 2. Using xchg as a TAS: source and dest are both memory locations TO LOCK: set src = 1 (that is the value you want in the lock location) use lock_var as dest (dest is the actual lock) xchg dest, src after xchg, src tells you if you succeeded or not, because it contains what was in dest (the lock) when you started. If the lock was 0, then it was available and you got it; if it was 1, then the lock was already held, and you didn't get it. TO UNLOCK: dest = 0 3. TAS using CAS: CVAR = 0 cmpxchg *sd, 1 if (ISSET(ZF)) /* Cmp succeeded; we got the spinlock. */ return 0 else return 1 4. LL/SC like a transaction It's basically implementing a transaction on a single location rather than multiple ones, but "failing the commit" if there have been any intervening operations. 5. Refer to the code in kern/thread/spinlock.c 6. Imagine that we leave interrupts on and just as we successfully obtain a spinlock, a timer interrupt fires and it just so happens that the processing of this interrupt tries to acquire the very spinlock we just acquired! We would have a deadlock situation (the interrupt handler could never finish). That would be bad (TM)! ***** You must only use spinlocks for short durations. ***** 7. kern/thread/synch.c 8. kern/thread/synch.c 9. A) You can hold locks with interrupts on! B) Locks have a process/thread owner while spinlocks are held by processORS 10. I will only use spinlocks for short critical sections that cannot block. Locks will likely be my goto solution for managing data structure in the "upper" parts of the operating system (e.g., process structures, file system structures, etc). Also, if I need to hold two resources simultaneously, I would do that with locks, not spinlocks. When I need to wait for events, rather than simply obtain exclusive access, I'll need to introduce condition variables. I would imagine using semaphores for scheduling kinds of synchronization -- perhaps in situations where I am waiting for a condition, but in which case there is a single specific task to be done, and a particular thread has to do it. I'm not sure if I'll have a need for counting semaphores, but perhaps if I need to limit the number of threads accessing some resource, they will come in handy.