]> git.stg.codes - stg.git/blobdiff - projects/stargazer/stg_timer.cpp
Make time-sensitive tests in local machine time.
[stg.git] / projects / stargazer / stg_timer.cpp
index 7903c38d70dfd825b30672ed4ce447c92d629a1a..7a460ddfc89e68b710d9909d451c3c3d046c02ce 100644 (file)
@@ -1,15 +1,31 @@
-#include <unistd.h>
-#include <pthread.h>
+#include "stg_timer.h"
+
+#include "stg/common.h"
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <jthread.hpp>
+#pragma GCC diagnostic pop
 
+#include <ctime>
 #include <cstring>
+#include <csignal>
+
+#include <pthread.h>
+
+namespace
+{
+
+std::jthread thread;
+
+}
 
-#include "common.h"
+void * StgTimer(void *);
 
-static int nonstop;
-static pthread_t thrStgTimer;
 static bool isTimerRunning = false;
 volatile time_t stgTime;
 
+#ifdef STG_TIMER_DEBUG
 const int TIME_SPEED = 1;
 /*
  1  - 1x  speed
@@ -18,25 +34,27 @@ const int TIME_SPEED = 1;
  10 - 10x speed
  */
 
-const int START_TIME = 0;
+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 * StgTimer(void *)
+void timer(std::stop_token token)
 {
 #ifdef STG_TIMER_DEBUG
 struct tm lt;
 memset(&lt, 0, sizeof(lt));
 
-lt.tm_year = 2007 - 1900; // 2005
-lt.tm_mon  = 11 - 1;      // Nov
+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)
     {
@@ -50,49 +68,58 @@ switch (START_TIME)
         break;
 
     case 2:
-        lt.tm_mday = 30;
+        lt.tm_mday = 31;
         stgTime = mktime(&lt);
         break;
     }
+#else
+stgTime = time(NULL);
 #endif
 
-nonstop = 1;
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
 isTimerRunning = true;
-while (nonstop)
+while (!token.stop_requested())
     {
     #ifdef STG_TIMER_DEBUG
-    usleep(1000000 / TIME_SPEED);
+    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);
-    usleep(500000);
     #endif
     }
 isTimerRunning = false;
-
-return NULL;
 }
 //-----------------------------------------------------------------------------
 int RunStgTimer()
 {
-static int a = 0;
 isTimerRunning = false;
 
-if (a == 0)
-    if (pthread_create(&thrStgTimer, NULL, StgTimer, NULL))
-        {
-        isTimerRunning = false;
-        return -1;
-        }
+if (!thread.joinable())
+    thread = std::jthread(timer);
 
-a = 1;
 return 0;
 }
 //-----------------------------------------------------------------------------
 void StopStgTimer()
 {
-nonstop = 0;
-pthread_join(thrStgTimer, NULL); // Cleanup thread resources
+thread.request_stop();
+thread.join();
 printfd(__FILE__, "STG_TIMER stopped\n");
 }
 //-----------------------------------------------------------------------------
@@ -104,9 +131,11 @@ return isTimerRunning;
 int stgUsleep(unsigned long t)
 {
 #ifdef STG_TIMER_DEBUG
-return usleep(t / TIME_SPEED);
+struct timespec ts = {static_cast<time_t>((t / TIME_SPEED) / 1000000), static_cast<long>(((t / TIME_SPEED) % 1000000) * 1000)};
+return nanosleep(&ts, NULL);
 #else
-return usleep(t);
+struct timespec ts = {static_cast<time_t>(t / 1000000), static_cast<long>((t % 1000000) * 1000)};
+return nanosleep(&ts, NULL);
 #endif
 }
 //-----------------------------------------------------------------------------
@@ -116,5 +145,3 @@ void WaitTimer()
         stgUsleep(200000);
 }
 //-----------------------------------------------------------------------------
-
-