A: If a guest simply had to enter and leave the monitor once, you would be right. The guest would just lock it, conduct business, unlock it, and then leave the monitor. However, it's not that simple.
The complication is that a guest must enter and leave the monitor several times as he/she walks the buffet line. For example, guest four will call buffet_get multiple times like so:
buffet_get(0,x,4); buffet_get(1,x,4); buffet_get(2,x,4); buffet_get(3,x,4); ...Each time the guest gets some items, he/she must lock the mutex, modify the plate array, unlock the mutex, and then leave. Thus, the monitor must remember which thread is currently using the buffet and force all others to wait until it is done.
A: This is the essence of problem that you must figure out on your own! It is definitely possible to let many (i.e. more than two) guests in at once. The trick is to figure out which set of guests are safe to let in at once.
Start by thinking about this question: is it safe to allow exactly two guests to simultaneously walk the buffet line in opposite directions? You could test this out very easily by simply running "buffet 2 deadlock" and see what happens. If it is safe, why? It is not, why not?
A: Whoops, you are right! There was a bug in the guest thread, although it wouldn't have any effect on your solution. It has been fixed, and you can download a new buffet.c as of 12 noon, Feb 16th.
A: On some machines, MULTI may not actually be much faster than SINGLE. (This is because it takes a significant number of CPU cycles to draw all those rapidly-scrolling words on the screen.) The important part is that you are allowing more than one to pick items at once. You should be able to verify this simply by reading the output of the buffet simulation.
A monitor requires all operations on the condition variable to happen *inside* the monitor, that is, inside a lock/unlock pair.
A: Moreover, you only want to broadcast (or signal) if you know that the monitor's variables are in a consistent state and it is safe for another thread to wake up. The only way that you can know this is if you hold the monitor mutex, ensuring that no-one else has modified the monitor's variables in the mean time.
You can, but it's difficult to get right. The problem is, what do you do if the thread chosen to be woken up isn't actually ready to go? It must then issue another signal and then go back to sleep. Then, what if no threads are ready to proceed? You have to have some way of stopping the signal from going around continuously. This is possible, but very tricky to get all of the boundary conditions right.
Thus, I always use a while() loop combined with broadcast(). This is a defensive programming style. Every thread has the opportunity to wake up and examine its condition, and you don't have to worry about which thread gets woken up. Of course, broadcast is less efficient, because many threads wake up even if only one will eventually be allowed to run.