Listing 1

/*
 *  monitor.c :  A task monitor for Desqview API
 *  author:      Victor R. Volkman
 */

#include <stdio.h>
#include <malloc.h>
#include "dvapi.h"        /* These two files are found in */
#include "dvapi2.h"       /* the Desqview API C package.  */
#include "monitor.h"

#ifndef MAKEFD
#include "monitor.fd"
#endif

/* The monitor contains two mutually exclusive functions:
   recvl and sendv. The recvl function is used by
   subprocesses to wait for any signal. A signal can
   indicate either a synchronization wait or a communication
   wait. The sendv function is used by suprocesses to send
   a synchronization signal or obtain exclusive write access
   to the global communication array.
   
   Semafore usage is decoded as follows:
   
   Semafore value    Usage
   --------------    -----
      MASTER        Signal indicating that the master node
                  is executing the critical section.

    1..NUMPRC        Communication signal indicates that
                  valid data is waiting for a given node.

   NUMPRC+node       Synchronization signal returned by the
                  master node to each individual node.

   2*NUMPRC+1        Termination signal returned when the
                  master node finds that no further
                  intervals will be used.
*/
open_monitor(sem_name, new_mon_pp)
char *sem_name;
MONITOR **new_mon_pp;
{
   DESQ_HAN semaphore_han;

   semaphore_han = mal_new();
   mal_name(semaphore_han, sem_name, strlen(sem_name));
   *new_mon_pp = (MONITOR *) calloc(sizeof(MONITOR),1);
   (*new_mon_pp)->sem_han = semaphore_han;
}

close_monitor(old_mon_pp)
MONITOR **old_mon_pp;
{
   mal_close((*old_mon_pp)->sem_han);
   free(*old_mon_pp};
   *old_mon_pp = NULL;
}
sendv(mon_p,val,to_node)
MONITOR *mon_p;
double val;
int to_node;
{
   DESQ_HAN semaphore_han = mon_p->sem_han;

   mal_lock(semaphore_han);       /* begin mutually exclusive
                               access */

   mon_p->sent[to_node]++;
   mon_p->value[to_node] = val;
   mal_unlock(semaphore_han};     /* end mutually exclusive
                               access */
}
recvl(mon_p,val_p,from_node)
MONITOR *mon_p;
double *val_p;
int from_node;
{
   DESQ_HAN semaphore_han = mon_p->sem_han;
   int *from_ptr;
   
   from_ptr = &(mon_p->sent[from_node]);
   
   mal_lock(semaphore_han);       /* begin mutually exclusive
                               access */
   while (! *from_ptr) {  /*  message hasn't arrived yet */
     mal_unlock(semaphore_han);
     api_pause();
     mal_lock(semaphore_han);
     }
   *from_ptr = *from_ptr - 1;
   *val_p = mon_p->value[from_node];
   mal_unlock(semaphore_han);     /* end mutually exclusive
                               access */
}