If the block will cause the execution context to be idle (fewer thread than execution context), busy wait might be a better choice.
What does "block until true" mean? I'm rather confused by what blocking synchronization is about. In busy waiting, the thread continues to spin in a tight loop until the while condition is false, but here, it seems that the current thread just breaks off (gets de-scheduled), and then... what happens to the rest of the program?
@totofufu Block is typically implemented as a conditional variable. If the condition is not true, then the thread is descheduled, which means it is no longer running. Once some other thread completes the requirements for the condition, for example releases some resource, it signals (broadcasts) that conditional variable. Hence the thread(s) waiting on that conditional variable know that the condition has possibly changed, so they can recheck it. Typically the waiting thread is set as runnable. It may not immediately run, but that depends on the scheduling policy.
I tried searching and couldn't find anything, but I'm pretty sure blocking until a certain condition is true tells the OS to de-schedule it. During the review at the beginning of this lecture, we went over how interleaving works - basically, after a certain number of cycles, the OS can switch out threads from their execution contexts. I believe this works in the same way.
If a thread is blocking to wait for a resource or for something to become true, then the OS can have another thread run for a while. I think the interleaving allows the original thread to come back. When it's switching out threads, it can check if an inactive thread is still blocking to see if it should be assigned to an execution context. This way, the blocking thread doesn't waste precious resources.
^ This is what I think. No claims to being correct.
The sample code shown during the lecture uses waitforsingleobject to achieve blocking synchronization. According to this doc, the first parameter is the handle (event) that the thread is waiting for, and the second parameter is the time-out interval. The thread is blocked until the event finally occurs, and will move on to the while condition to try to acquire the lock again.
Probably a late follow-up but I recently just came across condition variable, and I'll just explain it here since it's OS-level concept.
A condition variable is a queue where threads can put themselves and go to sleep until some certain condition is satisfied. Its interface mainly includes three functions:
Condvar primitive can be directly used as a blocking mechanism, as it avoids burning cycles as a thread is waiting on a certain condition. However, as the lecture later mentions, this method incurs OS scheduling cost (up to 1000 cycles), and sometimes it might be better to use a simple spin lock.
@yimmyz. I think you mean "condition variable". ;-)
A thread can call the yield() syscall to let the kernel know that "I can't make progress right now, schedule other threads and come back to me later." The kernel will keep track of the yielded threads and check back when the kernel thinks it can make progress (for example, a certain condition is satisfied.)
I don't think you should always busy wait if you have fewer threads then execution contexts.
One reason, as discussed, is that the thread is holding resources which other threads thread could use. In addition, if the expected wait time is larger, then busy waiting is not energy efficient.