Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "MACRelayUnitNP.h"
00019 #include "EtherFrame_m.h"
00020 #include "Ethernet.h"
00021 #include "MACAddress.h"
00022
00023
00024 Define_Module( MACRelayUnitNP );
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 MACRelayUnitNP::MACRelayUnitNP()
00036 {
00037 endProcEvents = NULL;
00038 numCPUs = 0;
00039 }
00040
00041 MACRelayUnitNP::~MACRelayUnitNP()
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 }
00056
00057 void MACRelayUnitNP::initialize()
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
00076
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 }
00104
00105 void MACRelayUnitNP::handleMessage(cMessage *msg)
00106 {
00107 if (!msg->isSelfMessage())
00108 {
00109
00110 handleIncomingFrame(check_and_cast<EtherFrame *>(msg));
00111 }
00112 else
00113 {
00114
00115 processFrame(msg);
00116 }
00117 }
00118
00119 void MACRelayUnitNP::handleIncomingFrame(EtherFrame *frame)
00120 {
00121
00122
00123 long length = frame->getByteLength();
00124 if (length + bufferUsed < bufferSize)
00125 {
00126 bufferUsed += length;
00127
00128
00129 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval)
00130 {
00131
00132 for (int i=0; i<numPorts; i++)
00133 sendPauseFrame(i, pauseUnits);
00134 pauseLastSent = simTime();
00135 }
00136
00137
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
00157 else
00158 {
00159 EV << "Buffer full, dropping frame " << frame << endl;
00160 delete frame;
00161 ++numDroppedFrames;
00162 }
00163
00164
00165 bufferLevel.record(bufferUsed);
00166 }
00167
00168 void MACRelayUnitNP::processFrame(cMessage *msg)
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
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 }
00200
00201 void MACRelayUnitNP::finish()
00202 {
00203 recordScalar("processed frames", numProcessedFrames);
00204 recordScalar("dropped frames", numDroppedFrames);
00205 }