/*************************************/ /* Test amdc shared records */ /* Kristi Cablk */ /*************************************/ /* This simple program will just have the master node send some data to a global location name, and then each slave node will fetch a copy of the data from that location and print it. This will demonstrate the fetchCopy procedure. Next, the master node will send some data to another location name, and node 1 will fetch the data and print it. This will demonstrate the fetch procedure. */ #include "amdc96.h" #include #define FETCHED 1 #define DATA 2 #define FETCH 3 #define FETCHCOPY 4 typedef struct { int data1; int data2; } GlobalData; Location my_loc; LocName global_loc; LocName global_loc2; Message fetch(LocName L); Message fetchCopy(LocName L); void doFetch(Message m, Location loc); void doFetchCopy(Message m, Location loc); void doStore(Message m, Location loc); void storeAt(Message m, LocName L); /* * This procedure is called by a process to * fetch a record. */ Message fetch(LocName L) { Message p; Destiny *d = (Destiny *)amdc_rawMsg(sizeof(Destiny)); *d = amdc_makeDest(amdc_getNameOfLoc(my_loc),FETCHED, (Script)amdc_rawScript); amdc_sendToAsDo(d,L,FETCH,(Script)doFetch); while ((p=amdc_getLoc(my_loc, FETCHED))==NULL) amdc_pollBlock(); return p; } /* * This procedure is called by a process to * fetch a copy of a record. */ Message fetchCopy(LocName L) { Message p; Destiny *d = (Destiny *)amdc_rawMsg(sizeof(Destiny)); *d = amdc_makeDest(amdc_getNameOfLoc(my_loc),FETCHED, (Script)amdc_rawScript); amdc_sendToAsDo(d, L, FETCHCOPY, (Script)doFetchCopy); while ((p=amdc_getLoc(my_loc,FETCHED))==NULL) amdc_pollBlock(); return p; } /* * This is a script to fetch a record. */ void doFetch(Message m, Location loc) { Message p; Destiny d; LocName loc_name = amdc_getNameOfLoc(loc); memcpy(&d,m,sizeof(Destiny)); if ((p=amdc_getLoc(loc,DATA))!=NULL) { amdc_sendToDest(p,d); amdc_freeMsg(m); } else amdc_putLoc(loc,m); } /* * This is a script to fetch a copy of a record. */ void doFetchCopy(Message m, Location loc) { Message p; Destiny d; memcpy(&d,m,sizeof(Destiny)); if ((p=amdc_getLoc(loc,DATA))!=NULL) { amdc_sendToDest(amdc_copyMsg(p), d); amdc_putLoc(loc,p); amdc_freeMsg(m); } else amdc_putLoc(loc,m); } /* * This is a script to store a record - it will execute * the scripts of waiting "fetch" messages immediately. */ void doStore(Message m, Location loc) { Message p; amdc_putLoc(loc,m); while ((p=amdc_getLoc(loc,FETCHCOPY))!=NULL) (amdc_getScript(p))(p,loc); if ((p=amdc_getLoc(loc,FETCH)) != NULL) { (amdc_getScript(p))(p,loc); } } /* * This procedure is used by a process to store a * record at a location. */ void storeAt(Message m, LocName L) { amdc_sendToAsDo(m, L, DATA, (Script) doStore); } Main() { GlobalData *msg; GlobalData *msg2; my_loc=amdc_getMyLoc(); global_loc = amdc_0DLocName(AMDC_AbsoluteSymbol(0,AMDC_SYMB_HASH)); global_loc2 = amdc_0DLocName(AMDC_AbsoluteSymbol(1,AMDC_SYMB_HASH)); printf("I am node %d\n", amdc_getMyId()); if (amdc_getMyId() == 0) { printf("Number of Nodes is: %d\n", amdc_getNumNodes()); /* send a message with some data in it to the global location */ /* this is just some hard-coded sample data */ msg = amdc_newMsg((Script)amdc_rawScript, DATA, sizeof(GlobalData)); msg->data1 = 1; msg->data2 = 2; /* store the message in the global location */ storeAt(msg, global_loc); /* now send some more data to another location */ msg2 = amdc_newMsg((Script)amdc_rawScript, DATA, sizeof(GlobalData)); msg2->data1 = 3; msg2->data2 = 4; /* store the message in the second global location */ storeAt(msg2, global_loc2); } else { msg = (GlobalData*) fetchCopy(global_loc); printf("Process %d received data: %d, %d\n", amdc_getMyId(), msg->data1, msg->data2); if (amdc_getMyId() == 1) { msg2 = (GlobalData*) fetch(global_loc2); printf("Process %d received data: %d, %d\n", amdc_getMyId(), msg2->data1, msg2->data2); } } }