00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef _MSC_VER
00020 #pragma warning(disable:4786)
00021 #endif
00022
00023
00024 #include "MACRelayUnitNP.h"
00025
00026 #include "EtherFrame_m.h"
00027 #include "utils.h"
00028 #include "Ethernet.h"
00029 #include "MACAddress.h"
00030
00031
00032
00033 Define_Module( MACRelayUnitNP );
00034
00035
00036
00037 #ifndef OPP3
00038 static cEnvir& operator<< (cEnvir& ev, const MACAddress& addr)
00039 {
00040 char buf[20];
00041 EV << addr.toHexString(buf);
00042 return ev;
00043 }
00044 #endif
00045
00046 static cEnvir& operator<< (cEnvir& ev, cMessage *msg)
00047 {
00048 ev.printf("(%s)%s",msg->className(),msg->fullName());
00049 return ev;
00050 }
00051
00052
00053 void MACRelayUnitNP::initialize()
00054 {
00055 MACRelayUnitBase::initialize();
00056
00057 bufferLevel.setName("buffer level");
00058 queue.setName("queue");
00059
00060 numProcessedFrames = numDroppedFrames = 0;
00061 WATCH(numProcessedFrames);
00062 WATCH(numDroppedFrames);
00063
00064 numCPUs = par("numCPUs");
00065
00066 processingTime = par("processingTime");
00067 bufferSize = par("bufferSize");
00068 highWatermark = par("highWatermark");
00069 pauseUnits = par("pauseUnits");
00070
00071
00072
00073 pauseInterval = pauseUnits*512.0/100000.0;
00074
00075 pauseLastSent = 0;
00076 WATCH(pauseLastSent);
00077
00078 bufferUsed = 0;
00079 WATCH(bufferUsed);
00080
00081 endProcEvents = new cMessage *[numCPUs];
00082 for (int i=0; i<numCPUs; i++)
00083 {
00084 char msgname[20];
00085 sprintf(msgname, "endProcessing-cpu%d", i);
00086 endProcEvents[i] = new cMessage(msgname,i);
00087 }
00088
00089 EV << "Parameters of (" << className() << ") " << fullPath() << "\n";
00090 EV << "number of processors: " << numCPUs << "\n";
00091 EV << "processing time: " << processingTime << "\n";
00092 EV << "ports: " << numPorts << "\n";
00093 EV << "buffer size: " << bufferSize << "\n";
00094 EV << "address table size: " << addressTableSize << "\n";
00095 EV << "aging time: " << agingTime << "\n";
00096 EV << "high watermark: " << highWatermark << "\n";
00097 EV << "pause time: " << pauseUnits << "\n";
00098 EV << "\n";
00099 }
00100
00101 void MACRelayUnitNP::handleMessage(cMessage *msg)
00102 {
00103 if (!msg->isSelfMessage())
00104 {
00105
00106 if (msg->kind()!=ETH_FRAME)
00107 error("Unknown incoming frame");
00108
00109 handleIncomingFrame((EtherFrame *)msg);
00110 }
00111 else
00112 {
00113
00114 processFrame(msg);
00115 }
00116 }
00117
00118 void MACRelayUnitNP::handleIncomingFrame(EtherFrame *frame)
00119 {
00120
00121
00122 long length = frame->length()/8;
00123 if (length + bufferUsed < bufferSize)
00124 {
00125 bufferUsed += length;
00126
00127
00128 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && pauseLastSent-simTime()>pauseInterval)
00129 {
00130
00131 for (int i=0; i<numPorts; i++)
00132 sendPauseFrame(i, pauseUnits);
00133 pauseLastSent = simTime();
00134 }
00135
00136
00137 int i;
00138 for (i=0; i<numCPUs; i++)
00139 if (!endProcEvents[i]->isScheduled())
00140 break;
00141 if (i==numCPUs)
00142 {
00143 EV << "All CPUs busy, enqueueing incoming frame " << frame << " for later processing\n";
00144 queue.insert(frame);
00145 }
00146 else
00147 {
00148 EV << "Idle CPU-" << i << " starting processing of incoming frame " << frame << endl;
00149 cMessage *msg = endProcEvents[i];
00150 msg->encapsulate(frame);
00151 scheduleAt(simTime() + processingTime, msg);
00152 }
00153 }
00154
00155 else
00156 {
00157 EV << "Buffer full, dropping frame " << frame << endl;
00158 delete frame;
00159 ++numDroppedFrames;
00160 }
00161
00162
00163 bufferLevel.record(bufferUsed);
00164 }
00165
00166 void MACRelayUnitNP::processFrame(cMessage *msg)
00167 {
00168 int cpu = msg->kind();
00169 EtherFrame *frame = (EtherFrame *) msg->decapsulate();
00170 long length = frame->length()/8;
00171 int inputport = frame->arrivalGate()->index();
00172
00173 EV << "CPU-" << cpu << " completed processing of frame " << frame << endl;
00174
00175 handleAndDispatchFrame(frame, inputport);
00176 printAddressTable();
00177
00178 bufferUsed -= length;
00179 bufferLevel.record(bufferUsed);
00180
00181 numProcessedFrames++;
00182
00183
00184 if (!queue.empty())
00185 {
00186 EtherFrame *newframe = (EtherFrame *) queue.pop();
00187 msg->encapsulate(newframe);
00188 EV << "CPU-" << cpu << " starting processing of frame " << newframe << endl;
00189 scheduleAt(simTime()+processingTime, msg);
00190 }
00191 else
00192 {
00193 EV << "CPU-" << cpu << " idle\n";
00194 }
00195 }
00196
00197 void MACRelayUnitNP::finish()
00198 {
00199 if (par("writeScalars").boolValue())
00200 {
00201 recordScalar("processed frames", numProcessedFrames);
00202 recordScalar("dropped frames", numDroppedFrames);
00203 }
00204 }
00205