= Message Passing = First attempt: {{{ $input int NPROCS; $assume NPROCS >= 1; $scope top; $heap mp_heap; $proc procs[NPROCS]; /* There will be one message queue for each pair of prods (i,j). * Each queue is a doubly-linked list of Message objects. */ typedef struct Message { struct Message * next; struct Message * prev; int tag; int size; void * data; } Message; typedef struct Comm_struct { Message * buf_front[NPROCS][NPROCS]; Message * buf_back[NPROCS][NPROCS]; } Comm_struct; typedef Comm_struct *Comm; /* As in MPI, when a receive returns, this structure * tells you the source and tag of received message, * which you need if you used wildcards, Also size. */ typedef struct Status { int source; int tag; int size; } Status; Comm _Comm_world; /* The user will use COMM_WORLD */ Comm * COMM_WORLD = &_Comm_world; void init() { for (int i=0; ibuf_front[i][j] = NULL; COMM_WORLD->buf_back[i][j] = NULL; } } void send(int source, void *buf, int size, int tag, int dest, Comm comm) { // create a message Message message; message.tag = tag; message.size = size; message.data = $malloc(&mp_heap, size); memcpy(message.data, buf, size); // enqueue on comm->buf_front[i][j] … // update message.next, message.prev, buf_back[i][j] } // can I use a function as a guard? not now // can always use busy-wait loop? boolean probe(…) { } void recv(int dest, void *buf, int size, int tag, int source, Comm comm, Status *status) { Message *message; int message_source; int message_dest; // search the queue looking for the message // also set message_source, message_dest; // and remove message from the queue if (message.size > size) error…; memcpy(buf, message.data, message.size); status->size = message.size; status->source = message_source; status->dest = message_dest; $free(message->data); } }}}