/* ******************************************************************************** * * BROADCAST IN AMDC USING SHARED RECORDS * -------------------------------------- * * 1) Each node sends a broadcast message, containing its own id, to a 2D * location for each node where the first dimension is the of the node to * communicate to, and the second dimension is the nodes own id. * * 2) Each node also sends a gather message, containing its own id, to a 2D * location for each node where the first dimension is the nodes own id, and * the second dimension is the id of the node which will be sending the * broadcast message. * * NOTE: If the kind of symbol for the 2D locations is AMDC_SYMB_X0, * the location of the records will be on the gather's node. If the * kind of symbol is AMDC_SYMB_HASH then the location of the records * will be arbitrary. * * 3) When a broadcast and gather message both arrive at the same location, the * sender's id from the broadcast message and the gather's id from the gather * message are put into a print message and sent to node message are put * into a print message and sent to node 0. * * 4) When a print message is received, it will print the ids contained in the * message, then put the message into the table at that location. * * 5) When the number of print messages at that location is equal to * (num_of_nodes * num_of_nodes), then all expected prints have been received * and the program will terminate. * ******************************************************************************** */ #include #include "amdc96.h" /* -------------------------------------------------------------------------------- Definitions -------------------------------------------------------------------------------- */ #define BROADCAST 1L #define PRINT 2L #define GATHER 3L typedef struct { int sender_id; } Broadcast; typedef struct { int receiver_id; } Gather; typedef struct { int sender_id; int receiver_id; } Print; /* -------------------------------------------------------------------------------- Function print_op -------------------------------------------------------------------------------- */ void print_op(Message msg, Location loc) { Print *print = msg; printf("From %ld to %ld\n", print->sender_id, print->receiver_id); amdc_putLoc(loc, msg); } /* -------------------------------------------------------------------------------- Function gather_broadcast -------------------------------------------------------------------------------- */ void gather_broadcast(Gather *gather, Broadcast *broadcast) { LocName loc_name_0 = amdc_0DLocName(AMDC_AbsoluteSymbol(0, AMDC_SYMB_X0)); Print *print; print = amdc_newMsg((Script)print_op, PRINT, sizeof(Print)); print->receiver_id = gather->receiver_id; print->sender_id = broadcast->sender_id; amdc_freeMsg(gather); amdc_freeMsg(broadcast); amdc_sendTo(print, loc_name_0); } /* -------------------------------------------------------------------------------- Function gather_op -------------------------------------------------------------------------------- */ void gather_op(Message msg, Location loc) { if (amdc_presentLoc(loc, BROADCAST)) gather_broadcast((Gather *) msg, (Broadcast *) amdc_getLoc(loc, BROADCAST)); else amdc_putLoc(loc, msg); } /* -------------------------------------------------------------------------------- Function broadcast_op -------------------------------------------------------------------------------- */ void broadcast_op(Message msg, Location loc) { if (amdc_presentLoc(loc, GATHER)) gather_broadcast((Gather *) amdc_getLoc(loc, GATHER), (Broadcast *) msg); else amdc_putLoc(loc, msg); } /* -------------------------------------------------------------------------------- Function Main -------------------------------------------------------------------------------- */ Main(int argc, char *argv[]) { Location my_loc; LocName broadcast_loc_name, gather_loc_name; const int num_of_nodes = amdc_getNumNodes(); int num_of_nodes_squared; int count; Broadcast *broadcast; Gather *gather; int next_node; int my_id; my_id = amdc_getMyId(); broadcast_loc_name = amdc_0DLocName(AMDC_AbsoluteSymbol(0, AMDC_SYMB_X0)); broadcast_loc_name.X[1] = my_id; gather_loc_name = amdc_0DLocName(AMDC_AbsoluteSymbol(0, AMDC_SYMB_X0)); gather_loc_name.X[0] = my_id; next_node = my_id; /* Send broadcast to every node and gather from every node */ for(count = 0; count < num_of_nodes; count++) { next_node = (next_node + 1) % num_of_nodes; /* Send broadcast */ broadcast = amdc_newMsg((Script)broadcast_op, BROADCAST, sizeof(Broadcast)); broadcast->sender_id = my_id; broadcast_loc_name.X[0] = next_node; amdc_sendTo(broadcast, broadcast_loc_name); /* Send gather */ gather = amdc_newMsg((Script)gather_op, GATHER, sizeof(Gather)); gather->receiver_id = my_id; gather_loc_name.X[1] = next_node; amdc_sendTo(gather, gather_loc_name); } if(my_id == 0) { my_loc = amdc_getMyLoc(); num_of_nodes_squared = num_of_nodes * num_of_nodes; /* Execute pollBlock until all print messages received */ printf("Waiting for %ld messages\n", num_of_nodes_squared); while(amdc_numLoc(my_loc, PRINT) < num_of_nodes_squared) amdc_pollBlock(); printf("All messages received!\n"); /* Free all print messages at my_loc */ while(amdc_presentLoc(my_loc, PRINT)) amdc_freeMsg(amdc_getLoc(my_loc, PRINT)); printf("Messages removed\n"); } else { /* Execute pollBlock forever */ while(1) amdc_pollBlock(); } }