Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MACRelayUnitNP Class Reference

#include <MACRelayUnitNP.h>

Inheritance diagram for MACRelayUnitNP:

MACRelayUnitBase List of all members.

Detailed Description

An implementation of the MAC Relay Unit that assumes a shared memory and N CPUs in the switch. The CPUs process frames from a single shared queue.


Public Member Functions

 MACRelayUnitNP ()
virtual ~MACRelayUnitNP ()

Protected Member Functions

void handleIncomingFrame (EtherFrame *msg)
void processFrame (cMessage *msg)
Redefined cSimpleModule member functions.
virtual void initialize ()
virtual void handleMessage (cMessage *msg)
virtual void finish ()

Protected Attributes

cQueue queue
int numCPUs
simtime_t processingTime
int bufferSize
long highWatermark
int pauseUnits
simtime_t pauseInterval
int bufferUsed
cMessage ** endProcEvents
simtime_t pauseLastSent
long numProcessedFrames
long numDroppedFrames
cOutVector bufferLevel


Constructor & Destructor Documentation

MACRelayUnitNP::MACRelayUnitNP  ) 
 

00044 {
00045     endProcEvents = NULL;
00046     numCPUs = 0;
00047 }

MACRelayUnitNP::~MACRelayUnitNP  )  [virtual]
 

00050 {
00051     for (int i=0; i<numCPUs; i++)
00052         cancelAndDelete(endProcEvents[i]);
00053     delete [] endProcEvents;
00054 }


Member Function Documentation

void MACRelayUnitNP::finish  )  [protected, virtual]
 

Writes statistics.

00198 {
00199     if (par("writeScalars").boolValue())
00200     {
00201         recordScalar("processed frames", numProcessedFrames);
00202         recordScalar("dropped frames", numDroppedFrames);
00203     }
00204 }

void MACRelayUnitNP::handleIncomingFrame EtherFrame msg  )  [protected]
 

Handle incoming Ethernet frame: if buffer full discard it, otherwise, insert it into buffer and start processing if a processor is free.

00119 {
00120     // If buffer not full, insert payload frame into buffer and process the frame in parallel.
00121 
00122     long length = frame->byteLength();
00123     if (length + bufferUsed < bufferSize)
00124     {
00125         bufferUsed += length;
00126 
00127         // send PAUSE if above watermark
00128         if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval)
00129         {
00130             // send PAUSE on all ports
00131             for (int i=0; i<numPorts; i++)
00132                 sendPauseFrame(i, pauseUnits);
00133             pauseLastSent = simTime();
00134         }
00135 
00136         // assign frame to a free CPU (if there is one)
00137         int i;
00138         for (i=0; i<numCPUs; i++)
00139             if (!endProcEvents[i]->isScheduled())
00140                 break;
00141         if (i==numCPUs)
00142         {
00143             EV << "All CPUs busy, enqueueing incoming frame " << frame << " for later processing\n";
00144             queue.insert(frame);
00145         }
00146         else
00147         {
00148             EV << "Idle CPU-" << i << " starting processing of incoming frame " << frame << endl;
00149             cMessage *msg = endProcEvents[i];
00150             msg->encapsulate(frame);
00151             scheduleAt(simTime() + processingTime, msg);
00152         }
00153     }
00154     // Drop the frame and record the number of dropped frames
00155     else
00156     {
00157         EV << "Buffer full, dropping frame " << frame << endl;
00158         delete frame;
00159         ++numDroppedFrames;
00160     }
00161 
00162     // Record statistics of buffer usage levels
00163     bufferLevel.record(bufferUsed);
00164 }

void MACRelayUnitNP::handleMessage cMessage *  msg  )  [protected, virtual]
 

Calls handleIncomingFrame() for frames arrived from outside, and processFrame() for self messages.

00105 {
00106     if (!msg->isSelfMessage())
00107     {
00108         // Frame received from MAC unit
00109         handleIncomingFrame(check_and_cast<EtherFrame *>(msg));
00110     }
00111     else
00112     {
00113         // Self message signal used to indicate a frame has finished processing
00114         processFrame(msg);
00115     }
00116 }

void MACRelayUnitNP::initialize  )  [protected, virtual]
 

