#include <MACRelayUnitPP.h>
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 |
PortBuffer * | buffer |
simtime_t | pauseLastSent |
long | numProcessedFrames |
long | numDroppedFrames |
cOutVector | bufferLevel |
Classes | |
struct | PortBuffer |
MACRelayUnitPP::MACRelayUnitPP | ( | ) |
MACRelayUnitPP::~MACRelayUnitPP | ( | ) | [virtual] |
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 }
simtime_t MACRelayUnitPP::processingTime [protected] |
Referenced by handleIncomingFrame(), initialize(), and processFrame().
int MACRelayUnitPP::bufferSize [protected] |
Referenced by handleIncomingFrame(), and initialize().
long MACRelayUnitPP::highWatermark [protected] |
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] |
Referenced by handleIncomingFrame(), initialize(), and processFrame().
PortBuffer* MACRelayUnitPP::buffer [protected] |
Referenced by handleIncomingFrame(), initialize(), MACRelayUnitPP(), and ~MACRelayUnitPP().
simtime_t MACRelayUnitPP::pauseLastSent [protected] |
Referenced by handleIncomingFrame(), and initialize().
long MACRelayUnitPP::numProcessedFrames [protected] |
Referenced by finish(), initialize(), and processFrame().
long MACRelayUnitPP::numDroppedFrames [protected] |
Referenced by finish(), handleIncomingFrame(), and initialize().
cOutVector MACRelayUnitPP::bufferLevel [protected] |
Referenced by handleIncomingFrame(), initialize(), and processFrame().