#include "maisie.h" #define NUMCHANNELS 10 #define NUMCELLS 5 #define CALLS 500 #define HOLDT 5 #define MAXTIME 30 #define HANDOFF 0 #define INCOMING 1 #define MAXNUMCELLS 20 /********** ** ** DRIVER: Parses command line arguments and generates ** random sequence of calls. ** **********/ entity driver{argc,argv} int argc; char **argv; { int numCells = NUMCELLS; int numCalls = CALLS; int pause = HOLDT; int i,holdT,fromCell,completeT,moveT,toCell; int maxTime = MAXTIME; char time[100]; ename gCell[MAXNUMCELLS],simCounter; /* Get command line arguments */ if (argc > 1 && argc != 5) { printf("usage: callI [numCells] [numCalls] [pause] [maxTime]\n"); exit(1); } else if (argc >1) { numCells = atoi(argv[1]); numCalls = atoi(argv[2]); pause = atoi(argv[3]); maxTime = atoi(argv[4]); } /* Seed Random Number Generator */ srand(34028); /* Create Cells */ for(i=0;i Incoming (%d): Received incoming call\n", myCellNo,cti(sclock())); #endif /* Statistical bookkepping */ if (msg.Incoming.type == INCOMING) { incomingCount++; } else handoffCount++; if (activeChannels < NUMCHANNELS) { /* Search for available channel */ for(i=0;i Incoming: Processing using CH%d (%d)\n", myCellNo,availChannel,activeChannels); #endif } /* Drop incoming call */ else { if (msg.Incoming.type == HANDOFF) { #ifdef DEBUG printf("C%d\t--> Incoming (%d): Dropping Handoff from C%d\n", myCellNo,cti(sclock()),msg.Incoming.destCell); #endif handoffDropped++; } else { #ifdef DEBUG printf("C%d\t--> Incoming (%d): Dropping Incoming call\n", myCellNo,cti(sclock())); #endif incomingDropped++; invoke simCounter with MsgHandled{}; } } } /* Update active Calls */ or mtype(timeout) { if (activeChannels) { for(i=0;i 0 && (callMove[i] == 0 || callEnd[i] <= callMove[i]) && (arrivalTime[i]+callEnd[i] <= cti(sclock()))) { callEnd[i] = 0; callMove[i] = 0; callCellDest[i] = -1; arrivalTime[i] = -1; activeChannels--; callsCompleted++; #ifdef DEBUG printf("C%d\t-->Update (%d): CH[%d] call completed (%d)\n", myCellNo,cti(sclock()),i,activeChannels); #endif invoke simCounter with MsgHandled{}; } /* Hand off call to next Cell */ else if (callMove[i] > 0 && callMove[i] < callEnd[i] && (arrivalTime[i]+callMove[i] <= cti(sclock()))) { #ifdef DEBUG printf("C%d\t--> Update (%d): Handing off call to C%d (%d)\n", myCellNo,cti(sclock()),callCellDest[i],activeChannels-1); #endif invoke gCell[callCellDest[i]] with Incoming{callEnd[i]-callMove[i],0,myCellNo,HANDOFF}; callEnd[i] = 0; callMove[i] = 0; callCellDest[i] = -1; activeChannels--; } } } /* Determine when next call will arrive */ if (nextCallTime < cti(sclock())) { nextCallTime = (rand()%pause) + cti(sclock()) + 1; fromCell = rand() % numCells; completeT = (rand() % maxTime) + 1; moveT = (rand() % maxTime) + 1; toCell = rand() % numCells; if (fromCell == toCell) toCell = (toCell+1) % numCells; invoke gCell[fromCell] with Incoming{completeT,moveT,toCell,INCOMING}; #ifdef DEBUG printf("at clock %d: From %d to %d -- moving at %d, completing at %d\n", cti(sclock()),fromCell,toCell,moveT,completeT); #endif } } /* End simulation */ or mtype(displayResults) { printf("C %d:\t%i %.0f", myCellNo,handoffDropped,handoffCount); printf("\t\t%i %0.f ", incomingDropped,incomingCount); printf("\t\t%i %0.f\t(%.5f)\n", callsCompleted,incomingCount, (handoffDropped+incomingDropped)/((float)incomingCount)); invoke simCounter with displayAck{}; } } } } /********** ** ** COUNTER: Coordinates the termination of the simulation under ** the "mpc" simulation. Waits till the given number ** of calls have been handled, and then tells all ** cells to stop. Upon ack that all cells have finished ** their termination routines (printing out stats), ** terminate() signal invoked. **********/ entity Counter{maxMsgs,numCells,gCell} int maxMsgs;int numCells;ename gCell[MAXNUMCELLS]; { message MsgHandled{} MsgHandled; message displayAck{} displayAck; int currMsgs = 0,currAck=0; int i; for (;;) { wait until { mtype(MsgHandled) { currMsgs++; if (currMsgs == maxMsgs) { for(i=0;i