Unfortunately, XINU doesn't give us the same synchronization power that Pthreads gave us. This is a real limitation. In fact, XINU message passing gives us no synchronization at all.
XINU message passing consists of 3 routines:
First, lets look at the semantics of these operations.
Send(int pid, int msg) takes the message msg and sends it to the process identified by the argument pid. Send does NOT block. A message in XINU is simply a four-byte value. This would normally be an integer or (perhaps more useful) a pointer. Not being able to send arbitrary-length messages in XINU makes the implementation much easier and isn't really much of a limitation (why? because XINU process all share memory - there isn't much need to copy chunks of memory between processes. This does require, however, that processes are careful not to manipulate sent messages until the receivers are done with them).
One severe limitation of XINUs message passing facility is that it will only allow one outstanding message at a time for a receiver (though don't despair - there is a port message passing facility discussed in chapter 15 that does not have this same restriction). So, if a message has already been sent to process B (by anyone) and a process tries to send B another message before it has issued a receive() to collect the first one, the second send() will fail and return SYSERR. This also makes IPC in XINU easier to implement, but places a fairly big restriction on its use.
If the message transfer works out OK (there is not already another outstanding), send() returns OK.
Receive() in XINU is a blocking operation. If there is an outstanding message for the receiving process, the message is returned. If there is currently no message waiting for that process, then the process is blocked until a message arrives. Thus, receive() will never return anything other than a message. If a message is never sent, it will wait forever.
Recvclr() is just like receive() except that it never blocks. If a message is waiting for the calling process at the time of call, then that message is returned (just as it would have been had receive() been called instead). If, on the other hand, there is no message waiting, then recvclr() will return immediately anyway, with the value OK. Clearly, a sender must therefore be careful about sending the value OK as a message.