diff --git a/device.c b/device.c index 372a247..d373bfc 100644 --- a/device.c +++ b/device.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: device.c,v 1.58 2007/10/08 12:30:53 rahrenbe Exp $ + * $Id: device.c,v 1.59 2007/10/08 16:24:48 rahrenbe Exp $ */ #include "common.h" @@ -327,9 +327,8 @@ bool cIptvDevice::GetTSPacket(uchar *&Data) } isPacketDelivered = true; Data = p; - // Increment statistics counter - dataBytes += Count; - UpdateActivePids(ts_pid(p), payload(p)); + // Update statistics + AddStatistic(Count, ts_pid(p), payload(p)); // Run the data through all filters for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) { if (secfilters[i]) diff --git a/sectionfilter.c b/sectionfilter.c index 79d47f9..c860253 100644 --- a/sectionfilter.c +++ b/sectionfilter.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: sectionfilter.c,v 1.10 2007/10/05 21:56:02 ajhseppa Exp $ + * $Id: sectionfilter.c,v 1.11 2007/10/08 16:24:48 rahrenbe Exp $ */ #include "sectionfilter.h" @@ -123,9 +123,8 @@ int cIptvSectionFilter::dmxdev_section_callback(const uint8_t *buffer1, size_t b char tmp[64]; error("ERROR: write(): %s", strerror_r(errno, tmp, sizeof(tmp))); } - // Increment statistics counters - filteredData += retval; - ++numberOfCalls; + // Update statistics + AddStatistic(retval, 1); } #ifdef DEBUG_PRINTF else if (retval) diff --git a/statistics.c b/statistics.c index f524c38..fe847f1 100644 --- a/statistics.c +++ b/statistics.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: statistics.c,v 1.12 2007/10/08 12:30:53 rahrenbe Exp $ + * $Id: statistics.c,v 1.13 2007/10/08 16:24:48 rahrenbe Exp $ */ #include @@ -16,7 +16,8 @@ cIptvSectionStatistics::cIptvSectionStatistics() : filteredData(0), numberOfCalls(0), - timer() + timer(), + mutex() { //debug("cIptvSectionStatistics::cIptvSectionStatistics()\n"); } @@ -29,8 +30,13 @@ cIptvSectionStatistics::~cIptvSectionStatistics() cString cIptvSectionStatistics::GetStatistic() { //debug("cIptvSectionStatistics::GetStatistic()\n"); + mutex.Lock(); + long tmpNumberOfCalls = numberOfCalls; + long tmpFilteredData = filteredData; + filteredData = numberOfCalls = 0; uint64_t elapsed = timer.Elapsed(); timer.Set(); + mutex.Unlock(); float divider = elapsed / 1000; char unit[] = { ' ', 'B', '/', 's', '\0' }; if (IptvConfig.IsStatsUnitInKilos()) { @@ -41,18 +47,27 @@ cString cIptvSectionStatistics::GetStatistic() divider /= sizeof(unsigned short) * 8; unit[1] = 'b'; } - cString info = cString::sprintf("%4ld (%4ld %s)", numberOfCalls, divider ? - (long)(filteredData / divider) : 0L, unit); - filteredData = numberOfCalls = 0; + cString info = cString::sprintf("%4ld (%4ld %s)", tmpNumberOfCalls, divider ? + (long)(tmpFilteredData / divider) : 0L, unit); return info; } +void cIptvSectionStatistics::AddStatistic(long Bytes, long Calls) +{ + //debug("cIptvSectionStatistics::AddStatistic(Bytes=%ld, Calls=%ld)\n", Bytes, Calls); + mutex.Lock(); + filteredData += Bytes; + numberOfCalls += Calls; + mutex.Unlock(); +} + // --- cIptvDeviceStatistics ------------------------------------------------- // Device statistic class cIptvDeviceStatistics::cIptvDeviceStatistics() : dataBytes(0), - timer() + timer(), + mutex() { debug("cIptvDeviceStatistics::cIptvDeviceStatistics()\n"); memset(mostActivePids, '\0', sizeof(mostActivePids)); @@ -66,9 +81,15 @@ cIptvDeviceStatistics::~cIptvDeviceStatistics() cString cIptvDeviceStatistics::GetStatistic() { //debug("cIptvDeviceStatistics::GetStatistic()\n"); + mutex.Lock(); long tmpDataBytes = dataBytes; + dataBytes = 0; + pidStruct tmpMostActivePids[IPTV_STATS_ACTIVE_PIDS_COUNT]; + memcpy(&tmpMostActivePids, &mostActivePids, sizeof(tmpMostActivePids)); + memset(&mostActivePids, '\0', sizeof(mostActivePids)); uint64_t elapsed = timer.Elapsed(); timer.Set(); + mutex.Unlock(); float divider = elapsed / 1000; char unit[] = { ' ', 'B', '/', 's', '\0' }; if (IptvConfig.IsStatsUnitInKilos()) { @@ -82,16 +103,14 @@ cString cIptvDeviceStatistics::GetStatistic() cString info = cString::sprintf("Bitrate: %ld %s\n", divider ? (long)(tmpDataBytes / divider) : 0L, unit); for (unsigned int i = 0; i < IPTV_STATS_ACTIVE_PIDS_COUNT; ++i) { - if (mostActivePids[i].pid) + if (tmpMostActivePids[i].pid) info = cString::sprintf("%sPid %d: %4d (%4ld %s)%c", *info, i, - mostActivePids[i].pid, - (long)(mostActivePids[i].DataAmount / divider), + tmpMostActivePids[i].pid, + (long)(tmpMostActivePids[i].DataAmount / divider), unit, ((i + 1) % 2) ? '\t' : '\n'); } if (!endswith(*info, "\n")) info = cString::sprintf("%s%c", *info, '\n'); - dataBytes = 0; - memset(&mostActivePids, '\0', sizeof(mostActivePids)); return info; } @@ -107,9 +126,11 @@ int cIptvDeviceStatistics::SortPids(const void* data1, const void* data2) return 0; } -void cIptvDeviceStatistics::UpdateActivePids(u_short pid, long payload) +void cIptvDeviceStatistics::AddStatistic(long Bytes, u_short pid, long payload) { - //debug("cIptvDeviceStatistics::UpdateActivePids()\n"); + //debug("cIptvDeviceStatistics::AddStatistic(Bytes=%ld, pid=%ld, payload=%ld)\n", Bytes, pid, payload); + mutex.Lock(); + dataBytes += Bytes; const int numberOfElements = sizeof(mostActivePids) / sizeof(pidStruct); // If our statistic already is in the array, update it and quit for (int i = 0; i < numberOfElements; ++i) { @@ -128,6 +149,7 @@ void cIptvDeviceStatistics::UpdateActivePids(u_short pid, long payload) // Re-sort qsort(&mostActivePids, numberOfElements, sizeof(pidStruct), SortPids); } + mutex.Unlock(); } // --- cIptvStreamerStatistics ----------------------------------------------- @@ -135,7 +157,8 @@ void cIptvDeviceStatistics::UpdateActivePids(u_short pid, long payload) // Streamer statistic class cIptvStreamerStatistics::cIptvStreamerStatistics() : dataBytes(0), - timer() + timer(), + mutex() { debug("cIptvStreamerStatistics::cIptvStreamerStatistics()\n"); } @@ -148,8 +171,12 @@ cIptvStreamerStatistics::~cIptvStreamerStatistics() cString cIptvStreamerStatistics::GetStatistic() { //debug("cIptvStreamerStatistics::GetStatistic()\n"); + mutex.Lock(); + long tmpDataBytes = dataBytes; + dataBytes = 0; uint64_t elapsed = timer.Elapsed(); timer.Set(); + mutex.Unlock(); float divider = elapsed / 1000; char unit[] = { ' ', 'B', '/', 's', '\0' }; if (IptvConfig.IsStatsUnitInKilos()) { @@ -160,7 +187,14 @@ cString cIptvStreamerStatistics::GetStatistic() divider /= sizeof(unsigned short) * 8; unit[1] = 'b'; } - long tmpDataBytes = divider ? (long)(dataBytes / divider) : 0L; - dataBytes = 0; - return cString::sprintf("Streamer: %ld %s", tmpDataBytes, unit); + return cString::sprintf("Streamer: %ld %s", divider ? + (long)(tmpDataBytes / divider) : 0L, unit); +} + +void cIptvStreamerStatistics::AddStatistic(long Bytes) +{ + //debug("cIptvStreamerStatistics::AddStatistic(Bytes=%ld)\n", Bytes); + mutex.Lock(); + dataBytes += Bytes; + mutex.Unlock(); } diff --git a/statistics.h b/statistics.h index aaa518c..d54c67f 100644 --- a/statistics.h +++ b/statistics.h @@ -3,43 +3,42 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: statistics.h,v 1.6 2007/10/08 12:25:30 rahrenbe Exp $ + * $Id: statistics.h,v 1.7 2007/10/08 16:24:48 rahrenbe Exp $ */ #ifndef __IPTV_STATISTICS_H #define __IPTV_STATISTICS_H +#include + #include "statisticif.h" // Section statistics class cIptvSectionStatistics : public cIptvStatisticIf { -protected: - long filteredData; - long numberOfCalls; - public: cIptvSectionStatistics(); virtual ~cIptvSectionStatistics(); - cString GetStatistic(); +protected: + void AddStatistic(long Bytes, long Calls); + private: + long filteredData; + long numberOfCalls; cTimeMs timer; + cMutex mutex; }; // Device statistics class cIptvDeviceStatistics : public cIptvStatisticIf { -protected: - long dataBytes; - public: cIptvDeviceStatistics(); virtual ~cIptvDeviceStatistics(); - cString GetStatistic(); protected: - void UpdateActivePids(u_short pid, long payload); + void AddStatistic(long Bytes, u_short pid, long payload); private: struct pidStruct { @@ -47,24 +46,28 @@ private: long DataAmount; }; pidStruct mostActivePids[IPTV_STATS_ACTIVE_PIDS_COUNT]; + long dataBytes; cTimeMs timer; + cMutex mutex; +private: static int SortPids(const void* data1, const void* data2); }; // Streamer statistics class cIptvStreamerStatistics : public cIptvStatisticIf { -protected: - long dataBytes; - public: cIptvStreamerStatistics(); virtual ~cIptvStreamerStatistics(); - cString GetStatistic(); +protected: + void AddStatistic(long Bytes); + private: + long dataBytes; cTimeMs timer; + cMutex mutex; }; #endif // __IPTV_STATISTICS_H diff --git a/streamer.c b/streamer.c index 47cbbcc..d5ce5f3 100644 --- a/streamer.c +++ b/streamer.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: streamer.c,v 1.18 2007/10/07 22:54:09 rahrenbe Exp $ + * $Id: streamer.c,v 1.19 2007/10/08 16:24:49 rahrenbe Exp $ */ #include @@ -37,7 +37,7 @@ void cIptvStreamer::Action(void) unsigned char *buffer = NULL; int length = protocol->Read(&buffer); if (length >= 0) { - dataBytes += length; // Statistics update + AddStatistic(length); mutex->Lock(); int p = ringBuffer->Put(buffer, length); if (p != length && Running())