summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox/src/toxcore/mono_time.c
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-07-24 16:44:24 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-07-24 16:44:24 +0300
commite55d071e5485a937efd427d159b76c208cccdcce (patch)
tree48d09dc5cf1df2581fd6471b5ccf1560015fa3a4 /protocols/Tox/libtox/src/toxcore/mono_time.c
parentf36629f67153bc500c828cf51de31988122a1024 (diff)
fixes #3118 (Update toxcore to 0.2.18)
Diffstat (limited to 'protocols/Tox/libtox/src/toxcore/mono_time.c')
-rw-r--r--protocols/Tox/libtox/src/toxcore/mono_time.c114
1 files changed, 67 insertions, 47 deletions
diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.c b/protocols/Tox/libtox/src/toxcore/mono_time.c
index e207996df6..df64f2246c 100644
--- a/protocols/Tox/libtox/src/toxcore/mono_time.c
+++ b/protocols/Tox/libtox/src/toxcore/mono_time.c
@@ -26,21 +26,16 @@
#include <sys/time.h>
#endif
+#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include "ccompat.h"
-//!TOKSTYLE-
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-#include "../testing/fuzzing/fuzz_adapter.h"
-#endif
-//!TOKSTYLE+
-
/** don't call into system billions of times for no reason */
struct Mono_Time {
- uint64_t time;
+ uint64_t cur_time;
uint64_t base_time;
#ifdef OS_WIN32
/* protect `last_clock_update` and `last_clock_mono` from concurrent access */
@@ -49,27 +44,31 @@ struct Mono_Time {
bool last_clock_update;
#endif
+#ifndef ESP_PLATFORM
/* protect `time` from concurrent access */
pthread_rwlock_t *time_update_lock;
+#endif
mono_time_current_time_cb *current_time_callback;
void *user_data;
};
-static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_data)
-{
- uint64_t time = 0;
#ifdef OS_WIN32
+non_null()
+static uint64_t current_time_monotonic_default(void *user_data)
+{
+ Mono_Time *const mono_time = (Mono_Time *)user_data;
+
/* Must hold mono_time->last_clock_lock here */
/* GetTickCount provides only a 32 bit counter, but we can't use
* GetTickCount64 for backwards compatibility, so we handle wraparound
* ourselves.
*/
- uint32_t ticks = GetTickCount();
+ const uint32_t ticks = GetTickCount();
/* the higher 32 bits count the number of wrap arounds */
- uint64_t old_ovf = mono_time->time & ~((uint64_t)UINT32_MAX);
+ uint64_t old_ovf = mono_time->cur_time & ~((uint64_t)UINT32_MAX);
/* Check if time has decreased because of 32 bit wrap from GetTickCount() */
if (ticks < mono_time->last_clock_mono) {
@@ -83,10 +82,18 @@ static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_
}
/* splice the low and high bits back together */
- time = old_ovf + ticks;
-#else
+ return old_ovf + ticks;
+}
+#else // !OS_WIN32
+static uint64_t timespec_to_u64(struct timespec clock_mono)
+{
+ return 1000ULL * clock_mono.tv_sec + (clock_mono.tv_nsec / 1000000ULL);
+}
+#ifdef __APPLE__
+non_null()
+static uint64_t current_time_monotonic_default(void *user_data)
+{
struct timespec clock_mono;
-#if defined(__APPLE__)
clock_serv_t muhclock;
mach_timespec_t machtime;
@@ -96,23 +103,26 @@ static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_
clock_mono.tv_sec = machtime.tv_sec;
clock_mono.tv_nsec = machtime.tv_nsec;
-#else
- clock_gettime(CLOCK_MONOTONIC, &clock_mono);
-#endif
- time = 1000ULL * clock_mono.tv_sec + (clock_mono.tv_nsec / 1000000ULL);
-#endif
- return time;
+ return timespec_to_u64(clock_mono);
}
-
-
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-static uint64_t current_time_monotonic_dummy(Mono_Time *mono_time, void *user_data)
+#else // !__APPLE__
+non_null()
+static uint64_t current_time_monotonic_default(void *user_data)
{
- return fuzz_get_count();
-}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ // This assert should always fail. If it does, the fuzzing harness didn't
+ // override the mono time callback.
+ assert(user_data == nullptr);
#endif
+ struct timespec clock_mono;
+ clock_gettime(CLOCK_MONOTONIC, &clock_mono);
+ return timespec_to_u64(clock_mono);
+}
+#endif // !__APPLE__
+#endif // !OS_WIN32
+
-Mono_Time *mono_time_new(void)
+Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void *user_data)
{
Mono_Time *mono_time = (Mono_Time *)calloc(1, sizeof(Mono_Time));
@@ -120,6 +130,7 @@ Mono_Time *mono_time_new(void)
return nullptr;
}
+#ifndef ESP_PLATFORM
mono_time->time_update_lock = (pthread_rwlock_t *)calloc(1, sizeof(pthread_rwlock_t));
if (mono_time->time_update_lock == nullptr) {
@@ -132,13 +143,9 @@ Mono_Time *mono_time_new(void)
free(mono_time);
return nullptr;
}
-
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
- mono_time->current_time_callback = current_time_monotonic_dummy;
-#else
- mono_time->current_time_callback = current_time_monotonic_default;
#endif
- mono_time->user_data = nullptr;
+
+ mono_time_set_current_time_callback(mono_time, current_time_callback, user_data);
#ifdef OS_WIN32
@@ -153,9 +160,10 @@ Mono_Time *mono_time_new(void)
#endif
- mono_time->time = 0;
+ mono_time->cur_time = 0;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
- mono_time->base_time = 0; // Maximum reproducibility
+ // Maximum reproducibility. Never return time = 0.
+ mono_time->base_time = 1;
#else
mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL);
#endif
@@ -167,44 +175,56 @@ Mono_Time *mono_time_new(void)
void mono_time_free(Mono_Time *mono_time)
{
+ if (mono_time == nullptr) {
+ return;
+ }
#ifdef OS_WIN32
pthread_mutex_destroy(&mono_time->last_clock_lock);
#endif
+#ifndef ESP_PLATFORM
pthread_rwlock_destroy(mono_time->time_update_lock);
free(mono_time->time_update_lock);
+#endif
free(mono_time);
}
void mono_time_update(Mono_Time *mono_time)
{
- uint64_t time = 0;
+ uint64_t cur_time = 0;
#ifdef OS_WIN32
/* we actually want to update the overflow state of mono_time here */
pthread_mutex_lock(&mono_time->last_clock_lock);
mono_time->last_clock_update = true;
#endif
- time = mono_time->current_time_callback(mono_time, mono_time->user_data) / 1000ULL;
- time += mono_time->base_time;
+ cur_time = mono_time->current_time_callback(mono_time->user_data) / 1000ULL;
+ cur_time += mono_time->base_time;
#ifdef OS_WIN32
pthread_mutex_unlock(&mono_time->last_clock_lock);
#endif
+#ifndef ESP_PLATFORM
pthread_rwlock_wrlock(mono_time->time_update_lock);
- mono_time->time = time;
+#endif
+ mono_time->cur_time = cur_time;
+#ifndef ESP_PLATFORM
pthread_rwlock_unlock(mono_time->time_update_lock);
+#endif
}
uint64_t mono_time_get(const Mono_Time *mono_time)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// Fuzzing is only single thread for now, no locking needed */
- return mono_time->time;
+ return mono_time->cur_time;
#else
- uint64_t time = 0;
+#ifndef ESP_PLATFORM
pthread_rwlock_rdlock(mono_time->time_update_lock);
- time = mono_time->time;
+#endif
+ const uint64_t cur_time = mono_time->cur_time;
+#ifndef ESP_PLATFORM
pthread_rwlock_unlock(mono_time->time_update_lock);
- return time;
+#endif
+ return cur_time;
#endif
}
@@ -218,7 +238,7 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time,
{
if (current_time_callback == nullptr) {
mono_time->current_time_callback = current_time_monotonic_default;
- mono_time->user_data = nullptr;
+ mono_time->user_data = mono_time;
} else {
mono_time->current_time_callback = current_time_callback;
mono_time->user_data = user_data;
@@ -237,9 +257,9 @@ uint64_t current_time_monotonic(Mono_Time *mono_time)
* but must protect against other threads */
pthread_mutex_lock(&mono_time->last_clock_lock);
#endif
- uint64_t time = mono_time->current_time_callback(mono_time, mono_time->user_data);
+ const uint64_t cur_time = mono_time->current_time_callback(mono_time->user_data);
#ifdef OS_WIN32
pthread_mutex_unlock(&mono_time->last_clock_lock);
#endif
- return time;
+ return cur_time;
}