CS452 - Real-Time Programming - Fall 2008

Lecture 11 - Send/Receive/Reply


Questions & Comments


Producer/Consumer

Two ways to do this

  1. Producer Sends, consumer Receives

    After Reply buffers holding data can be overwritten at will

  2. Producer Receives and Replys

    After Reply buffers can be overwritten at will.

What is the difference?

  1. If relationship is one-to-one
  2. If relationship is many-to-one
  3. If relationship is many-to-many

int Send( Tid tid, char *arg, int arg-length, char *reply-buffer, int reply-buffer-size )

These are pretty self explanatory, except

  1. The return value is the number of characters actually placed in the reply-buffer
  2. If something goes wrong, the return value is negative, coded to indicate what went wrong

    What can go wrong

    1. Illegal tid
    2. tid not an existing task

    It's up to Send to check that the reply-buffer was big enough by looking at its return value

    It's not an error if the task to which we Send never Receives

  3. Parsing argument and reply-buffer is potentially costly and error-prone
  4. This form of message passing requires user and kernel code to cooperate to avoid malignancies

Implementing Send

What's in application space is just stubs.

What the kernel must do

  1. Check arguments
  2. Change state of sender to RECEIVE_BLOCKED
  3. Put sender on receiver's sendQ
  4. If receiver is SEND_BLOCKED, do 3 in receiver
  5. Wait for Reply

int Receive( Tid *tid, char *arg-buffer, int arg-buffer-length )

These are pretty self explanatory, except

  1. How is the task id copied form kernel to receiver?
  2. What if the buffer wasn't big enough?
  3. If several tasks have Sended, which one gets Received first?
  4. return value is number of bytes in message, including \0.

Implementing Receive

What the kernel must do

  1. Check the sendQ
  2. If SENDQ_EMPTY
    1. change state to SEND_BLOCKED
    2. Wait for Send
  3. sendQ is not empty
    1. sender = head( sendQ )

      sendQ = next( sendQ )

    2. copy message from sender to receiver, after checking buffer sizes
    3. change sender's state to REPLY_BLOCKED
    4. put sender's tid into receiver's variable
    5. put receiver on readyQ
    6. set up receiver's return value
    7. change receiver's state to READY

int Reply( Tid tid, char *reply, int reply-length )

These are pretty self explanatory.

Implementing Reply

  1. Check arguments
  2. Copy message from replier to sender, checking buffer sizes
  3. Put sender on readyQ
  4. Set up sender's return value
  5. Change sender's state to READY
  6. Put replier on readyQ
  7. Set up replier's return value

Return to: