UCLA Parallel Computing Laboratory

rainbow line

Code Modifications for Maisie to Parsec

Several changes to Maisie code are necessary before it can be used with the Parsec compiler.

Header Files

The header file, indicated at the begining of the code as "maisie.h" or "mayc.h", no longer necessary. Please remove this line from your code, otherwise Parsec reports an error of "No such file or directory."

Old Format:
#include "maisie.h"

Compilation of the Parsec source file will generate an ".pi" file, containing Parsec information. An ".mo" file will no longer be generated. Also note that some programs will now require the inclusion of the "stdio.h" header file.

Entity Declaration

Entity and function prototypes must precede the entity's declaration by the new statement. This can be in the form of the either the entire entity or just a one line declaration if the entity appears later. Since PARSEC regards entity definitions as function definitions and the default type of functions is the integer type, the compiler reports an error message of type mismatch when no declaration is found before the entity is used on new statements.

Send and Receive Commands

Formerly known as "invoke" and "wait," these commands have been replaced by the more intuitive "send" and receive." Usage examples for each follow.
Old Format:
entity mailbox {postoffice1, postoffice2, 
                   pkg_count, ltr_count}
ename postoffice1, postoffice2;
int pkg_count, ltr_count;
{
   message letter {int class; int weight;} ltr;
   message package {int class; int weight;};
   invoke postoffice1 with letter {1,4}; 
   while (pkg_count > ltr_count)
   {   wait until {
         mtype (package) 
         {++pkg_count;
          ... }
         or ltr=mtype (letter)
         {++ltr_count;
          ... } 
         }
    }
New Format:
message letter {int class; int weight;};
message package {int class; int weight;};

entity mailbox (ename postoffice1, ename postoffice2)
{
   int pkg_count;
   int ltr_count;
   messsage letter ltr;
   send letter {1,4} to postoffice1; 
   while (pkg_count > ltr_count) {
      receive (package pkg) {
         ++pkg_count;
         ...
      }
      or receive (letter tmp_ltr) {
         ++ltr_count;
         ltr = tmp_ltr;
         ... 
      }
   }
}
Note that in the example above, the value of "pkg" and "tmp_ltr" are only valid in the clause where they appear as read-only constants. In contrast, the "ltr" variable is local throughout the entity. Any attempt to change the value of "pkg" or "tmp_ltr" will result in a warning.

Endsim Message

Endsim has been replaced by the "finalize" statement. Whereas the endsim message must be handled by every wait statement, only a single finalize block should appear as the last statement in the entity.
Before:
   for (i=0;i<N;i++)
     invoke q[i] with idmsg{rtr[i]};  
   wait until mtype(endsim) {
     print_info();
   }
Now:
entity example() {
   ...
   for (i = 0; i < N; i++)
     send idmsg{rtr[i]} to q[i];  

   ...

   finalize {
 	print_info();
   }
}

Timeout Message

Timeout is now a command of the format "or timeout after (expr) {commands;}". The "expr" portion must now be enclosed in parenthesis. The portion in curly braces is optional.
Before:
wait expon(mean) until
{	mtype(timeout);
	or mtype(end) break;
}
Now:
	receive (end signal) break;
	or timeout in (expon(mean));

The timeout must appear after all receive statements. If there are no receive statements, the 'timeout' should be replaced by the hold() command.

ANCI C Format

The Parsec compiler supports both ANSI C format and standard C. It is recommended, however, that programs follow ANSI C format.

Before:
entity job{ cpu, disk, dmean }
ename disk, cpu;
int dmean;
{ . . . . 
Recommended:
entity job( ename cpu, ename disk, int dmean )
{ . . . . 
Also note that in entity definitions, parentheses are used instead of curly braces for parameter declaration. Parentheses must also be used with the "new" statement.

Before:
q[j][i]=new queue{self,MEAN,i*NSRVR+j,NSWTCH} at i;
New Syntax:
q[j][i]=new queue(self,MEAN,i*NSRVR+j,NSWTCH) at i;

Message Declarations

The names of message types in a Parsec program are assumed to be global. In other words, a given identifier, say "req" can be used to define only one message type in a program. In the previous version, it was possible for a programmer to use "req" to define multiple message types (in the declaration of different entity types). Message definitions are global and the message variables are local.

Old Syntax:
entity job{ ename cpu, ename disk, 
            int dmean }
{
   message ack { }  ack1;
   message req { ename location;};
   int i, t, end, start, t_wait, tid; 
   invoke cpu with req {self}; 
   . . . . 


New Syntax:
message ack { };
message req{ ename location;};

entity job( ename cpu, ename disk, 
            int dmean )
{
   message ack ack1;
   int i, t, end, start, t_wait, tid; 
   send req {self} to cpu; 
   . . . . 

All message type definitions must include the message type name, followed by the parameters in curly braces, identical to stucture definitions. However, when defining a message variable, the parameters and curly braces should not appear.

Legal Syntax:
message ack{};
message finish {int x;};

entity job( ename cpu, ename disk, 
            int dmean )
{
   message finish job_fin;
   int i, t, end, start, t_wait, tid; 
   send  req {self} to cpu; 
   . . . . 
Illegal Syntax:
message ack ack1;
message finish;

entity job( ename cpu, ename disk, 
            int dmean )
{
   message finish {int x;} job_fin;
   int i, t, end, start, t_wait, tid; 
   send  req {self} to cpu; 
   . . . . 

Simulation Commands

The names of the sclock, zzcla, and zzmaxla functions have been changed for clarity.

Before:
sclock(void)
zzcla(sim_time)
zzmaxla(max_time)
maxclock(char *)
Now:
simclock(void)
setlookahead(clocktype delta, clocktype ceiling)
setmaxclock(clocktype)

Ranker

Due to inefficiencies introduced into the queue management and difficulties involved in implementation, the ranker feature has been discontinued.


New Features

Stacksize

Entities now contain an optional stack size parameter that takes a unary expression, in bytes.
Example:
entity my_entity ( int a, char *c, float d ) [stacksize (unary_expression)]
{  . . . . }; 

Friend Functions

Friend functions are currently supported by the Parsec compiler. Add the -ff flag to the command line when compiling. There are also a number of syntactical changes.
Before:
entity Entity { }
{     int ffunc ( );
      ...
}

int Entity ::ffunc ( )
{  ....  }
Now:
entity Entity (void);
int Entity :: ffunc (void);

entity Entity (void)
{  ....  }

int Entity :: ffunc (void)
{  ....  }




Information compiled by Monnica Terwilliger (monnica@cs.ucla.edu) and updated by Rich.
Return to Parsec Home Page

Updated: December 10, 1997.