diff --git a/libretroshare/src/rsserver/p3face-server.cc b/libretroshare/src/rsserver/p3face-server.cc index 54605333b..0ed2f698c 100644 --- a/libretroshare/src/rsserver/p3face-server.cc +++ b/libretroshare/src/rsserver/p3face-server.cc @@ -41,11 +41,12 @@ #include "services/rseventsservice.h" -/**** -#define DEBUG_TICK 1 -****/ +/******************* +#define TICK_DEBUG 1 +*******************/ #define WARN_BIG_CYCLE_TIME (0.2) + #ifdef WINDOWS_SYS #include "util/rstime.h" #include @@ -73,14 +74,13 @@ static double getCurrentTS() // In some cases (VOIP) it's likely that we will need to set them temporarily to a very low // value, in order to favor a fast feedback -const double RsServer::minTimeDelta = 0.05; // 25; -const double RsServer::maxTimeDelta = 0.2; -const double RsServer::kickLimit = 0.15; +const double RsServer::minTickInterval = 0.05; +const double RsServer::maxTickInterval = 0.2; RsServer::RsServer() : - coreMutex("RsServer"), mShutdownCallback([](int){}), - coreReady(false) + coreMutex("RsServer"), mShutdownCallback([](int){}), + coreReady(false) { { RsEventsService* tmpRsEvtPtr = new RsEventsService(); @@ -108,21 +108,20 @@ RsServer::RsServer() : msgSrv = NULL; chatSrv = NULL; mStatusSrv = NULL; - mGxsTunnels = NULL; + mGxsTunnels = NULL; - mMin = 0; - mLoop = 0; + mLastts = getCurrentTS(); + mTickInterval = maxTickInterval ; + mAvgRunDuration = 0; + mLastRunDuration = 0; + mCycle1 = 0; + mCycle2 = 0; + mCycle3 = 0; + mCycle4 = 0; + /* caches (that need ticking) */ - mLastts = getCurrentTS(); - mLastSec = 0; /* for the slower ticked stuff */ - mTimeDelta = 0.25 ; - - mAvgTickRate = mTimeDelta; - - /* caches (that need ticking) */ - - /* Config */ + /* config */ mConfigMgr = NULL; mGeneralConfig = NULL; } @@ -132,143 +131,132 @@ RsServer::~RsServer() delete mGxsTrans; } - /* General Internal Helper Functions - ----> MUST BE LOCKED! - */ +// General Internal Helper Functions ----> MUST BE LOCKED! - - - /* Thread Fn: Run the Core */ void RsServer::threadTick() { - rstime::rs_usleep(mTimeDelta * 1000000); - - double ts = getCurrentTS(); - double delta = ts - mLastts; - - /* for the fast ticked stuff */ - if (delta > mTimeDelta) - { -#ifdef DEBUG_TICK - std::cerr << "Delta: " << delta << std::endl; - std::cerr << "Time Delta: " << mTimeDelta << std::endl; - std::cerr << "Avg Tick Rate: " << mAvgTickRate << std::endl; +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG ticking interval "<< mTickInterval << std::endl; #endif - mLastts = ts; +// we try to tick at a regular interval which depends on the load +// if there is time left, we sleep + double timeToSleep = mTickInterval - mAvgRunDuration; - /******************************** RUN SERVER *****************/ - lockRsCore(); + if (timeToSleep > 0) + { +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG will sleep " << timeToSleep << " ms" << std::endl; +#endif + rstime::rs_usleep(timeToSleep * 1000000); + } - int moreToTick = pqih->tick(); + double ts = getCurrentTS(); + mLastts = ts; -#ifdef DEBUG_TICK - std::cerr << "RsServer::run() ftserver->tick(): moreToTick: " << moreToTick << std::endl; +// stuff we do always +// tick the core +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG ticking server" << std::endl; +#endif + lockRsCore(); + int moreToTick = pqih->tick(); + unlockRsCore(); +// tick the managers +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG ticking mPeerMgr" << std::endl; +#endif + mPeerMgr->tick(); +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG ticking mLinkMgr" << std::endl; +#endif + mLinkMgr->tick(); +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG ticking mNetMgr" << std::endl; +#endif + mNetMgr->tick(); + + +// stuff we do every second + if (ts - mCycle1 > 1) + { +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG every second" << std::endl; +#endif + // slow services + if (rsPlugins) + rsPlugins->slowTickPlugins((rstime_t)ts); + // UDP keepalive + // tou_tick_stunkeepalive(); + // other stuff to tick + // update(); + mCycle1 = ts; + } + +// stuff we do every five seconds + if (ts - mCycle2 > 5) + { +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG every 5 seconds" << std::endl; +#endif + // save stuff + mConfigMgr->tick(); + mCycle2 = ts; + } + +// stuff we do every minute + if (ts - mCycle3 > 60) + { +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG every 60 seconds" << std::endl; +#endif + // force saving FileTransferStatus TODO + // ftserver->saveFileTransferStatus(); + // see if we need to resave certs + // AuthSSL::getAuthSSL()->CheckSaveCertificates(); + mCycle3 = ts; + } + +// stuff we do every hour + if (ts - mCycle4 > 3600) + { +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG every hour" << std::endl; +#endif + mCycle4 = ts; + } + +// ticking is done, now compute new values of mLastRunDuration, mAvgRunDuration and mTickInterval + ts = getCurrentTS(); + mLastRunDuration = ts - mLastts; + mAvgRunDuration = 0.1 * mLastRunDuration + 0.9 * mAvgRunDuration; + +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG new mLastRunDuration " << mLastRunDuration << " mAvgRunDuration " << mAvgRunDuration << std::endl; + if (mLastRunDuration > WARN_BIG_CYCLE_TIME) + RsDbg() << "TICK_DEBUG excessively long lycle time " << mLastRunDuration << std::endl; +#endif + +// if the core has returned that there is more to tick we decrease the ticking interval, else we increse it +// this should be studied closer as I dont think that the core ever returns 1 +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG moreToTick " << moreToTick << std::endl; +#endif + if (moreToTick == 1) + mTickInterval = 0.9 * mTickInterval; + else + mTickInterval = 1.1 * mTickInterval; +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG new tick interval " << mTickInterval << std::endl; #endif - unlockRsCore(); - - /* tick the Managers */ - mPeerMgr->tick(); - mLinkMgr->tick(); - mNetMgr->tick(); - /******************************** RUN SERVER *****************/ - - /* adjust tick rate depending on whether there is more. - */ - - mAvgTickRate = 0.2 * mTimeDelta + 0.8 * mAvgTickRate; - - if (1 == moreToTick) - { - mTimeDelta = 0.9 * mAvgTickRate; - if (mTimeDelta > kickLimit) - { - /* force next tick in one sec - * if we are reading data. - */ - mTimeDelta = kickLimit; - mAvgTickRate = kickLimit; - } - } - else - { - mTimeDelta = 1.1 * mAvgTickRate; - } - - /* limiter */ - if (mTimeDelta < minTimeDelta) - { - mTimeDelta = minTimeDelta; - } - else if (mTimeDelta > maxTimeDelta) - { - mTimeDelta = maxTimeDelta; - } - - /* Fast Updates */ - - - /* now we have the slow ticking stuff */ - /* stuff ticked once a second (but can be slowed down) */ - if ((int) ts > mLastSec) - { - mLastSec = (int) ts; - - // Every second! (UDP keepalive). - //tou_tick_stunkeepalive(); - - // every five loops (> 5 secs) - if (mLoop % 5 == 0) - { - // update_quick_stats(); - - // Update All Every 5 Seconds. - // These Update Functions do the locking themselves. -#ifdef DEBUG_TICK - std::cerr << "RsServer::run() Updates()" << std::endl; -#endif - - mConfigMgr->tick(); /* saves stuff */ - - } - - // every 60 loops (> 1 min) - if (++mLoop >= 60) - { - mLoop = 0; - - /* force saving FileTransferStatus TODO */ - //ftserver->saveFileTransferStatus(); - - /* see if we need to resave certs */ - //AuthSSL::getAuthSSL()->CheckSaveCertificates(); - - /* hour loop */ - if (++mMin >= 60) - { - mMin = 0; - } - } - - /* Tick slow services */ - if(rsPlugins) - rsPlugins->slowTickPlugins((rstime_t)ts); - - // slow update tick as well. - // update(); - } // end of slow tick. - - } // end of only once a second. - -#ifdef DEBUG_TICK - double endCycleTs = getCurrentTS(); - double cycleTime = endCycleTs - ts; - if (cycleTime > WARN_BIG_CYCLE_TIME) - { - std::string out; - rs_sprintf(out, "RsServer::run() WARNING Excessively Long Cycle Time: %g secs => Please DEBUG", cycleTime); - std::cerr << out << std::endl; - } +// keep the tick interval within allowed limits + if (mTickInterval < minTickInterval) + mTickInterval = minTickInterval; + else if (mTickInterval > maxTickInterval) + mTickInterval = maxTickInterval; +#ifdef TICK_DEBUG + RsDbg() << "TICK_DEBUG new tick interval after limiter " << mTickInterval << std::endl; #endif } + diff --git a/libretroshare/src/rsserver/p3face.h b/libretroshare/src/rsserver/p3face.h index 320c6f991..a2637ceaf 100644 --- a/libretroshare/src/rsserver/p3face.h +++ b/libretroshare/src/rsserver/p3face.h @@ -172,8 +172,8 @@ public: // p3Posted *mPosted; // p3PhotoService *mPhoto; // p3GxsCircles *mGxsCircles; -// p3GxsNetService *mGxsNetService; -// p3IdService *mGxsIdService; +// p3GxsNetService *mGxsNetService; +// p3IdService *mGxsIdService; // p3GxsForums *mGxsForums; // p3GxsChannels *mGxsChannels; // p3Wire *mWire; @@ -188,16 +188,14 @@ public: // Worker Data..... - int mMin ; - int mLoop ; - int mLastts ; - long mLastSec ; - double mAvgTickRate ; - double mTimeDelta ; + double mLastts; + double mTickInterval; + double mLastRunDuration; + double mAvgRunDuration; + double mCycle1, mCycle2, mCycle3, mCycle4; - static const double minTimeDelta; // 25; - static const double maxTimeDelta; - static const double kickLimit; + static const double minTickInterval; + static const double maxTickInterval; /// @see RsControl::setShutdownCallback std::function mShutdownCallback;