From d51ec3cbfb68fa4feb2e169d193541ee6c2a5399 Mon Sep 17 00:00:00 2001 From: iphydf Date: Sat, 7 Jul 2018 22:15:08 +0000 Subject: [PATCH 1/2] Add a thread-safe version of unix_time and friends. These are not used in a thread-safe way, but it opens the path towards per-tox-instance time keeping and removal of some unsafe global state. --- toxcore/util.c | 59 ++++++++++++++++++++++++++++++++++++++++---------- toxcore/util.h | 12 +++++++++- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/toxcore/util.c b/toxcore/util.c index 57d1762ee4e..eb5c63bf009 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -36,33 +36,70 @@ #include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ #include "network.h" /* for current_time_monotonic */ +#include #include #include /* don't call into system billions of times for no reason */ -static uint64_t unix_time_value; -static uint64_t unix_base_time_value; +struct Unix_Time { + uint64_t time; + uint64_t base_time; +}; -/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of - * unix_time() may fail to increase monotonically with increasing time */ -void unix_time_update(void) +Unix_Time *unix_time_new(void) { - if (unix_base_time_value == 0) { - unix_base_time_value = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + Unix_Time *unixtime = (Unix_Time *)malloc(sizeof(Unix_Time)); + + if (unixtime == nullptr) { + return nullptr; } - unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value; + unixtime->time = 0; + unixtime->base_time = 0; + + return unixtime; } -uint64_t unix_time(void) +void unix_time_free(Unix_Time *unixtime) +{ + free(unixtime); +} + +void unix_time_update_r(Unix_Time *unixtime) +{ + if (unixtime->base_time == 0) { + unixtime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + } + + unixtime->time = (current_time_monotonic() / 1000ULL) + unixtime->base_time; +} + +uint64_t unix_time_get(const Unix_Time *unixtime) +{ + return unixtime->time; +} + +int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout) { - return unix_time_value; + return timestamp + timeout <= unix_time_get(unixtime); } +static Unix_Time global_time; + +/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of + * unix_time() may fail to increase monotonically with increasing time */ +void unix_time_update(void) +{ + unix_time_update_r(&global_time); +} +uint64_t unix_time(void) +{ + return unix_time_get(&global_time); +} int is_timeout(uint64_t timestamp, uint64_t timeout) { - return timestamp + timeout <= unix_time(); + return unix_time_is_timeout(&global_time, timestamp, timeout); } diff --git a/toxcore/util.h b/toxcore/util.h index 3979cefee01..cc1cffda34b 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -39,11 +39,21 @@ extern "C" { #define MIN(a,b) (((a)<(b))?(a):(b)) #define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } +typedef struct Unix_Time Unix_Time; + +Unix_Time *unix_time_new(void); +void unix_time_free(Unix_Time *unixtime); + +// TODO(#980): Use per-tox unixtime, remove unix_time_update, and rename +// unix_time_update_r to unix_time_update. +void unix_time_update_r(Unix_Time *unixtime); +uint64_t unix_time_get(const Unix_Time *unixtime); +int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout); + void unix_time_update(void); uint64_t unix_time(void); int is_timeout(uint64_t timestamp, uint64_t timeout); - /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src); uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */ From 324b25f02fd11a7f6b4231777c4153dc568a52df Mon Sep 17 00:00:00 2001 From: iphydf Date: Sun, 8 Jul 2018 08:43:42 +0000 Subject: [PATCH 2/2] Factor out time keeping code into its own module: mono_time.c. It turns out, `unix_time` is also monotonic, and is used as such, so I've renamed the new functions to `mono_time_*`. 2018-07-08: ``` 00:01 <@irungentoo> the idea used to be that the unix_time() function could go backward in time but I think I might have started using it like if it could not after I changed it so that it would never go back in time ``` --- .travis.yml | 12 +- CMakeLists.txt | 3 + auto_tests/TCP_test.c | 1 + auto_tests/onion_test.c | 1 + other/DHT_bootstrap.c | 1 + other/bootstrap_daemon/src/tox-bootstrapd.c | 1 + other/monolith.h | 1 + testing/av_test.c | 2 +- toxav/audio.c | 1 + toxav/bwcontroller.c | 1 + toxav/groupav.c | 1 + toxav/rtp.c | 1 + toxav/toxav.c | 1 + toxav/video.c | 1 + toxcore/BUILD.bazel | 17 +++ toxcore/DHT.c | 1 + toxcore/Messenger.c | 1 + toxcore/TCP_client.c | 1 + toxcore/TCP_connection.c | 1 + toxcore/TCP_server.c | 1 + toxcore/friend_connection.c | 1 + toxcore/group.c | 1 + toxcore/mono_time.c | 154 ++++++++++++++++++++ toxcore/mono_time.h | 35 +++++ toxcore/mono_time_test.cc | 30 ++++ toxcore/net_crypto.c | 1 + toxcore/network.c | 69 +-------- toxcore/network.h | 3 - toxcore/onion.c | 1 + toxcore/onion_announce.c | 1 + toxcore/onion_client.c | 1 + toxcore/ping.c | 1 + toxcore/ping_array.c | 1 + toxcore/util.c | 63 -------- toxcore/util.h | 15 -- toxcore/util_test.cc | 25 +--- 36 files changed, 274 insertions(+), 178 deletions(-) create mode 100644 toxcore/mono_time.c create mode 100644 toxcore/mono_time.h create mode 100644 toxcore/mono_time_test.cc diff --git a/.travis.yml b/.travis.yml index 416aecc7be0..f35e54baeba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,36 +38,36 @@ matrix: install: .travis/$JOB install script: .travis/$JOB script - stage: "Stage 1" - if: type IN (push, api, cron) +# if: type IN (push, api, cron) env: JOB=cmake-win32 services: [docker] install: .travis/$JOB install script: .travis/$JOB script - stage: "Stage 1" - if: type IN (push, api, cron) +# if: type IN (push, api, cron) env: JOB=cmake-win64 services: [docker] install: .travis/$JOB install script: .travis/$JOB script - stage: "Stage 1" - if: type IN (push, api, cron) +# if: type IN (push, api, cron) env: JOB=cmake-freebsd sudo: required install: .travis/$JOB-stage1 install script: .travis/$JOB-stage1 script - stage: "Stage 1" - if: type IN (push, api, cron) +# if: type IN (push, api, cron) env: JOB=tox-bootstrapd-docker services: [docker] script: .travis/$JOB - stage: "Stage 2" - if: type IN (push, api, cron) +# if: type IN (push, api, cron) env: JOB=cmake-freebsd sudo: required install: .travis/$JOB-stage2 install script: .travis/$JOB-stage2 script - stage: "Stage 2" - if: type IN (push, api, cron) +# if: type IN (push, api, cron) env: JOB=cmake-osx os: osx install: .travis/$JOB install diff --git a/CMakeLists.txt b/CMakeLists.txt index 502a617284f..b989723d9e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,6 +171,8 @@ set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} libsodium) set(toxcore_SOURCES ${toxcore_SOURCES} toxcore/logger.c toxcore/logger.h + toxcore/mono_time.c + toxcore/mono_time.h toxcore/network.c toxcore/network.h toxcore/util.c @@ -341,6 +343,7 @@ include(CompileGTest) unit_test(toxav ring_buffer) unit_test(toxav rtp) unit_test(toxcore crypto_core) +unit_test(toxcore mono_time) unit_test(toxcore util) ################################################################################ diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 134bdf9bb41..f5bc247126a 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -18,6 +18,7 @@ #include "../toxcore/TCP_server.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/mono_time.h" #include "../toxcore/util.h" #include "helpers.h" diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index a4f20cba0b5..45679205e23 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -14,6 +14,7 @@ #include #include +#include "../toxcore/mono_time.h" #include "../toxcore/onion.h" #include "../toxcore/onion_announce.h" #include "../toxcore/onion_client.h" diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index f263b47172e..b71ab0b192b 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -33,6 +33,7 @@ #include "../toxcore/LAN_discovery.h" #include "../toxcore/friend_requests.h" #include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index 3c6d5d2c98b..fd05f8a2fdf 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -38,6 +38,7 @@ #include "../../../toxcore/LAN_discovery.h" #include "../../../toxcore/TCP_server.h" #include "../../../toxcore/logger.h" +#include "../../../toxcore/mono_time.h" #include "../../../toxcore/onion_announce.h" #include "../../../toxcore/util.h" diff --git a/other/monolith.h b/other/monolith.h index 42b6b6be967..10769b813bf 100644 --- a/other/monolith.h +++ b/other/monolith.h @@ -13,6 +13,7 @@ #include "../toxcore/group.c" #include "../toxcore/list.c" #include "../toxcore/logger.c" +#include "../toxcore/mono_time.c" #include "../toxcore/network.c" #include "../toxcore/net_crypto.c" #include "../toxcore/onion.c" diff --git a/testing/av_test.c b/testing/av_test.c index 5cc3b5dd554..87a01871570 100644 --- a/testing/av_test.c +++ b/testing/av_test.c @@ -45,7 +45,7 @@ extern "C" { #include "../toxav/ring_buffer.c" #include "../toxav/toxav.h" -#include "../toxcore/network.h" /* current_time_monotonic() */ +#include "../toxcore/mono_time.h" /* current_time_monotonic() */ #include "../toxcore/tox.h" #include "../toxcore/util.h" diff --git a/toxav/audio.c b/toxav/audio.c index 3b46d1d5909..2995717f905 100644 --- a/toxav/audio.c +++ b/toxav/audio.c @@ -29,6 +29,7 @@ #include "rtp.h" #include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" static struct JitterBuffer *jbuf_new(uint32_t capacity); static void jbuf_clear(struct JitterBuffer *q); diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c index 2d7dd65910c..05fac70402b 100644 --- a/toxav/bwcontroller.c +++ b/toxav/bwcontroller.c @@ -31,6 +31,7 @@ #include "ring_buffer.h" #include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" #include "../toxcore/util.h" #define BWC_PACKET_ID 196 diff --git a/toxav/groupav.c b/toxav/groupav.c index 8772838e539..1af27b4e069 100644 --- a/toxav/groupav.c +++ b/toxav/groupav.c @@ -27,6 +27,7 @@ #include #include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" #include "../toxcore/util.h" #define GROUP_JBUF_SIZE 6 diff --git a/toxav/rtp.c b/toxav/rtp.c index 1e178720578..3d563a1f241 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -32,6 +32,7 @@ #include "../toxcore/Messenger.h" #include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" #include "../toxcore/util.h" enum { diff --git a/toxav/toxav.c b/toxav/toxav.c index 36bf9cc296f..5abe1130904 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -28,6 +28,7 @@ #include "../toxcore/Messenger.h" #include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" #include "../toxcore/util.h" #include diff --git a/toxav/video.c b/toxav/video.c index 1126b8e6080..5145c29ceab 100644 --- a/toxav/video.c +++ b/toxav/video.c @@ -32,6 +32,7 @@ #include "rtp.h" #include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" #include "../toxcore/network.h" /** diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 1d43d828269..a5bef89ded6 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -51,6 +51,22 @@ cc_library( deps = [":ccompat"], ) +cc_library( + name = "mono_time", + srcs = ["mono_time.c"], + hdrs = ["mono_time.h"], + deps = [":ccompat"], +) + +cc_test( + name = "mono_time_test", + srcs = ["mono_time_test.cc"], + deps = [ + ":mono_time", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "network", srcs = [ @@ -70,6 +86,7 @@ cc_library( ":ccompat", ":crypto_core", ":logger", + ":mono_time", ], ) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 6c104a731fa..fc657e8f0b2 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -29,6 +29,7 @@ #include "LAN_discovery.h" #include "logger.h" +#include "mono_time.h" #include "network.h" #include "ping.h" #include "util.h" diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index b8509706ea0..6d467045f5c 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -34,6 +34,7 @@ #include #include "logger.h" +#include "mono_time.h" #include "network.h" #include "util.h" diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index d1cd4d66166..1291d2763b4 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -31,6 +31,7 @@ #include #include +#include "mono_time.h" #include "util.h" struct TCP_Client_Connection { diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index 06cb6e344c7..cd1fb5658d5 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c @@ -31,6 +31,7 @@ #include #include +#include "mono_time.h" #include "util.h" diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 65dc81c3366..5cc725718f5 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -39,6 +39,7 @@ #include #endif +#include "mono_time.h" #include "util.h" typedef struct TCP_Secure_Connection { diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index 62f76b22f53..440570030ba 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c @@ -31,6 +31,7 @@ #include #include +#include "mono_time.h" #include "util.h" #define PORTS_PER_DISCOVERY 10 diff --git a/toxcore/group.c b/toxcore/group.c index b7042f2feff..4942d8723fb 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -30,6 +30,7 @@ #include #include +#include "mono_time.h" #include "util.h" /* return 1 if the groupnumber is not valid. diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c new file mode 100644 index 00000000000..d0b435642e9 --- /dev/null +++ b/toxcore/mono_time.c @@ -0,0 +1,154 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 +#endif + +#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +#define OS_WIN32 +#endif + +#ifdef __APPLE__ +#include +#endif + +#if !defined(OS_WIN32) && !defined(__APPLE__) +#include +#include +#endif + +#include "mono_time.h" + +#include + +#include "ccompat.h" + +/* don't call into system billions of times for no reason */ +struct Mono_Time { + uint64_t time; + uint64_t base_time; +}; + +Mono_Time *mono_time_new(void) +{ + Mono_Time *monotime = (Mono_Time *)malloc(sizeof(Mono_Time)); + + if (monotime == nullptr) { + return nullptr; + } + + monotime->time = 0; + monotime->base_time = 0; + + return monotime; +} + +void mono_time_free(Mono_Time *monotime) +{ + free(monotime); +} + +void mono_time_update(Mono_Time *monotime) +{ + if (monotime->base_time == 0) { + monotime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); + } + + monotime->time = (current_time_monotonic() / 1000ULL) + monotime->base_time; +} + +uint64_t mono_time_get(const Mono_Time *monotime) +{ + return monotime->time; +} + +bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout) +{ + return timestamp + timeout <= mono_time_get(monotime); +} + + +static Mono_Time global_time; + +/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of + * unix_time() may fail to increase monotonically with increasing time */ +void unix_time_update(void) +{ + mono_time_update(&global_time); +} +uint64_t unix_time(void) +{ + return mono_time_get(&global_time); +} +int is_timeout(uint64_t timestamp, uint64_t timeout) +{ + return mono_time_is_timeout(&global_time, timestamp, timeout); +} + + + +/* return current UNIX time in microseconds (us). */ +uint64_t current_time_actual(void) +{ + uint64_t time; +#ifdef OS_WIN32 + /* This probably works fine */ + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + time = ft.dwHighDateTime; + time <<= 32; + time |= ft.dwLowDateTime; + time -= 116444736000000000ULL; + return time / 10; +#else + struct timeval a; + gettimeofday(&a, nullptr); + time = 1000000ULL * a.tv_sec + a.tv_usec; + return time; +#endif +} + + +#ifdef OS_WIN32 +static uint64_t last_monotime; +static uint64_t add_monotime; +#endif + +/* return current monotonic time in milliseconds (ms). */ +uint64_t current_time_monotonic(void) +{ + uint64_t time; +#ifdef OS_WIN32 + uint64_t old_add_monotime = add_monotime; + time = (uint64_t)GetTickCount() + add_monotime; + + /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race + * conditions when multiple threads call this function at once */ + if (time + 0x10000 < last_monotime) { + uint32_t add = ~0; + /* use old_add_monotime rather than simply incrementing add_monotime, to handle the case that many threads + * simultaneously detect an overflow */ + add_monotime = old_add_monotime + add; + time += add; + } + + last_monotime = time; +#else + struct timespec monotime; +#if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW) + clock_gettime(CLOCK_MONOTONIC_RAW, &monotime); +#elif defined(__APPLE__) + clock_serv_t muhclock; + mach_timespec_t machtime; + + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); + clock_get_time(muhclock, &machtime); + mach_port_deallocate(mach_task_self(), muhclock); + + monotime.tv_sec = machtime.tv_sec; + monotime.tv_nsec = machtime.tv_nsec; +#else + clock_gettime(CLOCK_MONOTONIC, &monotime); +#endif + time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL); +#endif + return time; +} diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h new file mode 100644 index 00000000000..55adedcdfd6 --- /dev/null +++ b/toxcore/mono_time.h @@ -0,0 +1,35 @@ +#ifndef C_TOXCORE_TOXCORE_MONO_TIME_H +#define C_TOXCORE_TOXCORE_MONO_TIME_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Mono_Time Mono_Time; + +Mono_Time *mono_time_new(void); +void mono_time_free(Mono_Time *monotime); + +void mono_time_update(Mono_Time *monotime); +uint64_t mono_time_get(const Mono_Time *monotime); +bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout); + +// TODO(#980): Use per-tox monotime, delete these functions. +void unix_time_update(void); +uint64_t unix_time(void); +int is_timeout(uint64_t timestamp, uint64_t timeout); + +/* return current UNIX time in microseconds (us). */ +uint64_t current_time_actual(void); + +/* return current monotonic time in milliseconds (ms). */ +uint64_t current_time_monotonic(void); + +#ifdef __cplusplus +} +#endif + +#endif // C_TOXCORE_TOXCORE_MONO_TIME_H diff --git a/toxcore/mono_time_test.cc b/toxcore/mono_time_test.cc new file mode 100644 index 00000000000..5ad913224db --- /dev/null +++ b/toxcore/mono_time_test.cc @@ -0,0 +1,30 @@ +#include "mono_time.h" + +#include + +namespace { + +TEST(Util, UnixTimeIncreasesOverTime) { + unix_time_update(); + uint64_t const start = unix_time(); + + while (start == unix_time()) { + unix_time_update(); + } + + uint64_t const end = unix_time(); + EXPECT_GT(end, start); +} + +TEST(Util, IsTimeout) { + uint64_t const start = unix_time(); + EXPECT_FALSE(is_timeout(start, 1)); + + while (start == unix_time()) { + unix_time_update(); + } + + EXPECT_TRUE(is_timeout(start, 1)); +} + +} // namespace diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index bfdbbe30a4a..5a544afdac2 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -33,6 +33,7 @@ #include #include +#include "mono_time.h" #include "util.h" typedef struct { diff --git a/toxcore/network.c b/toxcore/network.c index 2a32a170210..24e53c47d7b 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -170,6 +170,7 @@ static int inet_pton(int family, const char *addrString, void *addrbuf) #include #include "logger.h" +#include "mono_time.h" #include "util.h" // Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD @@ -418,74 +419,6 @@ int set_socket_dualstack(Socket sock) } -/* return current UNIX time in microseconds (us). */ -static uint64_t current_time_actual(void) -{ - uint64_t time; -#ifdef OS_WIN32 - /* This probably works fine */ - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - time = ft.dwHighDateTime; - time <<= 32; - time |= ft.dwLowDateTime; - time -= 116444736000000000ULL; - return time / 10; -#else - struct timeval a; - gettimeofday(&a, nullptr); - time = 1000000ULL * a.tv_sec + a.tv_usec; - return time; -#endif -} - - -#ifdef OS_WIN32 -static uint64_t last_monotime; -static uint64_t add_monotime; -#endif - -/* return current monotonic time in milliseconds (ms). */ -uint64_t current_time_monotonic(void) -{ - uint64_t time; -#ifdef OS_WIN32 - uint64_t old_add_monotime = add_monotime; - time = (uint64_t)GetTickCount() + add_monotime; - - /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race - * conditions when multiple threads call this function at once */ - if (time + 0x10000 < last_monotime) { - uint32_t add = ~0; - /* use old_add_monotime rather than simply incrementing add_monotime, to handle the case that many threads - * simultaneously detect an overflow */ - add_monotime = old_add_monotime + add; - time += add; - } - - last_monotime = time; -#else - struct timespec monotime; -#if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW) - clock_gettime(CLOCK_MONOTONIC_RAW, &monotime); -#elif defined(__APPLE__) - clock_serv_t muhclock; - mach_timespec_t machtime; - - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); - clock_get_time(muhclock, &machtime); - mach_port_deallocate(mach_task_self(), muhclock); - - monotime.tv_sec = machtime.tv_sec; - monotime.tv_nsec = machtime.tv_nsec; -#else - clock_gettime(CLOCK_MONOTONIC, &monotime); -#endif - time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL); -#endif - return time; -} - static uint32_t data_0(uint16_t buflen, const uint8_t *buffer) { return buflen > 4 ? net_ntohl(*(const uint32_t *)&buffer[1]) : 0; diff --git a/toxcore/network.h b/toxcore/network.h index fbd12bb775b..8f166c672e7 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -381,9 +381,6 @@ int set_socket_reuseaddr(Socket sock); */ int set_socket_dualstack(Socket sock); -/* return current monotonic time in milliseconds (ms). */ -uint64_t current_time_monotonic(void); - /* Basic network functions: */ /* Function to send packet(data) of length length to ip_port. */ diff --git a/toxcore/onion.c b/toxcore/onion.c index 5bbc7f751c8..d313b7ce6fa 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -30,6 +30,7 @@ #include #include +#include "mono_time.h" #include "util.h" #define RETURN_1 ONION_RETURN_1 diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 6c9e8659aba..f3dd979b3c0 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -31,6 +31,7 @@ #include #include "LAN_discovery.h" +#include "mono_time.h" #include "util.h" #define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 35e725b7c02..b14b59fdebc 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -32,6 +32,7 @@ #include #include "LAN_discovery.h" +#include "mono_time.h" #include "util.h" /* defines for the array size and diff --git a/toxcore/ping.c b/toxcore/ping.c index 3767805dfb5..1bf096bfcc9 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -33,6 +33,7 @@ #include #include "DHT.h" +#include "mono_time.h" #include "network.h" #include "ping_array.h" #include "util.h" diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c index bcab9fe2b19..18240cc1e3a 100644 --- a/toxcore/ping_array.c +++ b/toxcore/ping_array.c @@ -31,6 +31,7 @@ #include #include "crypto_core.h" +#include "mono_time.h" #include "util.h" diff --git a/toxcore/util.c b/toxcore/util.c index eb5c63bf009..6766c3b6afa 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -34,75 +34,12 @@ #include "util.h" #include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ -#include "network.h" /* for current_time_monotonic */ #include #include #include -/* don't call into system billions of times for no reason */ -struct Unix_Time { - uint64_t time; - uint64_t base_time; -}; - -Unix_Time *unix_time_new(void) -{ - Unix_Time *unixtime = (Unix_Time *)malloc(sizeof(Unix_Time)); - - if (unixtime == nullptr) { - return nullptr; - } - - unixtime->time = 0; - unixtime->base_time = 0; - - return unixtime; -} - -void unix_time_free(Unix_Time *unixtime) -{ - free(unixtime); -} - -void unix_time_update_r(Unix_Time *unixtime) -{ - if (unixtime->base_time == 0) { - unixtime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL)); - } - - unixtime->time = (current_time_monotonic() / 1000ULL) + unixtime->base_time; -} - -uint64_t unix_time_get(const Unix_Time *unixtime) -{ - return unixtime->time; -} - -int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout) -{ - return timestamp + timeout <= unix_time_get(unixtime); -} - -static Unix_Time global_time; - -/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of - * unix_time() may fail to increase monotonically with increasing time */ -void unix_time_update(void) -{ - unix_time_update_r(&global_time); -} -uint64_t unix_time(void) -{ - return unix_time_get(&global_time); -} -int is_timeout(uint64_t timestamp, uint64_t timeout) -{ - return unix_time_is_timeout(&global_time, timestamp, timeout); -} - - /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src) { diff --git a/toxcore/util.h b/toxcore/util.h index cc1cffda34b..930e9a93361 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -39,21 +39,6 @@ extern "C" { #define MIN(a,b) (((a)<(b))?(a):(b)) #define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } -typedef struct Unix_Time Unix_Time; - -Unix_Time *unix_time_new(void); -void unix_time_free(Unix_Time *unixtime); - -// TODO(#980): Use per-tox unixtime, remove unix_time_update, and rename -// unix_time_update_r to unix_time_update. -void unix_time_update_r(Unix_Time *unixtime); -uint64_t unix_time_get(const Unix_Time *unixtime); -int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout); - -void unix_time_update(void); -uint64_t unix_time(void); -int is_timeout(uint64_t timestamp, uint64_t timeout); - /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src); uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */ diff --git a/toxcore/util_test.cc b/toxcore/util_test.cc index 541aa61f5d7..ff57f3fb755 100644 --- a/toxcore/util_test.cc +++ b/toxcore/util_test.cc @@ -4,28 +4,7 @@ #include -TEST(Util, UnixTimeIncreasesOverTime) { - unix_time_update(); - uint64_t const start = unix_time(); - - while (start == unix_time()) { - unix_time_update(); - } - - uint64_t const end = unix_time(); - EXPECT_GT(end, start); -} - -TEST(Util, IsTimeout) { - uint64_t const start = unix_time(); - EXPECT_FALSE(is_timeout(start, 1)); - - while (start == unix_time()) { - unix_time_update(); - } - - EXPECT_TRUE(is_timeout(start, 1)); -} +namespace { TEST(Util, TwoRandomIdsAreNotEqual) { uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; @@ -49,3 +28,5 @@ TEST(Util, IdCopyMakesKeysEqual) { EXPECT_TRUE(id_equal(pk1, pk2)); } + +} // namespace