reduce cpu load by increasing sleep before ticking pqi and core

This commit is contained in:
jolavillette 2020-05-09 20:35:20 +02:00
parent 4ead639e8c
commit 7c2efbc630
2 changed files with 58 additions and 51 deletions

View file

@ -23,17 +23,17 @@
#include "pqi/pqithreadstreamer.h" #include "pqi/pqithreadstreamer.h"
#include <unistd.h> #include <unistd.h>
#define DEFAULT_STREAMER_TIMEOUT 10000 // 10 ms. #define DEFAULT_STREAMER_TIMEOUT 10000 // 10 ms
#define DEFAULT_STREAMER_SLEEP 1000 // 1 ms. #define DEFAULT_STREAMER_SLEEP 30000 // 30 ms
#define DEFAULT_STREAMER_IDLE_SLEEP 1000000 // 1 sec #define DEFAULT_STREAMER_IDLE_SLEEP 1000000 // 1 sec
//#define PQISTREAMER_DEBUG // #define PQISTREAMER_DEBUG
pqithreadstreamer::pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& id, BinInterface *bio_in, int bio_flags_in) pqithreadstreamer::pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& id, BinInterface *bio_in, int bio_flags_in)
:pqistreamer(rss, id, bio_in, bio_flags_in), mParent(parent), mTimeout(0), mThreadMutex("pqithreadstreamer") :pqistreamer(rss, id, bio_in, bio_flags_in), mParent(parent), mTimeout(0), mThreadMutex("pqithreadstreamer")
{ {
mTimeout = DEFAULT_STREAMER_TIMEOUT; mTimeout = DEFAULT_STREAMER_TIMEOUT;
mSleepPeriod = DEFAULT_STREAMER_SLEEP; mSleepPeriod = DEFAULT_STREAMER_SLEEP;
} }
bool pqithreadstreamer::RecvItem(RsItem *item) bool pqithreadstreamer::RecvItem(RsItem *item)
@ -43,9 +43,8 @@ bool pqithreadstreamer::RecvItem(RsItem *item)
int pqithreadstreamer::tick() int pqithreadstreamer::tick()
{ {
// pqithreadstreamer mutex lock is not needed here // pqithreadstreamer mutex lock is not needed here
// we are only checking if the connection is active, and if not active we will try to establish it // we will only check if the connection is active, and if not we will try to establish it
// RsStackMutex stack(mThreadMutex);
tick_bio(); tick_bio();
return 0; return 0;
@ -53,47 +52,50 @@ int pqithreadstreamer::tick()
void pqithreadstreamer::threadTick() void pqithreadstreamer::threadTick()
{ {
uint32_t recv_timeout = 0; uint32_t recv_timeout = 0;
uint32_t sleep_period = 0; uint32_t sleep_period = 0;
bool isactive = false; bool isactive = false;
{
RsStackMutex stack(mStreamerMtx);
recv_timeout = mTimeout;
sleep_period = mSleepPeriod;
isactive = mBio->isactive();
}
updateRates() ; {
RsStackMutex stack(mStreamerMtx);
recv_timeout = mTimeout;
sleep_period = mSleepPeriod;
isactive = mBio->isactive();
}
if (!isactive) // update the connection rates
{ updateRates() ;
rstime::rs_usleep(DEFAULT_STREAMER_IDLE_SLEEP);
return ;
}
{ // if the connection est not active, long sleep then return
RsStackMutex stack(mThreadMutex); if (!isactive)
tick_recv(recv_timeout); {
} rstime::rs_usleep(DEFAULT_STREAMER_IDLE_SLEEP);
return ;
}
// Push Items, Outside of Mutex. // fill incoming queue with items from SSL
RsItem *incoming = NULL; {
while((incoming = GetItem())) RsStackMutex stack(mThreadMutex);
{ tick_recv(recv_timeout);
RecvItem(incoming); }
}
{ // move items to appropriate service queue or shortcut to fast service
RsStackMutex stack(mThreadMutex); RsItem *incoming = NULL;
tick_send(0); while((incoming = GetItem()))
} {
RecvItem(incoming);
}
if (sleep_period) // parse the outgoing queue and send items to SSL
{ {
rstime::rs_usleep(sleep_period); RsStackMutex stack(mThreadMutex);
} tick_send(0);
}
// sleep
if (sleep_period)
{
rstime::rs_usleep(sleep_period);
}
} }

View file

@ -143,13 +143,14 @@ void RsServer::threadTick()
// if there is time left, we sleep // if there is time left, we sleep
double timeToSleep = mTickInterval - mAvgRunDuration; double timeToSleep = mTickInterval - mAvgRunDuration;
if (timeToSleep > 0) // never sleep less than 50 ms
{ if (timeToSleep < 0.050)
timeToSleep = 0.050;
#ifdef TICK_DEBUG #ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG will sleep " << timeToSleep << " ms" << std::endl; RsDbg() << "TICK_DEBUG will sleep " << (int) (1000 * timeToSleep) << " ms" << std::endl;
#endif #endif
rstime::rs_usleep(timeToSleep * 1000000); rstime::rs_usleep(timeToSleep * 1000000);
}
double ts = getCurrentTS(); double ts = getCurrentTS();
mLastts = ts; mLastts = ts;
@ -229,12 +230,16 @@ void RsServer::threadTick()
// ticking is done, now compute new values of mLastRunDuration, mAvgRunDuration and mTickInterval // ticking is done, now compute new values of mLastRunDuration, mAvgRunDuration and mTickInterval
ts = getCurrentTS(); ts = getCurrentTS();
mLastRunDuration = ts - mLastts; mLastRunDuration = ts - mLastts;
// low-pass filter and don't let mAvgRunDuration exceeds maxTickInterval
mAvgRunDuration = 0.1 * mLastRunDuration + 0.9 * mAvgRunDuration; mAvgRunDuration = 0.1 * mLastRunDuration + 0.9 * mAvgRunDuration;
if (mAvgRunDuration > maxTickInterval)
mAvgRunDuration = maxTickInterval;
#ifdef TICK_DEBUG #ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new mLastRunDuration " << mLastRunDuration << " mAvgRunDuration " << mAvgRunDuration << std::endl; RsDbg() << "TICK_DEBUG new mLastRunDuration " << mLastRunDuration << " mAvgRunDuration " << mAvgRunDuration << std::endl;
if (mLastRunDuration > WARN_BIG_CYCLE_TIME) if (mLastRunDuration > WARN_BIG_CYCLE_TIME)
RsDbg() << "TICK_DEBUG excessively long lycle time " << mLastRunDuration << std::endl; RsDbg() << "TICK_DEBUG excessively long cycle time " << mLastRunDuration << std::endl;
#endif #endif
// if the core has returned that there is more to tick we decrease the ticking interval, else we increse it // if the core has returned that there is more to tick we decrease the ticking interval, else we increse it
@ -250,7 +255,7 @@ void RsServer::threadTick()
RsDbg() << "TICK_DEBUG new tick interval " << mTickInterval << std::endl; RsDbg() << "TICK_DEBUG new tick interval " << mTickInterval << std::endl;
#endif #endif
// keep the tick interval within allowed limits // keep the tick interval target within allowed limits
if (mTickInterval < minTickInterval) if (mTickInterval < minTickInterval)
mTickInterval = minTickInterval; mTickInterval = minTickInterval;
else if (mTickInterval > maxTickInterval) else if (mTickInterval > maxTickInterval)