Read parameters parameters.

Reimplemented from MACRelayUnitBase.

00057 {
00058     MACRelayUnitBase::initialize();
00059 
00060     bufferLevel.setName("buffer level");
00061     queue.setName("queue");
00062 
00063     numProcessedFrames = numDroppedFrames = 0;
00064     WATCH(numProcessedFrames);
00065     WATCH(numDroppedFrames);
00066 
00067     numCPUs = par("numCPUs");
00068 
00069     processingTime    = par("processingTime");
00070     bufferSize = par("bufferSize");
00071     highWatermark = par("highWatermark");
00072     pauseUnits = par("pauseUnits");
00073 
00074     // 1 pause unit is 512 bit times; we assume 100Mb MACs here.
00075     // We send a pause again when previous one is about to expire.
00076     pauseInterval = pauseUnits*512.0/100000.0;
00077 
00078     pauseLastSent = 0;
00079     WATCH(pauseLastSent);
00080 
00081     bufferUsed = 0;
00082     WATCH(bufferUsed);
00083 
00084     endProcEvents = new cMessage *[numCPUs];
00085     for (int i=0; i<numCPUs; i++)
00086     {
00087         char msgname[20];
00088         sprintf(msgname, "endProcessing-cpu%d", i);
00089         endProcEvents[i] = new cMessage(msgname,i);
00090     }
00091 
00092     EV << "Parameters of (" << className() << ") " << fullPath() << "\n";
00093     EV << "number of processors: " << numCPUs << "\n";
00094     EV << "processing time: " << processingTime << "\n";
00095     EV << "ports: " << numPorts << "\n";
00096     EV << "buffer size: " << bufferSize << "\n";
00097     EV << "address table size: " << addressTableSize << "\n";
00098     EV << "aging time: " << agingTime << "\n";
00099     EV << "high watermark: " << highWatermark << "\n";
00100     EV << "pause time: " << pauseUnits << "\n";
00101     EV << "\n";
00102 }

void MACRelayUnitNP::processFrame cMessage *  msg  )  [protected]
 

Triggered when a frame has completed processing, it routes the frame to the appropriate port, and starts processing the next frame.

00167 {
00168     int cpu = msg->kind();
00169     EtherFrame *frame = (EtherFrame *) msg->decapsulate();
00170     long length = frame->byteLength();
00171     int inputport = frame->arrivalGate()->index();
00172 
00173     EV << "CPU-" << cpu << " completed processing of frame " << frame << endl;
00174 
00175     handleAndDispatchFrame(frame, inputport);
00176     printAddressTable();
00177 
00178     bufferUsed -= length;
00179     bufferLevel.record(bufferUsed);
00180 
00181     numProcessedFrames++;
00182 
00183     // Process next frame in queue if they are pending
00184     if (!queue.empty())
00185     {
00186         EtherFrame *newframe = (EtherFrame *) queue.pop();
00187         msg->encapsulate(newframe);
00188         EV << "CPU-" << cpu << " starting processing of frame " << newframe << endl;
00189         scheduleAt(simTime()+processingTime, msg);
00190     }
00191     else
00192     {
00193         EV << "CPU-" << cpu << " idle\n";
00194     }
00195 }


Member Data Documentation

cOutVector MACRelayUnitNP::bufferLevel [protected]
 

int MACRelayUnitNP::bufferSize [protected]
 

int MACRelayUnitNP::bufferUsed [protected]
 

cMessage** MACRelayUnitNP::endProcEvents [protected]
 

long MACRelayUnitNP::highWatermark [protected]
 

int MACRelayUnitNP::numCPUs [protected]
 

long MACRelayUnitNP::numDroppedFrames [protected]
 

long MACRelayUnitNP::numProcessedFrames [protected]
 

simtime_t MACRelayUnitNP::pauseInterval [protected]
 

simtime_t MACRelayUnitNP::pauseLastSent [protected]
 

int MACRelayUnitNP::pauseUnits [protected]
 

simtime_t MACRelayUnitNP::processingTime [protected]
 

cQueue MACRelayUnitNP::queue [protected]
 


The documentation for this class was generated from the following files:
Generated on Thu Oct 19 18:22:26 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0