I needed to write a component which would output the average of its intput with a fixed sampling period. As the computation of the average is independent of the rate of incoming data, I used a thread to do the averaging and output.
Following is a simplified example snippet working with my user defined type PCapStream.
- Code: Select all
void MAPSPCapStats::Birth()
{
packetSum = 0;
pSamplingRate = GetFloatProperty("SamplingRate");
if (pSamplingRate <= 0) {
ReportError("SamplingRate must be positive");
CommitSuicide();
}
CreateThread((MAPSThreadFunction) &MAPSPCapStats::AggregateLoop);
}
void MAPSPCapStats::Core()
{
MAPSIOElt *iElt;
iElt = StartReading(Input("iPCapStream"));
if (iElt==NULL)
return;
PCapStream &iPkt=*static_cast<PCapStream *>(iElt->Data());
mutex.Lock();
packetSum++;
mutex.Release();
}
void MAPSPCapStats::AggregateLoop()
{
MAPSIOElt *oElt;
float period = 1000000. / pSamplingRate;
MAPSFloat avgPPS = 0;
while(!IsDying()) {
mutex.Lock();
avgPPS = pSamplingRate * packetSum;
packetSum = 0;
mutex.Release();
oElt = StartWriting(Output("oPackets"));
if (oElt == NULL) {
ReportError("Can't allocate I/O element for writing");
} else {
oElt->Float() = avgPPS;
StopWriting(oElt);
}
Rest(period);
}
}
Is this a correct approach? Is there a better one?
