Commit 73b6ea42 authored by Pavel Vainerman's avatar Pavel Vainerman Committed by Pavel Vainerman

(timers): used steady_clock instead high_resolution_clock

parent 4ed50544
......@@ -314,7 +314,7 @@ void UNetReceiver::statisticsEvent(ev::periodic& tm, int revents) noexcept
return;
}
t_end = chrono::high_resolution_clock::now();
t_end = chrono::steady_clock::now();
float sec = chrono::duration_cast<chrono::duration<float>>(t_end - t_stats).count();
t_stats = t_end;
stats.recvPerSec = recvCount / sec;
......@@ -537,7 +537,7 @@ void UNetReceiver::readEvent( ev::io& watcher ) noexcept
return;
bool ok = false;
t_start = chrono::high_resolution_clock::now();
t_start = chrono::steady_clock::now();
try
{
......@@ -564,7 +564,7 @@ void UNetReceiver::readEvent( ev::io& watcher ) noexcept
ptRecvTimeout.reset();
}
t_end = chrono::high_resolution_clock::now();
t_end = chrono::steady_clock::now();
stats.recvProcessingTime_microsec = std::chrono::duration_cast<std::chrono::microseconds>(t_end - t_start).count();
}
// -----------------------------------------------------------------------------
......@@ -621,7 +621,7 @@ void UNetReceiver::updateEvent( ev::periodic& tm, int revents ) noexcept
bool recvOk = checkConnection();
// обновление данных в SM
t_start = chrono::high_resolution_clock::now();
t_start = chrono::steady_clock::now();
try
{
......@@ -632,7 +632,7 @@ void UNetReceiver::updateEvent( ev::periodic& tm, int revents ) noexcept
unetcrit << myname << "(updateEvent): " << ex.what() << std::endl;
}
t_end = chrono::high_resolution_clock::now();
t_end = chrono::steady_clock::now();
stats.upProcessingTime_microsec = std::chrono::duration_cast<std::chrono::microseconds>(t_end - t_start).count();
if( sidRespond != DefaultObjectId )
......
......@@ -218,9 +218,9 @@ namespace uniset
// счётчики для подсчёта статистики
size_t recvCount = { 0 };
size_t upCount = { 0 };
std::chrono::system_clock::time_point t_start;
std::chrono::system_clock::time_point t_end;
std::chrono::system_clock::time_point t_stats;
std::chrono::steady_clock::time_point t_start;
std::chrono::steady_clock::time_point t_end;
std::chrono::steady_clock::time_point t_stats;
// текущая статистика
struct Stats
......
......@@ -277,7 +277,7 @@ int main(int argc, char* argv[])
if( ncycles > 0 )
nc = ncycles;
auto t_start = high_resolution_clock::now();
auto t_start = steady_clock::now();
unsigned int npack = 0;
......@@ -287,7 +287,7 @@ int main(int argc, char* argv[])
{
if( nprof > 0 && npack >= nprof )
{
auto t_end = high_resolution_clock::now();
auto t_end = steady_clock::now();
float sec = duration_cast<duration<float>>(t_end - t_start).count();
cout << "Receive " << setw(5) << npack << " packets for " << setw(8) << sec << " sec "
<< " [ 1 packet per " << setw(10) << ( sec / (float)npack ) << " sec ]" << endl;
......
......@@ -229,7 +229,7 @@ int main(int argc, char* argv[])
if( ncycles > 0 )
nc = ncycles;
auto t_start = high_resolution_clock::now();
auto t_start = steady_clock::now();
unsigned int npack = 0;
......@@ -239,7 +239,7 @@ int main(int argc, char* argv[])
{
if( nprof > 0 && npack >= nprof )
{
auto t_end = high_resolution_clock::now();
auto t_end = steady_clock::now();
float sec = duration_cast<duration<float>>(t_end - t_start).count();
cout << "Receive " << setw(5) << npack << " packets for " << setw(8) << sec << " sec "
<< " [ 1 packet per " << setw(10) << ( sec / (float)npack ) << " sec ]" << endl;
......
......@@ -118,7 +118,7 @@ namespace uniset
// отделяем внутреннее (теперь уже стандартное >= c++11)
// представление для работы со временем (std::chrono)
// и тип (t_msec) для "пользователей"
std::chrono::high_resolution_clock::time_point t_start; /*!< время установки таймера (сброса) */
std::chrono::steady_clock::time_point t_start; /*!< время установки таймера (сброса) */
std::chrono::milliseconds t_inner_msec; /*!< время установки таймера, мсек (в единицах std::chrono) */
private:
......
......@@ -63,7 +63,7 @@ namespace uniset
do
{
status = future.wait_for(std::chrono::milliseconds(tout_msec));
status = future.wait_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(tout_msec));
if( status == std::future_status::timeout )
return false;
......@@ -99,7 +99,7 @@ namespace uniset
do
{
status = future.wait_for(std::chrono::milliseconds(tout_msec));
status = future.wait_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(tout_msec));
if( status == std::future_status::timeout )
return false;
......
......@@ -297,7 +297,7 @@ namespace uniset
ulogsys << "(FINISH GUARD THREAD): wait " << TERMINATE_TIMEOUT_SEC << " sec.." << endl << flush;
g_doneevent.wait_for(lk, std::chrono::milliseconds(TERMINATE_TIMEOUT_SEC * 1000), []()
g_doneevent.wait_until(lk, std::chrono::steady_clock::now() + std::chrono::milliseconds(TERMINATE_TIMEOUT_SEC * 1000), []()
{
return (g_done == true);
} );
......
......@@ -46,7 +46,7 @@ namespace uniset
thr = unisetstd::make_unique<std::thread>( [&] { CommonEventLoop::defaultLoop(); } );
std::unique_lock<std::mutex> lock2(looprunOK_mutex);
looprunOK_event.wait_for(lock2, std::chrono::milliseconds(waitTimeout_msec), [&]()
looprunOK_event.wait_until(lock2, std::chrono::steady_clock::now() + std::chrono::milliseconds(waitTimeout_msec), [&]()
{
return (isrunning == true);
} );
......@@ -70,7 +70,7 @@ namespace uniset
evprep.send(); // будим default loop
// ожидаем обработки evprepare (которая будет в defaultLoop)
prep_event.wait_for(locker, std::chrono::milliseconds(waitTimeout_msec), [ = ]()
prep_event.wait_until(locker, std::chrono::steady_clock::now() + std::chrono::milliseconds(waitTimeout_msec), [ = ]()
{
return ( prep_notify == true );
} );
......
......@@ -171,7 +171,7 @@ namespace uniset
return true;
std::unique_lock<std::mutex> lock(looprunOK_mutex);
looprunOK_event.wait_for(lock, std::chrono::milliseconds(waitTimeout_msec), [&]()
looprunOK_event.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(waitTimeout_msec), [&]()
{
return (isrunning == true);
} );
......
......@@ -23,60 +23,63 @@
#include <sstream>
#include <time.h>
#include "PassiveTimer.h"
#include <iostream>
// ------------------------------------------------------------------------------------------
using namespace std;
// ------------------------------------------------------------------------------------------
namespace uniset
{
// ------------------------------------------------------------------------------------------
PassiveCondTimer::PassiveCondTimer() noexcept:
terminated(ATOMIC_VAR_INIT(1))
{
}
// ------------------------------------------------------------------------------------------
PassiveCondTimer::~PassiveCondTimer() noexcept
{
terminate();
}
// ------------------------------------------------------------------------------------------
void PassiveCondTimer::terminate() noexcept
{
try
{
std::unique_lock<std::mutex> lk(m_working);
terminated = true;
}
catch(...) {}
// ------------------------------------------------------------------------------------------
PassiveCondTimer::PassiveCondTimer() noexcept:
terminated(ATOMIC_VAR_INIT(1))
{
}
// ------------------------------------------------------------------------------------------
PassiveCondTimer::~PassiveCondTimer() noexcept
{
terminate();
}
// ------------------------------------------------------------------------------------------
void PassiveCondTimer::terminate() noexcept
{
try
{
std::unique_lock<std::mutex> lk(m_working);
terminated = true;
}
catch(...) {}
cv_working.notify_all();
}
// ------------------------------------------------------------------------------------------
bool PassiveCondTimer::wait( timeout_t time_msec ) noexcept
{
try
{
std::unique_lock<std::mutex> lk(m_working);
terminated = false;
cv_working.notify_all();
}
// ------------------------------------------------------------------------------------------
bool PassiveCondTimer::wait( timeout_t time_msec ) noexcept
{
try
{
std::unique_lock<std::mutex> lk(m_working);
terminated = false;
timeout_t t_msec = PassiveTimer::setTiming(time_msec); // вызываем для совместимости с обычным PassiveTimer-ом
timeout_t t_msec = PassiveTimer::setTiming(time_msec); // вызываем для совместимости с обычным PassiveTimer-ом
if( time_msec == WaitUpTime )
{
while( !terminated )
cv_working.wait(lk);
}
else
cv_working.wait_for(lk, std::chrono::milliseconds(t_msec), [&]()
{
return (terminated == true);
} );
if( time_msec == WaitUpTime )
{
while( !terminated )
cv_working.wait(lk);
}
else
{
cv_working.wait_until(lk, std::chrono::steady_clock::now() + std::chrono::milliseconds(t_msec), [&]()
{
return (terminated == true);
});
}
terminated = true;
return true;
}
catch(...) {}
terminated = true;
return true;
}
catch(...) {}
return false;
}
// ------------------------------------------------------------------------------------------
return false;
}
// ------------------------------------------------------------------------------------------
} // end of namespace uniset
......@@ -33,25 +33,25 @@ using namespace std;
// ------------------------------------------------------------------------------------------
void PassiveSigTimer::call(int signo, siginfo_t* evp, void* ucontext)
{
cout << "PassiveSigTimer: callme time=" << evp->si_value.sival_int << " ms" << endl;
cout << "PassiveSigTimer: callme time=" << evp->si_value.sival_int << " ms" << endl;
}
void PassiveSigTimer::callalrm(int signo)
{
// cout << "PassiveSigTimer: callme signo "<< signo <<endl;
// cout << "PassiveSigTimer: callme signo "<< signo <<endl;
}
// ------------------------------------------------------------------------------------------
PassiveSigTimer::PassiveSigTimer():
terminated(1)
terminated(1)
{
init();
init();
}
// ------------------------------------------------------------------------------------------
PassiveSigTimer::~PassiveSigTimer()
{
terminate();
terminate();
}
// ------------------------------------------------------------------------------------------
void PassiveSigTimer::init()
......@@ -60,79 +60,79 @@ void PassiveSigTimer::init()
// ------------------------------------------------------------------------------------------
void PassiveSigTimer::terminate()
{
if (!terminated)
{
t_msec = 0;
terminated = 1;
// cout << "PassiveTimer("<< pid <<"): прерываю работу "<< endl;
kill(pid, SIGALRM);
}
if (!terminated)
{
t_msec = 0;
terminated = 1;
// cout << "PassiveTimer("<< pid <<"): прерываю работу "<< endl;
kill(pid, SIGALRM);
}
}
// ------------------------------------------------------------------------------------------
bool PassiveSigTimer::wait(timeout_t timeMS)
{
pid = getpid();
// struct itimerval val;
struct sigaction action;
sigemptyset(&action.sa_mask);
action.sa_handler = (void(*)(int))callalrm;
action.sa_flags = SA_RESETHAND;//SA_RESTART;
if( sigaction(SIGALRM, &action, 0) == -1)
{
cerr << "PassiveSigTimer: error sigaction" << endl;
return false;
}
// if ( !terminated )
// terminate();
terminated = 0;
timeout_t sec;
timeout_t msec;
if (timeMS == WaitUpTime)
{
sec = 15 * 60; // 15min
msec = 0;
}
else
{
sec = timeMS / 1000;
msec = (timeMS % 1000) * 1000;
}
mtimer.it_value.tv_sec = sec;
mtimer.it_value.tv_usec = msec;
mtimer.it_interval.tv_sec = 0;
mtimer.it_interval.tv_usec = 0;
setitimer( ITIMER_REAL, &mtimer, (struct itimerval*)0 );
PassiveTimer::setTiming(timeMS); // вызываем для совместимости с обычным PassiveTimer-ом
sigset_t mask, oldmask;
sigemptyset(&mask);
// блокируем все сигналы кроме этих
sigaddset( &mask, SIGALRM );
sigprocmask( SIG_BLOCK, &mask, &oldmask );
if (timeMS == WaitUpTime)
{
while (!terminated)
sigsuspend( &oldmask );
}
else
sigsuspend( &oldmask );
terminated = 1;
sigprocmask( SIG_UNBLOCK, &mask, NULL );
// cout << "PassiveSigTimer: time ok"<< endl;
return true;
pid = getpid();
// struct itimerval val;
struct sigaction action;
sigemptyset(&action.sa_mask);
action.sa_handler = (void(*)(int))callalrm;
action.sa_flags = SA_RESETHAND;//SA_RESTART;
if( sigaction(SIGALRM, &action, 0) == -1)
{
cerr << "PassiveSigTimer: error sigaction" << endl;
return false;
}
// if ( !terminated )
// terminate();
terminated = 0;
timeout_t sec;
timeout_t msec;
if (timeMS == WaitUpTime)
{
sec = 15 * 60; // 15min
msec = 0;
}
else
{
sec = timeMS / 1000;
msec = (timeMS % 1000) * 1000;
}
mtimer.it_value.tv_sec = sec;
mtimer.it_value.tv_usec = msec;
mtimer.it_interval.tv_sec = 0;
mtimer.it_interval.tv_usec = 0;
setitimer( ITIMER_REAL, &mtimer, (struct itimerval*)0 );
PassiveTimer::setTiming(timeMS); // вызываем для совместимости с обычным PassiveTimer-ом
sigset_t mask, oldmask;
sigemptyset(&mask);
// блокируем все сигналы кроме этих
sigaddset( &mask, SIGALRM );
sigprocmask( SIG_BLOCK, &mask, &oldmask );
if (timeMS == WaitUpTime)
{
while (!terminated)
sigsuspend( &oldmask );
}
else
sigsuspend( &oldmask );
terminated = 1;
sigprocmask( SIG_UNBLOCK, &mask, NULL );
// cout << "PassiveSigTimer: time ok"<< endl;
return true;
}
// ------------------------------------------------------------------------------------------
......
......@@ -23,116 +23,116 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -----------------------------------------------------------------------------
PassiveTimer::PassiveTimer( ) noexcept:
PassiveTimer(WaitUpTime)
{
reset();
}
//------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
PassiveTimer::PassiveTimer( ) noexcept:
PassiveTimer(WaitUpTime)
{
reset();
}
//------------------------------------------------------------------------------
PassiveTimer::PassiveTimer( timeout_t msec ) noexcept:
t_msec(msec)
{
setTiming(msec);
}
PassiveTimer::PassiveTimer( timeout_t msec ) noexcept:
t_msec(msec)
{
setTiming(msec);
}
//------------------------------------------------------------------------------
PassiveTimer::~PassiveTimer() noexcept
{
//------------------------------------------------------------------------------
PassiveTimer::~PassiveTimer() noexcept
{
}
//------------------------------------------------------------------------------
bool PassiveTimer::checkTime() const noexcept
{
if( t_msec == WaitUpTime )
return false;
}
//------------------------------------------------------------------------------
bool PassiveTimer::checkTime() const noexcept
{
if( t_msec == WaitUpTime )
return false;
if( t_msec == 0 )
return true;
if( t_msec == 0 )
return true;
return ( std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t_start).count() >= t_inner_msec.count() );
}
return ( std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - t_start).count() >= t_inner_msec.count() );
}
//------------------------------------------------------------------------------
// Установить время таймера
timeout_t PassiveTimer::setTiming( timeout_t msec ) noexcept
{
t_msec = msec;
//------------------------------------------------------------------------------
// Установить время таймера
timeout_t PassiveTimer::setTiming( timeout_t msec ) noexcept
{
t_msec = msec;
// TODO: не знаю как по-другому
// приходиться делать это через промежуточную переменную
std::chrono::milliseconds ms(msec);
std::swap(t_inner_msec, ms);
// TODO: не знаю как по-другому
// приходиться делать это через промежуточную переменную
std::chrono::milliseconds ms(msec);
std::swap(t_inner_msec, ms);
PassiveTimer::reset();
return getInterval();
}
//------------------------------------------------------------------------------
// Запустить таймер
void PassiveTimer::reset(void) noexcept
{
t_start = std::chrono::high_resolution_clock::now();
}
//------------------------------------------------------------------------------
// получить текущее значение таймера
timeout_t PassiveTimer::getCurrent() const noexcept
{
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t_start).count();
}
//------------------------------------------------------------------------------
timeout_t PassiveTimer::getInterval() const noexcept
{
return (t_msec != UniSetTimer::WaitUpTime ? t_msec : 0);
}
//------------------------------------------------------------------------------
void PassiveTimer::terminate() noexcept
{
t_msec = WaitUpTime;
}
//------------------------------------------------------------------------------
PassiveTimer::reset();
return getInterval();
}
//------------------------------------------------------------------------------
// Запустить таймер
void PassiveTimer::reset(void) noexcept
{
t_start = std::chrono::steady_clock::now();
}
//------------------------------------------------------------------------------
// получить текущее значение таймера
timeout_t PassiveTimer::getCurrent() const noexcept
{
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - t_start).count();
}
//------------------------------------------------------------------------------
timeout_t PassiveTimer::getInterval() const noexcept
{
return (t_msec != UniSetTimer::WaitUpTime ? t_msec : 0);
}
//------------------------------------------------------------------------------
void PassiveTimer::terminate() noexcept
{
t_msec = WaitUpTime;
}
//------------------------------------------------------------------------------
timeout_t UniSetTimer::getLeft(timeout_t timeout) const noexcept
{
timeout_t ct = getCurrent();
timeout_t UniSetTimer::getLeft(timeout_t timeout) const noexcept
{
timeout_t ct = getCurrent();
if( timeout <= ct )
return 0;
if( timeout <= ct )
return 0;
return timeout - ct;
}
//------------------------------------------------------------------------------
bool UniSetTimer::wait( timeout_t timeMS )
{
return false;
}
//------------------------------------------------------------------------------
void UniSetTimer::stop() noexcept
{
terminate();
}
//------------------------------------------------------------------------------
const Poco::Timespan UniSetTimer::millisecToPoco( const timeout_t msec ) noexcept
{
if( msec == WaitUpTime )
{
// int days, int hours, int minutes, int seconds, int microSeconds
return Poco::Timespan(std::numeric_limits<int>::max(), 0, 0, 0, 0);
}
return timeout - ct;
}
//------------------------------------------------------------------------------
bool UniSetTimer::wait( timeout_t timeMS )
{
return false;
}
//------------------------------------------------------------------------------
void UniSetTimer::stop() noexcept
{
terminate();
}
//------------------------------------------------------------------------------
const Poco::Timespan UniSetTimer::millisecToPoco( const timeout_t msec ) noexcept
{
if( msec == WaitUpTime )
{
// int days, int hours, int minutes, int seconds, int microSeconds
return Poco::Timespan(std::numeric_limits<int>::max(), 0, 0, 0, 0);
}
// msec --> usec
return Poco::Timespan( long(msec / 1000), long((msec * 1000) % 1000000) );
}
//------------------------------------------------------------------------------
const Poco::Timespan UniSetTimer::microsecToPoco( const timeout_t usec ) noexcept
{
if( usec == WaitUpTime )
{
// int days, int hours, int minutes, int seconds, int microSeconds
return Poco::Timespan(std::numeric_limits<int>::max(), 0, 0, 0, 0);
}
// msec --> usec
return Poco::Timespan( long(msec / 1000), long((msec * 1000) % 1000000) );
}
//------------------------------------------------------------------------------
const Poco::Timespan UniSetTimer::microsecToPoco( const timeout_t usec ) noexcept
{
if( usec == WaitUpTime )
{
// int days, int hours, int minutes, int seconds, int microSeconds
return Poco::Timespan(std::numeric_limits<int>::max(), 0, 0, 0, 0);
}
return Poco::Timespan( long(usec / 1000000), long(usec % 1000000) );
}
//------------------------------------------------------------------------------
return Poco::Timespan( long(usec / 1000000), long(usec % 1000000) );
}
//------------------------------------------------------------------------------
} // end of namespace uniset
......@@ -31,22 +31,22 @@ int WaitingPassiveTimer::countTimers = 0;
void WaitingPassiveTimer::checkCount()
{
if ( countTimers >= MAX_COUNT_THRPASSIVE_TIMERS )
{
char err[200];
sprintf(err, "LimitThrPassiveTimers: превышено максимальное количество таймеров %d", MAX_COUNT_THRPASSIVE_TIMERS);
throw LimitWaitingPTimers(err);
}
if ( countTimers >= MAX_COUNT_THRPASSIVE_TIMERS )
{
char err[200];
sprintf(err, "LimitThrPassiveTimers: превышено максимальное количество таймеров %d", MAX_COUNT_THRPASSIVE_TIMERS);
throw LimitWaitingPTimers(err);
}
countTimers++;
countTimers++;
}
WaitingPassiveTimer::WaitingPassiveTimer()throw(LimitWaitingPTimers):
terminated(true),
// pCall(NULL),
pValue(NULL)
terminated(true),
// pCall(NULL),
pValue(NULL)
{
checkCount();
checkCount();
}
// ------------------------------------------------------------------------------------------
......@@ -61,72 +61,72 @@ WaitingPassiveTimer::WaitingPassiveTimer( void(*fp)(void) ):
* \param *value - указатель на объект подлежащий изменению
*/
WaitingPassiveTimer::WaitingPassiveTimer(bool* value )throw(LimitWaitingPTimers):
pValue(value),
terminated(true)
// pCall(NULL)
pValue(value),
terminated(true)
// pCall(NULL)
{
checkCount();
checkCount();
}
// ------------------------------------------------------------------------------------------
WaitingPassiveTimer::~WaitingPassiveTimer()
{
// cout << "Timer: destructor.."<< endl;
// pCall = NULL;
pValue = NULL;
terminate();
countTimers--;
// cout << "Timer: destructor.."<< endl;
// pCall = NULL;
pValue = NULL;
terminate();
countTimers--;
}
// ------------------------------------------------------------------------------------------
void WaitingPassiveTimer::work()
{
timeout_t sleepMKS = MIN_QUANTITY_TIME_MS * 1000;
terminated = false;
timeout_t sleepMKS = MIN_QUANTITY_TIME_MS * 1000;
terminated = false;
while( !terminated )
{
std::this_thread::sleep_for(std::chrono::microseconds(sleepMKS));
while( !terminated )
{
std::this_thread::sleep_for(std::chrono::microseconds(sleepMKS));
if ( checkTime() )
break;
}
if ( checkTime() )
break;
}
terminated = true;
terminated = true;
if(pValue != NULL)
*pValue ^= true;
if(pValue != NULL)
*pValue ^= true;
/*
if(pCall!=NULL)
{
pCall();
}
/*
if(pCall!=NULL)
{
pCall();
}
*/
/*
check = false;
pause();
check = true;
*/
stop();
// cout << "Timer: завершил поток..."<< endl;
*/
/*
check = false;
pause();
check = true;
*/
stop();
// cout << "Timer: завершил поток..."<< endl;
}
// ------------------------------------------------------------------------------------------
void WaitingPassiveTimer::terminate()
{
timeAct = 0;
terminated = true;
std::this_thread::sleep_for(std::chrono::microseconds(1));
timeAct = 0;
terminated = true;
std::this_thread::sleep_for(std::chrono::microseconds(1));
}
// ------------------------------------------------------------------------------------------
void WaitingPassiveTimer::wait(timeout_t timeMS)
{
if ( !terminated )
terminate();
if ( !terminated )
terminate();
setTiming(timeMS);
start((PosixThread*)this);
pthread_join(getTID(), NULL);
setTiming(timeMS);
start((PosixThread*)this);
pthread_join(getTID(), NULL);
}
// ------------------------------------------------------------------------------------------
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment