#include <MACRelayUnitNP.h>
Public Member Functions | |
MACRelayUnitNP () | |
virtual | ~MACRelayUnitNP () |
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 | |
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 |
MACRelayUnitNP::MACRelayUnitNP | ( | ) |
MACRelayUnitNP::~MACRelayUnitNP | ( | ) | [virtual] |
00042 { 00043 for (int i=0; i<numCPUs; i++) 00044 { 00045 cMessage *endProcEvent = endProcEvents[i]; 00046 EtherFrame *etherFrame = (EtherFrame *)endProcEvent->getContextPointer(); 00047 if (etherFrame) 00048 { 00049 endProcEvent->setContextPointer(NULL); 00050 delete etherFrame; 00051 } 00052 cancelAndDelete(endProcEvent); 00053 } 00054 delete [] endProcEvents; 00055 }
void MACRelayUnitNP::initialize | ( | ) | [protected, virtual] |
Read parameters parameters.
Reimplemented from MACRelayUnitBase.
00058 { 00059 MACRelayUnitBase::initialize(); 00060 00061 bufferLevel.setName("buffer level"); 00062 queue.setName("queue"); 00063 00064 numProcessedFrames = numDroppedFrames = 0; 00065 WATCH(numProcessedFrames); 00066 WATCH(numDroppedFrames); 00067 00068 numCPUs = par("numCPUs"); 00069 00070 processingTime = par("processingTime"); 00071 bufferSize = par("bufferSize"); 00072 highWatermark = par("highWatermark"); 00073 pauseUnits = par("pauseUnits"); 00074 00075 // 1 pause unit is 512 bit times; we assume 100Mb MACs here. 00076 // We send a pause again when previous one is about to expire. 00077 pauseInterval = pauseUnits*512.0/100000.0; 00078 00079 pauseLastSent = 0; 00080 WATCH(pauseLastSent); 00081 00082 bufferUsed = 0; 00083 WATCH(bufferUsed); 00084 00085 endProcEvents = new cMessage *[numCPUs]; 00086 for (int i=0; i<numCPUs; i++) 00087 { 00088 char msgname[20]; 00089 sprintf(msgname, "endProcessing-cpu%d", i); 00090 endProcEvents[i] = new cMessage(msgname,i); 00091 } 00092 00093 EV << "Parameters of (" << getClassName() << ") " << getFullPath() << "\n"; 00094 EV << "number of processors: " << numCPUs << "\n"; 00095 EV << "processing time: " << processingTime << "\n"; 00096 EV << "ports: " << numPorts << "\n"; 00097 EV << "buffer size: " << bufferSize << "\n"; 00098 EV << "address table size: " << addressTableSize << "\n"; 00099 EV << "aging time: " << agingTime << "\n"; 00100 EV << "high watermark: " << highWatermark << "\n"; 00101 EV << "pause time: " << pauseUnits << "\n"; 00102 EV << "\n"; 00103 }
void MACRelayUnitNP::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Calls handleIncomingFrame() for frames arrived from outside, and processFrame() for self messages.
00106 { 00107 if (!msg->isSelfMessage()) 00108 { 00109 // Frame received from MAC unit 00110 handleIncomingFrame(check_and_cast<EtherFrame *>(msg)); 00111 } 00112 else 00113 { 00114 // Self message signal used to indicate a frame has finished processing 00115 processFrame(msg); 00116 } 00117 }
void MACRelayUnitNP::finish | ( | ) | [protected, virtual] |
Writes statistics.
00202 { 00203 recordScalar("processed frames", numProcessedFrames); 00204 recordScalar("dropped frames", numDroppedFrames); 00205 }
void MACRelayUnitNP::handleIncomingFrame | ( | EtherFrame * | msg | ) | [protected, virtual] |
Handle incoming Ethernet frame: if buffer full discard it, otherwise, insert it into buffer and start processing if a processor is free.
Referenced by handleMessage().
00120 { 00121 // If buffer not full, insert payload frame into buffer and process the frame in parallel. 00122 00123 long length = frame->getByteLength(); 00124 if (length + bufferUsed < bufferSize) 00125 { 00126 bufferUsed += length; 00127 00128 // send PAUSE if above watermark 00129 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval) 00130 { 00131 // send PAUSE on all ports 00132 for (int i=0; i<numPorts; i++) 00133 sendPauseFrame(i, pauseUnits); 00134 pauseLastSent = simTime(); 00135 } 00136 00137 // assign frame to a free CPU (if there is one) 00138 int i; 00139 for (i=0; i<numCPUs; i++) 00140 if (!endProcEvents[i]->isScheduled()) 00141 break; 00142 if (i==numCPUs) 00143 { 00144 EV << "All CPUs busy, enqueueing incoming frame " << frame << " for later processing\n"; 00145 queue.insert(frame); 00146 } 00147 else 00148 { 00149 EV << "Idle CPU-" << i << " starting processing of incoming frame " << frame << endl; 00150 cMessage *msg = endProcEvents[i]; 00151 ASSERT(msg->getContextPointer()==NULL); 00152 msg->setContextPointer(frame); 00153 scheduleAt(simTime() + processingTime, msg); 00154 } 00155 } 00156 // Drop the frame and record the number of dropped frames 00157 else 00158 { 00159 EV << "Buffer full, dropping frame " << frame << endl; 00160 delete frame; 00161 ++numDroppedFrames; 00162 } 00163 00164 // Record statistics of buffer usage levels 00165 bufferLevel.record(bufferUsed); 00166 }
void MACRelayUnitNP::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().
00169 { 00170 int cpu = msg->getKind(); 00171 EtherFrame *frame = (EtherFrame *) msg->getContextPointer(); 00172 ASSERT(frame); 00173 msg->setContextPointer(NULL); 00174 long length = frame->getByteLength(); 00175 int inputport = frame->getArrivalGate()->getIndex(); 00176 00177 EV << "CPU-" << cpu << " completed processing of frame " << frame << endl; 00178 00179 handleAndDispatchFrame(frame, inputport); 00180 printAddressTable(); 00181 00182 bufferUsed -= length; 00183 bufferLevel.record(bufferUsed); 00184 00185 numProcessedFrames++; 00186 00187 // Process next frame in queue if they are pending 00188 if (!queue.empty()) 00189 { 00190 EtherFrame *newframe = (EtherFrame *) queue.pop(); 00191 msg->setContextPointer(newframe); 00192 EV << "CPU-" << cpu << " starting processing of frame " << newframe << endl; 00193 scheduleAt(simTime()+processingTime, msg); 00194 } 00195 else 00196 { 00197 EV << "CPU-" << cpu << " idle\n"; 00198 } 00199 }
cQueue MACRelayUnitNP::queue [protected] |
Referenced by handleIncomingFrame(), initialize(), and processFrame().
int MACRelayUnitNP::numCPUs [protected] |
Referenced by handleIncomingFrame(), initialize(), MACRelayUnitNP(), and ~MACRelayUnitNP().
simtime_t MACRelayUnitNP::processingTime [protected] |
Referenced by handleIncomingFrame(), initialize(), and processFrame().
int MACRelayUnitNP::bufferSize [protected] |
Referenced by handleIncomingFrame(), and initialize().
long MACRelayUnitNP::highWatermark [protected] |
Referenced by handleIncomingFrame(), and initialize().
int MACRelayUnitNP::pauseUnits [protected] |
Referenced by handleIncomingFrame(), and initialize().
simtime_t MACRelayUnitNP::pauseInterval [protected] |
Referenced by handleIncomingFrame(), and initialize().
int MACRelayUnitNP::bufferUsed [protected] |
Referenced by handleIncomingFrame(), initialize(), and processFrame().
cMessage** MACRelayUnitNP::endProcEvents [protected] |
Referenced by handleIncomingFrame(), initialize(), MACRelayUnitNP(), and ~MACRelayUnitNP().
simtime_t MACRelayUnitNP::pauseLastSent [protected] |
Referenced by handleIncomingFrame(), and initialize().
long MACRelayUnitNP::numProcessedFrames [protected] |
Referenced by finish(), initialize(), and processFrame().
long MACRelayUnitNP::numDroppedFrames [protected] |
Referenced by finish(), handleIncomingFrame(), and initialize().
cOutVector MACRelayUnitNP::bufferLevel [protected] |
Referenced by handleIncomingFrame(), initialize(), and processFrame().