ChorusOS 5.0 Application Developer's Guide

Using ChorusOS Message Queues

Example 11-1 illustrates the basic use of the message queue feature. The example uses the posix_spawn() system call and demonstrates how MIPC can be used with a POSIX process.

For more information, refer to the msgSpaceCreate(2K), msgSpaceOpen(2K), msgAllocate(2K), msgPut(2K), msgGet(2K) and msgFree(2K) man pages.


Example 11-1 Communicating Using Message Spaces

(file: opt/examples/progov/msgSpace.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <chorus.h>
#include <mipc/chMipc.h>
#include <spawn.h>

char* spawn_args[3];

#define NB_MSG_POOLS 2
#define NB_MSG_QUEUES 3
#define SMALL_MSG_SZ  32
#define LARGE_MSG_SZ  256
#define NB_SMALL_MSG  13
#define NB_LARGE_MSG  4
#define SAMPLE_SPACE  1111
#define LARGE_POOL 0
#define SMALL_POOL 1
#define Q1 0
#define Q2 1
#define Q3 2

KnMsgPool samplePools[NB_MSG_POOLS];
char* tagPtr = "Spawned";

int main(int argc, char** argv, char**envp)
{
  int          res;
  int          msgSpaceLi;
  char*        smallMsg;
  char*        smallReply;
  char*        largeMsg;
  KnActorPrivilege actorP;

  res = actorPrivilege(K_MYACTOR, &actorP, NULL);
  if (res != K_OK) {                                                  
      printf("Cannot get actor privilege, error %d\n", res);          
      exit(1);                                                        
  }                                                                   

  if (argc == 1) {
        /*
         * This is the first actor (or spawning actor):
         *   Create a message space,
         *   Spawn another actor,
         *   Allocate, modify and post a small message on Q2
         *   Get a large Message from Q3, print its contents, free it
         *   Get reply of small message on Q1, print its contents, free it.
         */

    samplePools[LARGE_POOL].msgSize = LARGE_MSG_SZ;
    samplePools[LARGE_POOL].msgNumber = NB_LARGE_MSG;

    samplePools[SMALL_POOL].msgSize = SMALL_MSG_SZ;
    samplePools[SMALL_POOL].msgNumber = NB_SMALL_MSG;

    msgSpaceLi = msgSpaceCreate(SAMPLE_SPACE, NB_MSG_QUEUES, 
                                NB_MSG_POOLS, samplePools);
    if (msgSpaceLi < 0) {                                             
        printf("Cannot create the message space error %d\n",          
                msgSpaceLi);                                          
        exit(1);                                                      
    }                                                                 

        /*
         * Message Space has been created, spawn the other actor,
         * argv[1] set to "Spawned" to differentiate the 2 actors.
         */
    spawn_args[0] = argv[0];
    spawn_args[1] = tagPtr;
    spawn_args[2] = NULL; 
        
    res = posix_spawnp(NULL, spawn_args[0], NULL, NULL, spawn_args, NULL);
    if (res < 0) {                                                    
      printf("Cannot spawn second actor, error %d\n", res);
      exit(1);                                                        
    }                                                                 

        /*
         * Allocate a small message 
         */
    res = msgAllocate(msgSpaceLi, SMALL_POOL, SMALL_MSG_SZ, 
                      K_NOTIMEOUT, &smallMsg);
    if (res != K_OK) {                                                
      printf("Cannot allocate a small message, error %d\n", res);     
      exit(1);                                                        
    }                                                                 
    
        /*
         * Initialize the allocated message
         */
    strncpy(smallMsg, "Sending a small message\n", SMALL_MSG_SZ);

        /*
         * Post the allocated small message to Q2 with priority 2
         */
    res = msgPut(msgSpaceLi, Q2, smallMsg, 2);
    if (res != K_OK) {                                                
      printf("Cannot post the small message to Q2, error %d\n", res); 
      exit(1);                                                        
    }                                                                 
    
        /*
         * Get a large message from Q3 and print its contents
         */
    res = msgGet(msgSpaceLi, Q3, K_NOTIMEOUT, &largeMsg, NULL);
    if (res != K_OK) {                                                
      printf("Cannot get the large message from  Q3, error %d\n",     
             res);                                                    
      exit(1);                                                        
    }                                                                 

    printf("Received large message contains:\n%s\n", largeMsg);

        /*
         * Free the received large message
         */
    res = msgFree(msgSpaceLi, largeMsg);
    if (res != K_OK) {                                                
      printf("Cannot free the large message, error %d\n", res);       
      exit(1);                                                        
    }                                                                 

        /*
         * Get the reply to small message from Q1 and print its contents
         */
    res = msgGet(msgSpaceLi, Q1, K_NOTIMEOUT, &smallReply, NULL);
    if (res != K_OK) {                                                
      printf("Cannot get the small message reply from  Q1, "          
             "error %d\n", res);                                      
      exit(1);                                                        
    }                                                                 

    printf("Received small reply contains:\n%s\n", smallReply);

        /*
         * Free the received small reply
         */
    res = msgFree(msgSpaceLi, smallReply);
    if (res != K_OK) {                                                
      printf("Cannot free the small reply message, error %d\n", res); 
      exit(1);                                                        
    }                                                                 


  } else {
    
        /*
         * This is the spawned actor:
         *   Check we have effectively been spawned
         *   Open the message space
         *   Allocate, initialize and post a large message to Q3
         *   Get a small message from Q2, print its contents
         *   Modify it and repost it to Q1
         */

    int     l;

    if ((argc != 2) || (strcmp(argv[1], tagPtr) != 0)) {              
        printf("%s does not take any argument!\n", argv[0]);          
        exit(1);                                                      
    }                                                                 
        /*
         * Open the message space, using the same global identifier
         */
    msgSpaceLi = msgSpaceOpen(SAMPLE_SPACE);
    if (msgSpaceLi < 0) {                                             
        printf("Cannot open the message space error %d\n",            
                msgSpaceLi);                                          
        exit(1);                                                      
    }                                                                 

        /*
         * Allocate the large message
         */
    res = msgAllocate(msgSpaceLi, K_ANY_MSGPOOL, LARGE_MSG_SZ, 
                      K_NOTIMEOUT, &largeMsg);
    if (res != K_OK) {                                                
      printf("Cannot allocate a large message, error %d\n", res);     
      exit(1);                                                        
    }                                                                 

    strcpy(largeMsg, "Sending a very large large large message\n");

        /*
         * Post the large message to Q3 with priority 0
         */
    res = msgPut(msgSpaceLi, Q3, largeMsg, 0);
    if (res != K_OK) {                                                
      printf("Cannot post the large message to Q3, error %d\n", res); 
      exit(1);                                                        
    }                                                                 

        /*
         * Get the small message from Q2
         */
    res = msgGet(msgSpaceLi, Q2, K_NOTIMEOUT, &smallMsg, NULL);
    if (res != K_OK) {                                                
      printf("Cannot get the small message from Q2, error %d\n", res);
      exit(1);                                                        
    }                                                                 
        
    printf("Spawned actor received small message containing:\n%s\n",
            smallMsg);
    
    for (l = 0; l < strlen(smallMsg); l++) {
        if ((smallMsg[l]>= 'a') && (smallMsg[l] <= 'z')) {
            smallMsg[l] = smallMsg[l] - 'a' + 'A';
        }
    }
    
        /*
         * Post the small message back to Q1, with priority 4
         */
    res = msgPut(msgSpaceLi, Q1, smallMsg, 4);
    if (res != K_OK) {                                                
      printf("Cannot post the small message reply to Q1, error %d\n", 
             res);                                                    
      exit(1);                                                        
    }        
  }
  return 0;
}