
David Abrahams wrote:
OK, so here's what I think I missed: B is blocking on a resource. The scheduler only distributes the running role among the ready threads. If B never becomes ready, it starves. The only way B can become ready is if A releases its lock to the system, so I guess the question is, does A's unlock actually move B into the ready state, or at least cause the scheduler to try to ready B in its next timeslice?
A's unlock has to wake up B (otherwise it will never run, even though the mutex is free), so yes. The only flaw in the ointment ( :-) ) is if the scheduler decides to preempt A while it's inside the critical section. But this is a general problem with any mutex scheme; if threads are frequently preempted while holding a lock, then that lock's granularity is wrong and the application needs to be redesigned. The same situation can occur with three threads, by the way:
A: lock [lockcount == 0] B: lock [lockcount == 1, slow path] A: unlock [lockcount == 0, slow path/post sema] C: lock - [lockcount == 1, slow path]