#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 |
|
00044 { 00045 buffer = NULL; 00046 }
|
|
00049 { 00050 delete [] buffer; 00051 }
|
|
Writes statistics. 00196 { 00197 if (par("writeScalars").boolValue()) 00198 { 00199 recordScalar("processed frames", numProcessedFrames); 00200 recordScalar("dropped frames", numDroppedFrames); 00201 } 00202 }
|
|
Handle incoming Ethernet frame: if buffer full discard it, otherwise, insert it into buffer and start processing if processor is free. 00118 { 00119 // If buffer not full, insert payload frame into buffer and process the frame in parallel. 00120 00121 long length = frame->byteLength(); 00122 if (length + bufferUsed < bufferSize) 00123 { 00124 int inputport = frame->arrivalGate()->index(); 00125 buffer[inputport].queue.insert(frame); 00126 buffer[inputport].port = inputport; 00127 bufferUsed += length; 00128 00129 // send PAUSE if above watermark 00130 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval) 00131 { 00132 // send PAUSE on all ports 00133 for (int i=0; i<numPorts; i++) 00134 sendPauseFrame(i, pauseUnits); 00135 pauseLastSent = simTime(); 00136 } 00137 00138 if (buffer[inputport].cpuBusy) 00139 { 00140 EV << "Port CPU " << inputport << " busy, incoming frame " << frame << " enqueued for later processing\n"; 00141 } 00142 else 00143 { 00144 EV << "Port CPU " << inputport << " free, begin processing of incoming frame " << frame << endl; 00145 buffer[inputport].cpuBusy = true; 00146 cMessage *msg = new cMessage("endProcessing"); 00147 msg->setContextPointer(&buffer[inputport]); 00148 scheduleAt(simTime() + processingTime, msg); 00149 } 00150 } 00151 // Drop the frame and record the number of dropped frames 00152 else 00153 { 00154 EV << "Buffer full, dropping frame " << frame << endl; 00155 delete frame; 00156 ++numDroppedFrames; 00157 } 00158 00159 // Record statistics of buffer usage levels 00160 bufferLevel.record(bufferUsed); 00161 }
|
|
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 if (msg->kind()!=ETH_FRAME) 00106 error("Unknown incoming frame"); 00107 00108 handleIncomingFrame((EtherFrame *)msg); 00109 } 00110 else 00111 { 00112 // Self message signal used to indicate a frame has been finished processing 00113 processFrame(msg); 00114 } 00115 }
|
|
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 }
|
|
Triggered when a frame has completed processing, it routes the frame to the appropriate port, and starts processing the next frame. 00164 { 00165 // Extract frame from the appropriate buffer; 00166 PortBuffer *pBuff = (PortBuffer*)msg->contextPointer(); 00167 EtherFrame *frame = (EtherFrame*)pBuff->queue.pop(); 00168 long length = frame->byteLength(); 00169 int inputport = pBuff->port; 00170 00171 EV << "Port CPU " << inputport << " completed processing of frame " << frame << endl; 00172 00173 handleAndDispatchFrame(frame, inputport); 00174 printAddressTable(); 00175 00176 bufferUsed -= length; 00177 bufferLevel.record(bufferUsed); 00178 00179 numProcessedFrames++; 00180 00181 // Process next frame in queue if they are pending 00182 if (!pBuff->queue.empty()) 00183 { 00184 EV << "Begin processing of next frame\n"; 00185 scheduleAt(simTime()+processingTime, msg); 00186 } 00187 else 00188 { 00189 EV << "Port CPU idle\n"; 00190 pBuff->cpuBusy = false; 00191 delete msg; 00192 } 00193 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|