#include <MACRelayUnitPP.h>
Inheritance diagram for MACRelayUnitPP:
Public Member Functions | |
MACRelayUnitPP () | |
virtual | ~MACRelayUnitPP () |
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 | |
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::finish | ( | ) | [protected, virtual] |
Writes statistics.
00193 { 00194 if (par("writeScalars").boolValue()) 00195 { 00196 recordScalar("processed frames", numProcessedFrames); 00197 recordScalar("dropped frames", numDroppedFrames); 00198 } 00199 }
void MACRelayUnitPP::handleIncomingFrame | ( | EtherFrame * | msg | ) | [protected] |
Handle incoming Ethernet frame: if buffer full discard it, otherwise, insert it into buffer and start processing if processor is free.
00115 { 00116 // If buffer not full, insert payload frame into buffer and process the frame in parallel. 00117 00118 long length = frame->byteLength(); 00119 if (length + bufferUsed < bufferSize) 00120 { 00121 int inputport = frame->arrivalGate()->index(); 00122 buffer[inputport].queue.insert(frame); 00123 buffer[inputport].port = inputport; 00124 bufferUsed += length; 00125 00126 // send PAUSE if above watermark 00127 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval) 00128 { 00129 // send PAUSE on all ports 00130 for (int i=0; i<numPorts; i++) 00131 sendPauseFrame(i, pauseUnits); 00132 pauseLastSent = simTime(); 00133 } 00134 00135 if (buffer[inputport].cpuBusy) 00136 { 00137 EV << "Port CPU " << inputport << " busy, incoming frame " << frame << " enqueued for later processing\n"; 00138 } 00139 else 00140 { 00141 EV << "Port CPU " << inputport << " free, begin processing of incoming frame " << frame << endl; 00142 buffer[inputport].cpuBusy = true; 00143 cMessage *msg = new cMessage("endProcessing"); 00144 msg->setContextPointer(&buffer[inputport]); 00145 scheduleAt(simTime() + processingTime, msg); 00146 } 00147 } 00148 // Drop the frame and record the number of dropped frames 00149 else 00150 { 00151 EV << "Buffer full, dropping frame " << frame << endl; 00152 delete frame; 00153 ++numDroppedFrames; 00154 } 00155 00156 // Record statistics of buffer usage levels 00157 bufferLevel.record(bufferUsed); 00158 }
void MACRelayUnitPP::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Calls handleIncomingFrame() for frames arrived from outside, and processFrame() for self messages.
00101 { 00102 if (!msg->isSelfMessage()) 00103 { 00104 // Frame received from MAC unit 00105 handleIncomingFrame(check_and_cast<EtherFrame *>(msg)); 00106 } 00107 else 00108 { 00109 // Self message signal used to indicate a frame has been finished processing 00110 processFrame(msg); 00111 } 00112 }
void MACRelayUnitPP::initialize | ( | ) | [protected, virtual] |
Read parameters parameters.
Reimplemented from MACRelayUnitBase.
00054 { 00055 MACRelayUnitBase::initialize(); 00056 00057 bufferLevel.setName("buffer level"); 00058 00059 numProcessedFrames = numDroppedFrames = 0; 00060 WATCH(numProcessedFrames); 00061 WATCH(numDroppedFrames); 00062 00063 processingTime = par("processingTime"); 00064 bufferSize = par("bufferSize"); 00065 highWatermark = par("highWatermark"); 00066 pauseUnits = par("pauseUnits"); 00067 00068 // 1 pause unit is 512 bit times; we assume 100Mb MACs here. 00069 // We send a pause again when previous one is about to expire. 00070 pauseInterval = pauseUnits*512.0/100000.0; 00071 00072 pauseLastSent = 0; 00073 WATCH(pauseLastSent); 00074 00075 bufferUsed = 0; 00076 WATCH(bufferUsed); 00077 00078 buffer = new PortBuffer[numPorts]; 00079 for (int i = 0; i < numPorts; ++i) 00080 { 00081 buffer[i].port = i; 00082 buffer[i].cpuBusy = false; 00083 00084 char qname[20]; 00085 sprintf(qname,"portQueue%d",i); 00086 buffer[i].queue.setName(qname); 00087 } 00088 00089 EV << "Parameters of (" << className() << ") " << fullPath() << "\n"; 00090 EV << "processing time: " << processingTime << "\n"; 00091 EV << "ports: " << numPorts << "\n"; 00092 EV << "buffer size: " << bufferSize << "\n"; 00093 EV << "address table size: " << addressTableSize << "\n"; 00094 EV << "aging time: " << agingTime << "\n"; 00095 EV << "high watermark: " << highWatermark << "\n"; 00096 EV << "pause time: " << pauseUnits << "\n"; 00097 EV << "\n"; 00098 }
void MACRelayUnitPP::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.
00161 { 00162 // Extract frame from the appropriate buffer; 00163 PortBuffer *pBuff = (PortBuffer*)msg->contextPointer(); 00164 EtherFrame *frame = (EtherFrame*)pBuff->queue.pop(); 00165 long length = frame->byteLength(); 00166 int inputport = pBuff->port; 00167 00168 EV << "Port CPU " << inputport << " completed processing of frame " << frame << endl; 00169 00170 handleAndDispatchFrame(frame, inputport); 00171 printAddressTable(); 00172 00173 bufferUsed -= length; 00174 bufferLevel.record(bufferUsed); 00175 00176 numProcessedFrames++; 00177 00178 // Process next frame in queue if they are pending 00179 if (!pBuff->queue.empty()) 00180 { 00181 EV << "Begin processing of next frame\n"; 00182 scheduleAt(simTime()+processingTime, msg); 00183 } 00184 else 00185 { 00186 EV << "Port CPU idle\n"; 00187 pBuff->cpuBusy = false; 00188 delete msg; 00189 } 00190 }
PortBuffer* MACRelayUnitPP::buffer [protected] |
cOutVector MACRelayUnitPP::bufferLevel [protected] |
int MACRelayUnitPP::bufferSize [protected] |
int MACRelayUnitPP::bufferUsed [protected] |
long MACRelayUnitPP::highWatermark [protected] |
long MACRelayUnitPP::numDroppedFrames [protected] |
long MACRelayUnitPP::numProcessedFrames [protected] |
simtime_t MACRelayUnitPP::pauseInterval [protected] |
simtime_t MACRelayUnitPP::pauseLastSent [protected] |
int MACRelayUnitPP::pauseUnits [protected] |
simtime_t MACRelayUnitPP::processingTime [protected] |