P(S); items--; V(S); return buffers[items];It should have read
P(S); BufferItem item = buffers[items-1]; items--; V(S); return item;The change makes sure the correct item is copied out of the buffer while still in the critical section.
MPC is optimized to process local messages first. If there's an enabling message from another entity on the same processor, that message will be executed in favor of a message from a remote processor. This leads to the unfortunate possibility of an infinite loop.
#include |
If we run this program on a single processor, the sequence of events is roughly as follows:
In some sense, the program behavior is still legal. Parsec/MPC semantics state that if two enabling messages of different types (i.e. Die and Ping) are available, a non-deterministic choice will be made between them. However, suppose we change the code to read:
or receive (Ping p) when (qempty(Die)) {Now the program is no longer non-deterministic. It must choose a Die message if one is available. (qempty is a predefined boolean function in Parsec/MPC which checks the input queue for a particular message type.) Unfortunately, qempty also does not check the remote queue, and the program still doesn't terminate. This leads me to believe that the program behaviour is incorrect. Professor Bagrodia argues that the program behavior is still technically correct (at least not provably wrong) because Parsec only guarantees that remote messages may be delivered "eventually," and the definition of "eventual" can be stretched to an arbitrary time less than infinity. Nevertheless, this anomolous behavior will cause a large class of programs to act in unexpected, if not literally incorrect, ways.