Skip to content

Commit

Permalink
Add timespec_to_micros in time-util
Browse files Browse the repository at this point in the history
The function timespec_to_micros converts the time stored in a struct
timespec into microseconds (uint64_t type).

Signed-off-by: Joonyoung Shim <[email protected]>
  • Loading branch information
dofmind committed Oct 8, 2024
1 parent d01a0c1 commit 549c145
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 6 deletions.
25 changes: 19 additions & 6 deletions src/libbluechi/common/time-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,15 @@ uint64_t get_time_micros() {
if (clock_gettime(CLOCK_REALTIME, &now) < 0) {
return 0;
}
uint64_t now_micros = now.tv_sec * sec_to_microsec_multiplier +
(uint64_t) ((double) now.tv_nsec * nanosec_to_microsec_multiplier);
return now_micros;
return timespec_to_micros(now);
}

uint64_t get_time_micros_monotonic() {
struct timespec now;
if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) {
return 0;
}
uint64_t now_micros = now.tv_sec * sec_to_microsec_multiplier +
(uint64_t) ((double) now.tv_nsec * nanosec_to_microsec_multiplier);
return now_micros;
return timespec_to_micros(now);
}

uint64_t finalize_time_interval_micros(int64_t start_time_micros) {
Expand All @@ -38,6 +34,23 @@ double micros_to_millis(uint64_t time_micros) {
return (double) time_micros * microsec_to_millisec_multiplier;
}

uint64_t timespec_to_micros(struct timespec time) {
uint64_t sec_micros = 0;
uint64_t nsec_micros = 0;

if ((uint64_t) time.tv_sec > UINT64_MAX / sec_to_microsec_multiplier) {
return 0;
}

sec_micros = time.tv_sec * sec_to_microsec_multiplier;
nsec_micros = (uint64_t) ((double) time.tv_nsec * nanosec_to_microsec_multiplier);
if (sec_micros > UINT64_MAX - nsec_micros) {
return 0;
}

return sec_micros + nsec_micros;
}

char *get_formatted_log_timestamp() {
struct timespec now;
int r = 0;
Expand Down
1 change: 1 addition & 0 deletions src/libbluechi/common/time-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ uint64_t get_time_micros();
uint64_t get_time_micros_monotonic();
uint64_t finalize_time_interval_micros(int64_t start_time_micros);
double micros_to_millis(uint64_t time_micros);
uint64_t timespec_to_micros(struct timespec time);
char *get_formatted_log_timestamp();
char *get_formatted_log_timestamp_for_timespec(struct timespec time, bool is_gmt);
1 change: 1 addition & 0 deletions src/libbluechi/test/common/time-util/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
network_src = [
'get_log_timestamp',
'micros_to_millis_test',
'timespec_to_micros_test',
]

foreach src : network_src
Expand Down
59 changes: 59 additions & 0 deletions src/libbluechi/test/common/time-util/timespec_to_micros_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright Contributors to the Eclipse BlueChi project
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#include <assert.h>
#include <limits.h>
#include <stdlib.h>

#include "libbluechi/common/time-util.h"

int main() {
struct timespec time = { 0, 0 };

assert(timespec_to_micros(time) == 0);

time.tv_sec = 0;
time.tv_nsec = 1234;
assert(timespec_to_micros(time) == 1);

time.tv_sec = 5678;
time.tv_nsec = 0;
assert(timespec_to_micros(time) == 5678000000);

time.tv_sec = 123;
time.tv_nsec = 4567890;
assert(timespec_to_micros(time) == 123004567);

if (LONG_MAX < UINT64_MAX / sec_to_microsec_multiplier) {
time.tv_sec = LONG_MAX;
time.tv_nsec = 999999999;
assert(timespec_to_micros(time) == LONG_MAX * sec_to_microsec_multiplier + 999999);
}

#if defined(__x86_64__) || defined(__aarch64__)
time.tv_sec = LONG_MAX;
time.tv_nsec = 0;
assert(timespec_to_micros(time) == 0);

time.tv_sec = UINT64_MAX / sec_to_microsec_multiplier;
time.tv_nsec = 0;
assert(timespec_to_micros(time) == 18446744073709000000ULL);

time.tv_sec = UINT64_MAX / sec_to_microsec_multiplier;
time.tv_nsec = 551615000;
assert(timespec_to_micros(time) == UINT64_MAX);

time.tv_sec = UINT64_MAX / sec_to_microsec_multiplier;
time.tv_nsec = 551616000;
assert(timespec_to_micros(time) == 0);

time.tv_sec = UINT64_MAX / sec_to_microsec_multiplier + 1;
time.tv_nsec = 0;
assert(timespec_to_micros(time) == 0);
#endif

return EXIT_SUCCESS;
}

0 comments on commit 549c145

Please sign in to comment.