#include <MACRelayUnitNP.h>
Inheritance diagram for MACRelayUnitNP:
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 |
|
00044 { 00045 endProcEvents = NULL; 00046 numCPUs = 0; 00047 }
|
|
00050 { 00051 for (int i=0; i<numCPUs; i++) 00052 cancelAndDelete(endProcEvents[i]); 00053 delete [] endProcEvents; 00054 }
|
|
Writes statistics. 00201 { 00202 if (par("writeScalars").boolValue()) 00203 { 00204 recordScalar("processed frames", numProcessedFrames); 00205 recordScalar("dropped frames", numDroppedFrames); 00206 } 00207 }
|
|
Handle incoming Ethernet frame: if buffer full discard it, otherwise, insert it into buffer and start processing if a processor is free. 00122 { 00123 // If buffer not full, insert payload frame into buffer and process the frame in parallel. 00124 00125 long length = frame->byteLength(); 00126 if (length + bufferUsed < bufferSize) 00127 { 00128 bufferUsed += length; 00129 00130 // send PAUSE if above watermark 00131 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval) 00132 { 00133 // send PAUSE on all ports 00134 for (int i=0; i<numPorts; i++) 00135 sendPauseFrame(i, pauseUnits); 00136 pauseLastSent = simTime(); 00137 } 00138 00139 // assign frame to a free CPU (if there is one) 00140 int i; 00141 for (i=0; i<numCPUs; i++) 00142 if (!endProcEvents[i]->isScheduled()) 00143 break; 00144 if (i==numCPUs) 00145 { 00146 EV << "All CPUs busy, enqueueing incoming frame " << frame << " for later processing\n"; 00147 queue.insert(frame); 00148 } 00149 else 00150 { 00151 EV << "Idle CPU-" << i << " starting processing of incoming frame " << frame << endl; 00152 cMessage *msg = endProcEvents[i]; 00153 msg->encapsulate(frame); 00154 scheduleAt(simTime() + processingTime, msg); 00155 } 00156 } 00157 // Drop the frame and record the number of dropped frames 00158 else 00159 { 00160 EV << "Buffer full, dropping frame " << frame << endl; 00161 delete frame; 00162 ++numDroppedFrames; 00163 } 00164 00165 // Record statistics of buffer usage levels 00166 bufferLevel.record(bufferUsed); 00167 }
|
|
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 if (msg->kind()!=ETH_FRAME) 00110 error("Unknown incoming frame"); 00111 00112 handleIncomingFrame((EtherFrame *)msg); 00113 } 00114 else 00115 { 00116 // Self message signal used to indicate a frame has been finished processing 00117 processFrame(msg); 00118 } 00119 }
|
|
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 }
|
|
Triggered when a frame has completed processing, it routes the frame to the appropriate port, and starts processing the next frame. 00170 { 00171 int cpu = msg->kind(); 00172 EtherFrame *frame = (EtherFrame *) msg->decapsulate(); 00173 long length = frame->byteLength(); 00174 int inputport = frame->arrivalGate()->index(); 00175 00176 EV << "CPU-" << cpu << " completed processing of frame " << frame << endl; 00177 00178 handleAndDispatchFrame(frame, inputport); 00179 printAddressTable(); 00180 00181 bufferUsed -= length; 00182 bufferLevel.record(bufferUsed); 00183 00184 numProcessedFrames++; 00185 00186 // Process next frame in queue if they are pending 00187 if (!queue.empty()) 00188 { 00189 EtherFrame *newframe = (EtherFrame *) queue.pop(); 00190 msg->encapsulate(newframe); 00191 EV << "CPU-" << cpu << " starting processing of frame " << newframe << endl; 00192 scheduleAt(simTime()+processingTime, msg); 00193 } 00194 else 00195 { 00196 EV << "CPU-" << cpu << " idle\n"; 00197 } 00198 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|