| Version 2 (modified by , 13 years ago) ( diff ) |
|---|
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 *<top> next;
struct Message *<top> prev;
int tag;
int size;
void *<top> data;
} Message;
typedef struct Comm_struct {
Message *<top> buf_front[NPROCS][NPROCS];
Message *<top> 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 *<top> COMM_WORLD = &_Comm_world;
void init() {
for (int i=0; i<NPROCS; i++)
procs[i] = $spawn proc(i);
for (int i=0; i<NPROCS; i++)
for (int j=0; j<NPROCS; j++) {
COMM_WORLD->buf_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<top>(&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);
}
Note:
See TracWiki
for help on using the wiki.
