Go backward to Process Management
Go up to The Kernel
Go forward to initmbox

Messages and Mail Boxes

There are two object types involved in implementing message passing: messages and mail boxes. Declarations for the structures I would like you to use to represent these objects in your kernel are shown below.
struct mbox        /* Structure used to represent a mailbox   */
  int availcount;                    /* Count of the number of messages in */
                                     /* the 'headmes' queue that have not  */
                                     /* been "promised" to a recently      */
                                     /* awakened process.                  */
  struct msg *headmes, *tailmes;     /* Pointer for list of messages sent  */
                                     /*  to this mailbox but not yet       */
                                     /*  received.                         */
  struct pcb *headproc,*tailproc;    /* Pointers for list of processes     */
                                     /*  waiting to receive messages from  */
                                     /*  this mailbox.                     */
;

struct msg    /* Structure used to hold a message          */
  int type,      /* A code used to hold the type of the message */
      value;     /* The value of the message                    */
  struct msg 
	*link;   /* A field used as a ``next'' pointer when messages are  */
                 /*  put in lists.                                        */
;

A mail box can be in three states. Either it is completely inactive, or there are processes waiting to receive messages from the mail box or there are messages waiting to be delivered from the mailbox. To handle these states, the "mbox" structure is basically designed to maintain two FIFO queues. The first queue's head and tail pointers are to be kept in "headmes" and "tailmes". This queue will be empty when there are no messages waiting to be delivered. If there are messages waiting to be delivered, they will be stored in this queue in the order in which they were sent.

The other queue's head and tail pointer are kept in "headproc" and "tailproc". This queue will be empty unless there are processes waiting to receive messages. If there are processes waiting for messages, this queue will hold those processes in the order in which they executed receive primitives.

The "msg" structure is designed to hold the value of a message and a linked list pointer field used when it is necessary to hold the message in the "headmes/tailmes" queue of a mailbox. The actual message is to be stored in the "type" and "value" fields. These two words are sufficient to store any message, because if a larger message is to be sent, one can just store a pointer to the message in the "value" field (C's type system will let you coerce an integer value like "value" into a pointer to the type of your choice). It should be obvious, therefore, that just a single "value" field without the "type" field would be sufficient. This is true. In many cases, you will not use the "type" field at all. It is provided because it is painless to include and on some occasions will enable you to pass a message more conveniently.

Just as the kernel does not dynamically allocate PCB or stack space for processes, it will not dynamically allocate mail boxes or message structures. If two processes wish to communicate, a variable of type "struct mbox" must be declared in some scope accessible to both processes (this normally means that each mail box must be declared as a global variable). When a process wishes to send a message, it must find an available message slot. If at most one message at a time is to be sent, this can be done by declaring a local variable of type "struct msg" in the function containing the process' code (or declaring it as a global variable). If a local variable is used, make sure that the function containing the declaration can not return until the message has been received and processed. In the case where something more like dynamic allocation is needed, the message passing primitives themselves can be used to help. I elaborate on this in the discussion of input/output buffers.

Your kernel must provide three primitives for manipulating mail boxes and messages: initmbox, send and receive.



Prev Up Next