#include <MACRelayUnitPP.h>
Inheritance diagram for MACRelayUnitPP:

Public Member Functions | |
| MACRelayUnitPP () | |
| virtual | ~MACRelayUnitPP () |
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 | |
| simtime_t | processingTime |
| int | bufferSize |
| long | highWatermark |
| int | pauseUnits |
| simtime_t | pauseInterval |
| int | bufferUsed |
| PortBuffer * | buffer |
| simtime_t | pauseLastSent |
| long | numProcessedFrames |
| long | numDroppedFrames |
| cOutVector | bufferLevel |
Classes | |
| struct | PortBuffer |
|
|
00044 {
00045 buffer = NULL;
00046 }
|
|
|
00049 {
00050 delete [] buffer;
00051 }
|
|
|
Writes statistics. 00196 {
00197 if (par("writeScalars").boolValue())
00198 {
00199 recordScalar("processed frames", numProcessedFrames);
00200 recordScalar("dropped frames", numDroppedFrames);
00201 }
00202 }
|
|
|
Handle incoming Ethernet frame: if buffer full discard it, otherwise, insert it into buffer and start processing if processor is free. 00118 {
00119 // If buffer not full, insert payload frame into buffer and process the frame in parallel.
00120
00121 long length = frame->byteLength();
00122 if (length + bufferUsed < bufferSize)
00123 {
00124 int inputport = frame->arrivalGate()->index();
00125 buffer[inputport].queue.insert(frame);
00126 buffer[inputport].port = inputport;
00127 bufferUsed += length;
00128
00129 // send PAUSE if above watermark
00130 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && simTime()-pauseLastSent>pauseInterval)
00131 {
00132 // send PAUSE on all ports
00133 for (int i=0; i<numPorts; i++)
00134 sendPauseFrame(i, pauseUnits);
00135 pauseLastSent = simTime();
00136 }
00137
00138 if (buffer[inputport].cpuBusy)
00139 {
00140 EV << "Port CPU " << inputport << " busy, incoming frame " << frame << " enqueued for later processing\n";
00141 }
00142 else
00143 {
00144 EV << "Port CPU " << inputport << " free, begin processing of incoming frame " << frame << endl;
00145 buffer[inputport].cpuBusy = true;
00146 cMessage *msg = new cMessage("endProcessing");
00147 msg->setContextPointer(&buffer[inputport]);
00148 scheduleAt(simTime() + processingTime, msg);
00149 }
00150 }
00151 // Drop the frame and record the number of dropped frames
00152 else
00153 {
00154 EV << "Buffer full, dropping frame " << frame << endl;
00155 delete frame;
00156 ++numDroppedFrames;
00157 }
00158
00159 // Record statistics of buffer usage levels
00160 bufferLevel.record(bufferUsed);
00161 }
|
|
|
Calls handleIncomingFrame() for frames arrived from outside, and processFrame() for self messages. 00101 {
00102 if (!msg->isSelfMessage())
00103 {
00104 // Frame received from MAC unit
00105 if (msg->kind()!=ETH_FRAME)
00106 error("Unknown incoming frame");
00107
00108 handleIncomingFrame((EtherFrame *)msg);
00109 }
00110 else
00111 {
00112 // Self message signal used to indicate a frame has been finished processing
00113 processFrame(msg);
00114 }
00115 }
|
|
|
Read parameters parameters. Reimplemented from MACRelayUnitBase. 00054 {
00055 MACRelayUnitBase::initialize();
00056
00057 bufferLevel.setName("buffer level");
00058
00059 numProcessedFrames = numDroppedFrames = 0;
00060 WATCH(numProcessedFrames);
00061 WATCH(numDroppedFrames);
00062
00063 processingTime = par("processingTime");
00064 bufferSize = par("bufferSize");
00065 highWatermark = par("highWatermark");
00066 pauseUnits = par("pauseUnits");
00067
00068 // 1 pause unit is 512 bit times; we assume 100Mb MACs here.
00069 // We send a pause again when previous one is about to expire.
00070 pauseInterval = pauseUnits*512.0/100000.0;
00071
00072 pauseLastSent = 0;
00073 WATCH(pauseLastSent);
00074
00075 bufferUsed = 0;
00076 WATCH(bufferUsed);
00077
00078 buffer = new PortBuffer[numPorts];
00079 for (int i = 0; i < numPorts; ++i)
00080 {
00081 buffer[i].port = i;
00082 buffer[i].cpuBusy = false;
00083
00084 char qname[20];
00085 sprintf(qname,"portQueue%d",i);
00086 buffer[i].queue.setName(qname);
00087 }
00088
00089 EV << "Parameters of (" << className() << ") " << fullPath() << "\n";
00090 EV << "processing time: " << processingTime << "\n";
00091 EV << "ports: " << numPorts << "\n";
00092 EV << "buffer size: " << bufferSize << "\n";
00093 EV << "address table size: " << addressTableSize << "\n";
00094 EV << "aging time: " << agingTime << "\n";
00095 EV << "high watermark: " << highWatermark << "\n";
00096 EV << "pause time: " << pauseUnits << "\n";
00097 EV << "\n";
00098 }
|
|
|
Triggered when a frame has completed processing, it routes the frame to the appropriate port, and starts processing the next frame. 00164 {
00165 // Extract frame from the appropriate buffer;
00166 PortBuffer *pBuff = (PortBuffer*)msg->contextPointer();
00167 EtherFrame *frame = (EtherFrame*)pBuff->queue.pop();
00168 long length = frame->byteLength();
00169 int inputport = pBuff->port;
00170
00171 EV << "Port CPU " << inputport << " completed processing of frame " << frame << endl;
00172
00173 handleAndDispatchFrame(frame, inputport);
00174 printAddressTable();
00175
00176 bufferUsed -= length;
00177 bufferLevel.record(bufferUsed);
00178
00179 numProcessedFrames++;
00180
00181 // Process next frame in queue if they are pending
00182 if (!pBuff->queue.empty())
00183 {
00184 EV << "Begin processing of next frame\n";
00185 scheduleAt(simTime()+processingTime, msg);
00186 }
00187 else
00188 {
00189 EV << "Port CPU idle\n";
00190 pBuff->cpuBusy = false;
00191 delete msg;
00192 }
00193 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1.4.1