MACRelayUnitPP Class Reference

#include <MACRelayUnitPP.h>

Inheritance diagram for MACRelayUnitPP:

MACRelayUnitBase

List of all members.


Detailed Description

An implementation of the MAC Relay Unit that assumes one processor assigned to each incoming port, with separate queues.

Public Member Functions

 MACRelayUnitPP ()
virtual ~MACRelayUnitPP ()

Protected Member Functions

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


virtual void initialize ()
virtual void handleMessage (cMessage *msg)
virtual void finish ()

Protected Attributes

simtime_t processingTime
int bufferSize
long highWatermark
int pauseUnits
simtime_t pauseInterval
int bufferUsed
PortBufferbuffer
simtime_t pauseLastSent
long numProcessedFrames
long numDroppedFrames
cOutVector bufferLevel

Classes

struct  PortBuffer

Constructor & Destructor Documentation

MACRelayUnitPP::MACRelayUnitPP (  ) 

00036 {
00037     buffer = NULL;
00038 }

MACRelayUnitPP::~MACRelayUnitPP (  )  [virtual]

00041 {
00042     delete [] buffer;
00043 }


Member Function Documentation

void MACRelayUnitPP::initialize (  )  [protected, virtual]

Read parameters parameters.

Reimplemented from MACRelayUnitBase.

00046 {
00047     MACRelayUnitBase::initialize();
00048 
00049     bufferLevel.setName("buffer level");
00050 
00051     numProcessedFrames = numDroppedFrames = 0;
00052     WATCH(numProcessedFrames);
00053     WATCH(numDroppedFrames);
00054 
00055     processingTime = par("processingTime");
00056     bufferSize = par("bufferSize");
00057     highWatermark = par("highWatermark");
00058     pauseUnits = par("pauseUnits");
00059 
00060     // 1 pause unit is 512 bit times; we assume 100Mb MACs here.
00061     // We send a pause again when previous one is about to expire.
00062     pauseInterval = pauseUnits*512.0/100000.0;
00063 
00064     pauseLastSent = 0;
00065     WATCH(pauseLastSent);
00066 
00067     bufferUsed = 0;
00068     WATCH(bufferUsed);
00069 
00070     buffer = new PortBuffer[numPorts];
00071     for (int i = 0; i < numPorts; ++i)
00072     {
00073         buffer[i].port = i;
00074         buffer[i].cpuBusy = false;
00075 
00076         char qname[20];
00077         sprintf(qname,"portQueue%d",i);
00078         buffer[i].queue.setName(qname);
00079     }
00080 
00081     EV << "Parameters of (" << getClassName() << ") " << getFullPath() << "\n";
00082     EV << "processing time: " << processingTime << "\n";
00083     EV << "ports: " << numPorts << "\n";
00084     EV << "buffer size: " << bufferSize << "\n";
00085     EV << "address table size: " << addressTableSize << "\n";
00086     EV << "aging time: " << agingTime << "\n";
00087     EV << "high watermark: " << highWatermark << "\n";
00088     EV << "pause time: " << pauseUnits << "\n";
00089     EV << "\n";
00090 }

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

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

00093 {
00094     if (!msg->isSelfMessage())
00095     {
00096         // Frame received from MAC unit
00097         handleIncomingFrame(check_and_cast<EtherFrame *>(msg));
00098     }
00099     else
00100     {
00101         // Self message signal used to indicate a frame has been finished processing
00102         processFrame(msg);
00103     }
00104 }

void MACRelayUnitPP::finish (  )  [protected, virtual]

Writes statistics.

00185 {
00186     recordScalar("processed frames", numProcessedFrames);
00187     recordScalar("dropped frames", numDroppedFrames);
00188 }

void MACRelayUnitPP::handleIncomingFrame ( EtherFrame *  msg  )  [protected, virtual]

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

Referenced by handleMessage().

00107 {
00108     // If buffer not full, insert payload frame into buffer and process the frame in parallel.
00109 
00110     long length = frame->getByteLength();
00111     if (length + bufferUsed < bufferSize)
00112     {
00113         int inputport = frame->getArrivalGate()->getIndex();
00114         buffer[inputport].queue.insert(frame);
00115         buffer[inputport].port = inputport;
00116         bufferUsed += length;
00117 
00118         // send PAUSE if above watermark
00119         if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval)
00120         {
00121             // send PAUSE on all ports
00122             for (int i=0; i<numPorts; i++)
00123                 sendPauseFrame(i, pauseUnits);
00124             pauseLastSent = simTime();
00125         }
00126 
00127         if (buffer[inputport].cpuBusy)
00128         {
00129             EV << "Port CPU " << inputport << " busy, incoming frame " << frame << " enqueued for later processing\n";
00130         }
00131         else
00132         {
00133             EV << "Port CPU " << inputport << " free, begin processing of incoming frame " << frame << endl;
00134             buffer[inputport].cpuBusy = true;
00135             cMessage *msg = new cMessage("endProcessing");
00136             msg->setContextPointer(&buffer[inputport]);
00137             scheduleAt(simTime() + processingTime, msg);
00138         }
00139     }
00140     // Drop the frame and record the number of dropped frames
00141     else
00142     {
00143         EV << "Buffer full, dropping frame " << frame << endl;
00144         delete frame;
00145         ++numDroppedFrames;
00146     }
00147 
00148     // Record statistics of buffer usage levels
00149     bufferLevel.record(bufferUsed);
00150 }

void MACRelayUnitPP::processFrame ( cMessage *  msg  )  [protected, virtual]

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

Referenced by handleMessage().

00153 {
00154     // Extract frame from the appropriate buffer;
00155     PortBuffer *pBuff = (PortBuffer*)msg->getContextPointer();
00156     EtherFrame *frame = (EtherFrame*)pBuff->queue.pop();
00157     long length = frame->getByteLength();
00158     int inputport = pBuff->port;
00159 
00160     EV << "Port CPU " << inputport << " completed processing of frame " << frame << endl;
00161 
00162     handleAndDispatchFrame(frame, inputport);
00163     printAddressTable();
00164 
00165     bufferUsed -= length;
00166     bufferLevel.record(bufferUsed);
00167 
00168     numProcessedFrames++;
00169 
00170     // Process next frame in queue if they are pending
00171     if (!pBuff->queue.empty())
00172     {
00173         EV << "Begin processing of next frame\n";
00174         scheduleAt(simTime()+processingTime, msg);
00175     }
00176     else
00177     {
00178         EV << "Port CPU idle\n";
00179         pBuff->cpuBusy = false;
00180         delete msg;
00181     }
00182 }


Member Data Documentation

simtime_t MACRelayUnitPP::processingTime [protected]

int MACRelayUnitPP::bufferSize [protected]

Referenced by handleIncomingFrame(), and initialize().

Referenced by handleIncomingFrame(), and initialize().

int MACRelayUnitPP::pauseUnits [protected]

Referenced by handleIncomingFrame(), and initialize().

simtime_t MACRelayUnitPP::pauseInterval [protected]

Referenced by handleIncomingFrame(), and initialize().

int MACRelayUnitPP::bufferUsed [protected]

simtime_t MACRelayUnitPP::pauseLastSent [protected]

Referenced by handleIncomingFrame(), and initialize().

Referenced by finish(), initialize(), and processFrame().

cOutVector MACRelayUnitPP::bufferLevel [protected]


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:20 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5