/*************************************/ /* Demonstrate amdc semaphores */ /* Kristi Cablk */ /*************************************/ /* */ #include "amdc96.h" #include #define FETCHED 1 #define DATA 2 #define FETCH 3 /* initial value for the semaphore */ #define SEMCOUNT 3 Location my_loc; LocName Sema; Message fetch(LocName L); void doFetch(Message m, Location loc); void doStore(Message m, Location loc); void storeAt(Message m, LocName L); void initSemaphore(LocName sema, int c); void up(LocName sema); void down(LocName sema); /* * 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 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 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); 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); } /* * This is a procedure to initialize the semaphore. It should be called * by only one process. */ void initSemaphore(LocName sema, int c) { for (;c>0;c--) storeAt(amdc_rawMsg(0), sema); } /* * This is the procedure used to decrement the semaphore. */ void down(LocName sema) { amdc_freeMsg(fetch(sema)); } /* * This is the procedure used to increment the semaphore. */ void up(LocName sema) { storeAt(amdc_rawMsg(0), sema); } Main() { my_loc=amdc_getMyLoc(); /* Create the location name of the semaphore */ Sema = amdc_0DLocName(AMDC_AbsoluteSymbol(1,AMDC_SYMB_HASH)); printf("I am node %d\n", amdc_getMyId()); if (amdc_getMyId() == 0) { /* This is the master process */ /* Initialize the semaphore to SEMCOUNT */ /* Call this only once! */ initSemaphore(Sema, SEMCOUNT); /* Do some stuff... */ down(Sema); /* perform critical section */ up(Sema); /* Do some more stuff ... */ } else { /* All other processes */ /* Do some stuff... */ down(Sema); /* perform critical section */ up(Sema); /* Do some more stuff ... */ } }