Message Passing Properties

  • Minix uses the concept of a message to support communication between processes. This is used universally througout Minix whenever one process needs to access another.

  • Minix user processes can only send/receive messages to system processes, not to other user processes.

  • Minix system processes can send messages to other system processes and reply to user process messages subject to certain restrictions.

  • The following message passing functions are implemented by the kernel:

    • send
    • receive
    • sendrec (send/receive)
    • notify
    • echo
  • The first three use the rendezvous style message passing. So sendrec in a user process will block the user if the destination system process is currently doing something other than trying to receive an new request message.

  • The _syscall function used by user level programs actually uses the sendrec (send/receive) function to send a request and receive a reply.

  • The notify type message does not use the rendezvous. That is, it does not get blocked if the destination is not yet ready to receive the notification.

  • The echo is used by the kernel process for passing a message from a process to itself.

Message Format

A message consists of: the process ID of the sending process, an identifier telling the process what sort of message it is, and then a union for holding the actual message structure. The code snippet from the file /usr/src/include/minix/ipc.h shows the message structure :

typedef struct {
  endpoint_t m_source;        /* who sent the message */
  int m_type;         /* what kind of message is it */
  union {
    mess_1 m_m1;
    mess_2 m_m2;
    mess_3 m_m3;
    mess_4 m_m4;
    mess_5 m_m5;
    mess_7 m_m7;
    mess_8 m_m8;
    mess_6 m_m6;
    mess_9 m_m9;
    mess_10 m_m10;
  } m_u;
} message __aligned(16);

MINIX 3 has 10 message types (mess_1 to mess_10) as we can see from the message structure above. Each of these message types are unique. The code below from the same file shows the different message types :

typedef struct {int m1i1, m1i2, m1i3; char *m1p1, *m1p2, *m1p3;} mess_1;
typedef struct {int m2i1, m2i2, m2i3; long m2l1, m2l2; char *m2p1; 
        short m2s1;} mess_2;
typedef struct {int m3i1, m3i2; char *m3p1; char m3ca1[M3_LONG_STRING];} mess_3;
typedef struct {long m4l1, m4l2, m4l3, m4l4, m4l5;} mess_4;
typedef struct {short m5s1, m5s2; int m5i1, m5i2; long m5l1, m5l2, m5l3;}mess_5;
typedef struct {long m6l1, m6l2, m6l3; short m6s1, m6s2, m6s3; char m6c1, m6c2;
        char *m6p1, *m6p2;} mess_6;
typedef struct {int m7i1, m7i2, m7i3, m7i4, m7i5; char *m7p1, *m7p2;} mess_7;
typedef struct {int m8i1, m8i2; char *m8p1, *m8p2, *m8p3, *m8p4;} mess_8;
typedef struct {long m9l1, m9l2, m9l3, m9l4, m9l5;
    short m9s1, m9s2, m9s3, m9s4; } mess_9;
typedef struct {int m10i1, m10i2, m10i3, m10i4;
    long m10l1, m10l2, m10l3; } mess_10;