]> git.stg.codes - stg.git/blob - projects/stargazer/stg_timer.cpp
Make time-sensitive tests in local machine time.
[stg.git] / projects / stargazer / stg_timer.cpp
1 #include "stg_timer.h"
2
3 #include "stg/common.h"
4
5 #pragma GCC diagnostic push
6 #pragma GCC diagnostic ignored "-Wshadow"
7 #include <jthread.hpp>
8 #pragma GCC diagnostic pop
9
10 #include <ctime>
11 #include <cstring>
12 #include <csignal>
13
14 #include <pthread.h>
15
16 namespace
17 {
18
19 std::jthread thread;
20
21 }
22
23 void * StgTimer(void *);
24
25 static bool isTimerRunning = false;
26 volatile time_t stgTime;
27
28 #ifdef STG_TIMER_DEBUG
29 const int TIME_SPEED = 1;
30 /*
31  1  - 1x  speed
32  2  - 2x  speed
33  5  - 5x  speed
34  10 - 10x speed
35  */
36
37 const int START_TIME = 2;
38 /*
39  0 - as is
40  1 - start before new day (3 min before)   29.11.2005 23:57:00
41  2 - start before new month (3 min before) 30.11.2005 23:57:00
42  */
43 #endif
44
45 //-----------------------------------------------------------------------------
46 void timer(std::stop_token token)
47 {
48 #ifdef STG_TIMER_DEBUG
49 struct tm lt;
50 memset(&lt, 0, sizeof(lt));
51
52 lt.tm_year = 2016 - 1900; // 2005
53 lt.tm_mon  = 7 - 1;      // Nov
54 lt.tm_hour = 23;          // 23 h
55 lt.tm_min = 57;           // 50 min
56 lt.tm_sec = 0;            // 00 sec
57 lt.tm_isdst = -1;
58
59 switch (START_TIME)
60     {
61     case 0:
62         stgTime = time(NULL);
63         break;
64
65     case 1:
66         lt.tm_mday = 29;
67         stgTime = mktime(&lt);
68         break;
69
70     case 2:
71         lt.tm_mday = 31;
72         stgTime = mktime(&lt);
73         break;
74     }
75 #else
76 stgTime = time(NULL);
77 #endif
78
79 sigset_t signalSet;
80 sigfillset(&signalSet);
81 pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
82
83 isTimerRunning = true;
84 while (!token.stop_requested())
85     {
86     #ifdef STG_TIMER_DEBUG
87     struct timespec ts;
88     if (TIME_SPEED == 1)
89         {
90         ts.tv_sec = 1;
91         ts.tv_nsec = 0;
92         }
93     else
94         {
95         ts.tv_sec = 0;
96         ts.tv_nsec = 1000000000 / TIME_SPEED;
97         }
98     nanosleep(&ts, NULL);
99     stgTime++;
100     #else
101     struct timespec ts = {0, 500000000};
102     nanosleep(&ts, NULL);
103     stgTime = time(NULL);
104     #endif
105     }
106 isTimerRunning = false;
107 }
108 //-----------------------------------------------------------------------------
109 int RunStgTimer()
110 {
111 isTimerRunning = false;
112
113 if (!thread.joinable())
114     thread = std::jthread(timer);
115
116 return 0;
117 }
118 //-----------------------------------------------------------------------------
119 void StopStgTimer()
120 {
121 thread.request_stop();
122 thread.join();
123 printfd(__FILE__, "STG_TIMER stopped\n");
124 }
125 //-----------------------------------------------------------------------------
126 bool IsStgTimerRunning()
127 {
128 return isTimerRunning;
129 }
130 //-----------------------------------------------------------------------------
131 int stgUsleep(unsigned long t)
132 {
133 #ifdef STG_TIMER_DEBUG
134 struct timespec ts = {static_cast<time_t>((t / TIME_SPEED) / 1000000), static_cast<long>(((t / TIME_SPEED) % 1000000) * 1000)};
135 return nanosleep(&ts, NULL);
136 #else
137 struct timespec ts = {static_cast<time_t>(t / 1000000), static_cast<long>((t % 1000000) * 1000)};
138 return nanosleep(&ts, NULL);
139 #endif
140 }
141 //-----------------------------------------------------------------------------
142 void WaitTimer()
143 {
144     for (int i = 0; i < 5 && !isTimerRunning; i++)
145         stgUsleep(200000);
146 }
147 //-----------------------------------------------------------------------------