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 "MACRelayUnitPP.h"
00019 #include "EtherFrame_m.h"
00020 #include "Ethernet.h"
00021 #include "MACAddress.h"
00022
00023
00024 Define_Module( MACRelayUnitPP );
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 MACRelayUnitPP::MACRelayUnitPP()
00036 {
00037 buffer = NULL;
00038 }
00039
00040 MACRelayUnitPP::~MACRelayUnitPP()
00041 {
00042 delete [] buffer;
00043 }
00044
00045 void MACRelayUnitPP::initialize()
00046 {
00047 MACRelayUnitBase::initialize();
00048
00049 bufferLevel.setName("buffer level");
00050
00051 numProcessedFrames = numDroppedFrames = 0;
00052 WATCH(numProcessedFrames);
00053 WATCH(numDroppedFrames);
00054
00055 processingTime = par("processingTime");
00056 bufferSize = par("bufferSize");
00057 highWatermark = par("highWatermark");
00058 pauseUnits = par("pauseUnits");
00059
00060
00061
00062 pauseInterval = pauseUnits*512.0/100000.0;
00063
00064 pauseLastSent = 0;
00065 WATCH(pauseLastSent);
00066
00067 bufferUsed = 0;
00068 WATCH(bufferUsed);
00069
00070 buffer = new PortBuffer[numPorts];
00071 for (int i = 0; i < numPorts; ++i)
00072 {
00073 buffer[i].port = i;
00074 buffer[i].cpuBusy = false;
00075
00076 char qname[20];
00077 sprintf(qname,"portQueue%d",i);
00078 buffer[i].queue.setName(qname);
00079 }
00080
00081 EV << "Parameters of (" << getClassName() << ") " << getFullPath() << "\n";
00082 EV << "processing time: " << processingTime << "\n";
00083 EV << "ports: " << numPorts << "\n";
00084 EV << "buffer size: " << bufferSize << "\n";
00085 EV << "address table size: " << addressTableSize << "\n";
00086 EV << "aging time: " << agingTime << "\n";
00087 EV << "high watermark: " << highWatermark << "\n";
00088 EV << "pause time: " << pauseUnits << "\n";
00089 EV << "\n";
00090 }
00091
00092 void MACRelayUnitPP::handleMessage(cMessage *msg)
00093 {
00094 if (!msg->isSelfMessage())
00095 {
00096
00097 handleIncomingFrame(check_and_cast<EtherFrame *>(msg));
00098 }
00099 else
00100 {
00101
00102 processFrame(msg);
00103 }
00104 }
00105
00106 void MACRelayUnitPP::handleIncomingFrame(EtherFrame *frame)
00107 {
00108
00109
00110 long length = frame->getByteLength();
00111 if (length + bufferUsed < bufferSize)
00112 {
00113 int inputport = frame->getArrivalGate()->getIndex();
00114 buffer[inputport].queue.insert(frame);
00115 buffer[inputport].port = inputport;
00116 bufferUsed += length;
00117
00118
00119 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval)
00120 {
00121
00122 for (int i=0; i<numPorts; i++)
00123 sendPauseFrame(i, pauseUnits);
00124 pauseLastSent = simTime();
00125 }
00126
00127 if (buffer[inputport].cpuBusy)
00128 {
00129 EV << "Port CPU " << inputport << " busy, incoming frame " << frame << " enqueued for later processing\n";
00130 }
00131 else
00132 {
00133 EV << "Port CPU " << inputport << " free, begin processing of incoming frame " << frame << endl;
00134 buffer[inputport].cpuBusy = true;
00135 cMessage *msg = new cMessage("endProcessing");
00136 msg->setContextPointer(&buffer[inputport]);
00137 scheduleAt(simTime() + processingTime, msg);
00138 }
00139 }
00140
00141 else
00142 {
00143 EV << "Buffer full, dropping frame " << frame << endl;
00144 delete frame;
00145 ++numDroppedFrames;
00146 }
00147
00148
00149 bufferLevel.record(bufferUsed);
00150 }
00151
00152 void MACRelayUnitPP::processFrame(cMessage *msg)
00153 {
00154
00155 PortBuffer *pBuff = (PortBuffer*)msg->getContextPointer();
00156 EtherFrame *frame = (EtherFrame*)pBuff->queue.pop();
00157 long length = frame->getByteLength();
00158 int inputport = pBuff->port;
00159
00160 EV << "Port CPU " << inputport << " completed processing of frame " << frame << endl;
00161
00162 handleAndDispatchFrame(frame, inputport);
00163 printAddressTable();
00164
00165 bufferUsed -= length;
00166 bufferLevel.record(bufferUsed);
00167
00168 numProcessedFrames++;
00169
00170
00171 if (!pBuff->queue.empty())
00172 {
00173 EV << "Begin processing of next frame\n";
00174 scheduleAt(simTime()+processingTime, msg);
00175 }
00176 else
00177 {
00178 EV << "Port CPU idle\n";
00179 pBuff->cpuBusy = false;
00180 delete msg;
00181 }
00182 }
00183
00184 void MACRelayUnitPP::finish()
00185 {
00186 recordScalar("processed frames", numProcessedFrames);
00187 recordScalar("dropped frames", numDroppedFrames);
00188 }
00189