#include "stg_timer.h" #include "stg/common.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" #include #pragma GCC diagnostic pop #include #include #include #include namespace { std::jthread thread; } void * StgTimer(void *); static bool isTimerRunning = false; volatile time_t stgTime; #ifdef STG_TIMER_DEBUG const int TIME_SPEED = 1; /* 1 - 1x speed 2 - 2x speed 5 - 5x speed 10 - 10x speed */ const int START_TIME = 2; /* 0 - as is 1 - start before new day (3 min before) 29.11.2005 23:57:00 2 - start before new month (3 min before) 30.11.2005 23:57:00 */ #endif //----------------------------------------------------------------------------- void timer(std::stop_token token) { #ifdef STG_TIMER_DEBUG struct tm lt; memset(<, 0, sizeof(lt)); lt.tm_year = 2016 - 1900; // 2005 lt.tm_mon = 7 - 1; // Nov lt.tm_hour = 23; // 23 h lt.tm_min = 57; // 50 min lt.tm_sec = 0; // 00 sec lt.tm_isdst = -1; switch (START_TIME) { case 0: stgTime = time(NULL); break; case 1: lt.tm_mday = 29; stgTime = mktime(<); break; case 2: lt.tm_mday = 31; stgTime = mktime(<); break; } #else stgTime = time(NULL); #endif sigset_t signalSet; sigfillset(&signalSet); pthread_sigmask(SIG_BLOCK, &signalSet, NULL); isTimerRunning = true; while (!token.stop_requested()) { #ifdef STG_TIMER_DEBUG struct timespec ts; if (TIME_SPEED == 1) { ts.tv_sec = 1; ts.tv_nsec = 0; } else { ts.tv_sec = 0; ts.tv_nsec = 1000000000 / TIME_SPEED; } nanosleep(&ts, NULL); stgTime++; #else struct timespec ts = {0, 500000000}; nanosleep(&ts, NULL); stgTime = time(NULL); #endif } isTimerRunning = false; } //----------------------------------------------------------------------------- int RunStgTimer() { isTimerRunning = false; if (!thread.joinable()) thread = std::jthread(timer); return 0; } //----------------------------------------------------------------------------- void StopStgTimer() { thread.request_stop(); thread.join(); printfd(__FILE__, "STG_TIMER stopped\n"); } //----------------------------------------------------------------------------- bool IsStgTimerRunning() { return isTimerRunning; } //----------------------------------------------------------------------------- int stgUsleep(unsigned long t) { #ifdef STG_TIMER_DEBUG struct timespec ts = {static_cast((t / TIME_SPEED) / 1000000), static_cast(((t / TIME_SPEED) % 1000000) * 1000)}; return nanosleep(&ts, NULL); #else struct timespec ts = {static_cast(t / 1000000), static_cast((t % 1000000) * 1000)}; return nanosleep(&ts, NULL); #endif } //----------------------------------------------------------------------------- void WaitTimer() { for (int i = 0; i < 5 && !isTimerRunning; i++) stgUsleep(200000); } //-----------------------------------------------------------------------------