diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/mono_time.c | 97 | ||||
-rw-r--r-- | toxcore/mono_time.h | 4 | ||||
-rw-r--r-- | toxcore/mono_time_test.cc | 4 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 2 |
4 files changed, 54 insertions, 53 deletions
diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c index aa272749..6e4bc067 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c | |||
@@ -28,12 +28,52 @@ | |||
28 | struct Mono_Time { | 28 | struct Mono_Time { |
29 | uint64_t time; | 29 | uint64_t time; |
30 | uint64_t base_time; | 30 | uint64_t base_time; |
31 | #ifdef OS_WIN32 | ||
32 | uint64_t last_clock_mono; | ||
33 | uint64_t add_clock_mono; | ||
34 | #endif | ||
31 | 35 | ||
32 | mono_time_current_time_cb *current_time_callback; | 36 | mono_time_current_time_cb *current_time_callback; |
33 | void *user_data; | 37 | void *user_data; |
34 | }; | 38 | }; |
35 | 39 | ||
36 | static mono_time_current_time_cb current_time_monotonic_default; | 40 | static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_data) |
41 | { | ||
42 | uint64_t time; | ||
43 | #ifdef OS_WIN32 | ||
44 | uint64_t old_add_clock_mono = mono_time->add_clock_mono; | ||
45 | time = (uint64_t)GetTickCount() + mono_time->add_clock_mono; | ||
46 | |||
47 | /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race | ||
48 | * conditions when multiple threads call this function at once */ | ||
49 | if (time + 0x10000 < mono_time->last_clock_mono) { | ||
50 | uint32_t add = ~0; | ||
51 | /* use old_add_clock_mono rather than simply incrementing add_clock_mono, to handle the case that many threads | ||
52 | * simultaneously detect an overflow */ | ||
53 | mono_time->add_clock_mono = old_add_clock_mono + add; | ||
54 | time += add; | ||
55 | } | ||
56 | |||
57 | mono_time->last_clock_mono = time; | ||
58 | #else | ||
59 | struct timespec clock_mono; | ||
60 | #if defined(__APPLE__) | ||
61 | clock_serv_t muhclock; | ||
62 | mach_timespec_t machtime; | ||
63 | |||
64 | host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); | ||
65 | clock_get_time(muhclock, &machtime); | ||
66 | mach_port_deallocate(mach_task_self(), muhclock); | ||
67 | |||
68 | clock_mono.tv_sec = machtime.tv_sec; | ||
69 | clock_mono.tv_nsec = machtime.tv_nsec; | ||
70 | #else | ||
71 | clock_gettime(CLOCK_MONOTONIC, &clock_mono); | ||
72 | #endif | ||
73 | time = 1000ULL * clock_mono.tv_sec + (clock_mono.tv_nsec / 1000000ULL); | ||
74 | #endif | ||
75 | return time; | ||
76 | } | ||
37 | 77 | ||
38 | Mono_Time *mono_time_new(void) | 78 | Mono_Time *mono_time_new(void) |
39 | { | 79 | { |
@@ -46,6 +86,11 @@ Mono_Time *mono_time_new(void) | |||
46 | mono_time->current_time_callback = current_time_monotonic_default; | 86 | mono_time->current_time_callback = current_time_monotonic_default; |
47 | mono_time->user_data = nullptr; | 87 | mono_time->user_data = nullptr; |
48 | 88 | ||
89 | #ifdef OS_WIN32 | ||
90 | mono_time->last_clock_mono = 0; | ||
91 | mono_time->add_clock_mono = 0; | ||
92 | #endif | ||
93 | |||
49 | mono_time->time = 0; | 94 | mono_time->time = 0; |
50 | mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL); | 95 | mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL); |
51 | 96 | ||
@@ -87,53 +132,7 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time, | |||
87 | } | 132 | } |
88 | 133 | ||
89 | /* return current monotonic time in milliseconds (ms). */ | 134 | /* return current monotonic time in milliseconds (ms). */ |
90 | uint64_t current_time_monotonic(const Mono_Time *mono_time) | 135 | uint64_t current_time_monotonic(Mono_Time *mono_time) |
91 | { | 136 | { |
92 | return mono_time->current_time_callback(mono_time->user_data); | 137 | return mono_time->current_time_callback(mono_time, mono_time->user_data); |
93 | } | ||
94 | |||
95 | //!TOKSTYLE- | ||
96 | // No global mutable state in Tokstyle. | ||
97 | #ifdef OS_WIN32 | ||
98 | static uint64_t last_clock_mono; | ||
99 | static uint64_t add_clock_mono; | ||
100 | #endif | ||
101 | //!TOKSTYLE+ | ||
102 | |||
103 | static uint64_t current_time_monotonic_default(void *user_data) | ||
104 | { | ||
105 | uint64_t time; | ||
106 | #ifdef OS_WIN32 | ||
107 | uint64_t old_add_clock_mono = add_clock_mono; | ||
108 | time = (uint64_t)GetTickCount() + add_clock_mono; | ||
109 | |||
110 | /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race | ||
111 | * conditions when multiple threads call this function at once */ | ||
112 | if (time + 0x10000 < last_clock_mono) { | ||
113 | uint32_t add = ~0; | ||
114 | /* use old_add_clock_mono rather than simply incrementing add_clock_mono, to handle the case that many threads | ||
115 | * simultaneously detect an overflow */ | ||
116 | add_clock_mono = old_add_clock_mono + add; | ||
117 | time += add; | ||
118 | } | ||
119 | |||
120 | last_clock_mono = time; | ||
121 | #else | ||
122 | struct timespec clock_mono; | ||
123 | #if defined(__APPLE__) | ||
124 | clock_serv_t muhclock; | ||
125 | mach_timespec_t machtime; | ||
126 | |||
127 | host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); | ||
128 | clock_get_time(muhclock, &machtime); | ||
129 | mach_port_deallocate(mach_task_self(), muhclock); | ||
130 | |||
131 | clock_mono.tv_sec = machtime.tv_sec; | ||
132 | clock_mono.tv_nsec = machtime.tv_nsec; | ||
133 | #else | ||
134 | clock_gettime(CLOCK_MONOTONIC, &clock_mono); | ||
135 | #endif | ||
136 | time = 1000ULL * clock_mono.tv_sec + (clock_mono.tv_nsec / 1000000ULL); | ||
137 | #endif | ||
138 | return time; | ||
139 | } | 138 | } |
diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h index b735f2c3..c2934d06 100644 --- a/toxcore/mono_time.h +++ b/toxcore/mono_time.h | |||
@@ -50,9 +50,9 @@ uint64_t mono_time_get(const Mono_Time *mono_time); | |||
50 | bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout); | 50 | bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout); |
51 | 51 | ||
52 | /* return current monotonic time in milliseconds (ms). */ | 52 | /* return current monotonic time in milliseconds (ms). */ |
53 | uint64_t current_time_monotonic(const Mono_Time *mono_time); | 53 | uint64_t current_time_monotonic(Mono_Time *mono_time); |
54 | 54 | ||
55 | typedef uint64_t mono_time_current_time_cb(void *user_data); | 55 | typedef uint64_t mono_time_current_time_cb(Mono_Time *mono_time, void *user_data); |
56 | 56 | ||
57 | /* Override implementation of current_time_monotonic() (for tests). | 57 | /* Override implementation of current_time_monotonic() (for tests). |
58 | * | 58 | * |
diff --git a/toxcore/mono_time_test.cc b/toxcore/mono_time_test.cc index 6e81ac7e..3b33a241 100644 --- a/toxcore/mono_time_test.cc +++ b/toxcore/mono_time_test.cc | |||
@@ -35,7 +35,9 @@ TEST(MonoTime, IsTimeout) { | |||
35 | mono_time_free(mono_time); | 35 | mono_time_free(mono_time); |
36 | } | 36 | } |
37 | 37 | ||
38 | static uint64_t test_current_time_callback(void *user_data) { return *(uint64_t *)user_data; } | 38 | uint64_t test_current_time_callback(Mono_Time *mono_time, void *user_data) { |
39 | return *(uint64_t *)user_data; | ||
40 | } | ||
39 | 41 | ||
40 | TEST(MonoTime, CustomTime) { | 42 | TEST(MonoTime, CustomTime) { |
41 | Mono_Time *mono_time = mono_time_new(); | 43 | Mono_Time *mono_time = mono_time_new(); |
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index a64ed970..736b9c4a 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -972,7 +972,7 @@ static int generate_request_packet(const Logger *log, uint8_t *data, uint16_t le | |||
972 | * return -1 on failure. | 972 | * return -1 on failure. |
973 | * return number of requested packets on success. | 973 | * return number of requested packets on success. |
974 | */ | 974 | */ |
975 | static int handle_request_packet(const Mono_Time *mono_time, const Logger *log, Packets_Array *send_array, | 975 | static int handle_request_packet(Mono_Time *mono_time, const Logger *log, Packets_Array *send_array, |
976 | const uint8_t *data, uint16_t length, uint64_t *latest_send_time, uint64_t rtt_time) | 976 | const uint8_t *data, uint16_t length, uint64_t *latest_send_time, uint64_t rtt_time) |
977 | { | 977 | { |
978 | if (length == 0) { | 978 | if (length == 0) { |