BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file BTime.h
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * @section DESCRIPTION
30 *
31 * System time abstraction used by {@link BReactor}.
32 */
33  
34 #ifndef BADVPN_SYSTEM_BTIME_H
35 #define BADVPN_SYSTEM_BTIME_H
36  
37 #if defined(BADVPN_USE_WINAPI)
38 #include <windows.h>
39 #elif defined(BADVPN_EMSCRIPTEN)
40 #include <emscripten/emscripten.h>
41 #else
42 #include <time.h>
43 #include <sys/time.h>
44 #endif
45  
46 #include <stdint.h>
47  
48 #include <misc/debug.h>
49 #include <misc/overflow.h>
50 #include <base/BLog.h>
51  
52 #include <generated/blog_channel_BTime.h>
53  
54 typedef int64_t btime_t;
55  
56 #define BTIME_MIN INT64_MIN
57  
58 struct _BTime_global {
59 #ifndef NDEBUG
60 int initialized; // initialized statically
61 #endif
62 #if defined(BADVPN_USE_WINAPI)
63 LARGE_INTEGER start_time;
64 #elif defined(BADVPN_EMSCRIPTEN)
65 btime_t start_time;
66 #else
67 btime_t start_time;
68 int use_gettimeofday;
69 #endif
70 };
71  
72 extern struct _BTime_global btime_global;
73  
74 static void BTime_Init (void)
75 {
76 ASSERT(!btime_global.initialized)
77  
78 #if defined(BADVPN_USE_WINAPI)
79  
80 ASSERT_FORCE(QueryPerformanceCounter(&btime_global.start_time))
81  
82 #elif defined(BADVPN_EMSCRIPTEN)
83  
84 btime_global.start_time = emscripten_get_now();
85  
86 #else
87  
88 struct timespec ts;
89 if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
90 BLog(BLOG_WARNING, "CLOCK_MONOTONIC is not available. Timers will be confused by clock changes.");
91  
92 struct timeval tv;
93 ASSERT_FORCE(gettimeofday(&tv, NULL) == 0)
94  
95 btime_global.start_time = (int64_t)tv.tv_sec * 1000 + (int64_t)tv.tv_usec/1000;
96 btime_global.use_gettimeofday = 1;
97 } else {
98 btime_global.start_time = (int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec/1000000;
99 btime_global.use_gettimeofday = 0;
100 }
101  
102 #endif
103  
104 #ifndef NDEBUG
105 btime_global.initialized = 1;
106 #endif
107 }
108  
109 static btime_t btime_gettime (void)
110 {
111 ASSERT(btime_global.initialized)
112  
113 #if defined(BADVPN_USE_WINAPI)
114  
115 LARGE_INTEGER count;
116 LARGE_INTEGER freq;
117 ASSERT_FORCE(QueryPerformanceCounter(&count))
118 ASSERT_FORCE(QueryPerformanceFrequency(&freq))
119 return (((count.QuadPart - btime_global.start_time.QuadPart) * 1000) / freq.QuadPart);
120  
121 #elif defined(BADVPN_EMSCRIPTEN)
122  
123 return (btime_t)emscripten_get_now() - btime_global.start_time;
124  
125 #else
126  
127 if (btime_global.use_gettimeofday) {
128 struct timeval tv;
129 ASSERT_FORCE(gettimeofday(&tv, NULL) == 0)
130 return ((int64_t)tv.tv_sec * 1000 + (int64_t)tv.tv_usec/1000);
131 } else {
132 struct timespec ts;
133 ASSERT_FORCE(clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
134 return (((int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec/1000000) - btime_global.start_time);
135 }
136  
137 #endif
138 }
139  
140 static btime_t btime_add (btime_t t1, btime_t t2)
141 {
142 // handle overflow
143 int overflows = add_int64_overflows(t1, t2);
144 btime_t sum;
145 if (overflows != 0) {
146 if (overflows > 0) {
147 sum = INT64_MAX;
148 } else {
149 sum = INT64_MIN;
150 }
151 } else {
152 sum = t1 + t2;
153 }
154  
155 return sum;
156 }
157  
158 static btime_t btime_getpast (void)
159 {
160 return INT64_MIN;
161 }
162  
163 #endif