mytime.c revision 292588
1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file       mytime.c
4/// \brief      Time handling functions
5//
6//  Author:     Lasse Collin
7//
8//  This file has been put into the public domain.
9//  You can do whatever you want with this file.
10//
11///////////////////////////////////////////////////////////////////////////////
12
13#include "private.h"
14
15#if !(defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC)
16#	include <sys/time.h>
17#endif
18
19uint64_t opt_flush_timeout = 0;
20bool flush_needed;
21
22static uint64_t start_time;
23static uint64_t next_flush;
24
25
26/// \brief      Get the current time as milliseconds
27///
28/// It's relative to some point but not necessarily to the UNIX Epoch.
29static uint64_t
30mytime_now(void)
31{
32	// NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1.
33#if defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC
34	// If CLOCK_MONOTONIC was available at compile time but for some
35	// reason isn't at runtime, fallback to CLOCK_REALTIME which
36	// according to POSIX is mandatory for all implementations.
37	static clockid_t clk_id = CLOCK_MONOTONIC;
38	struct timespec tv;
39	while (clock_gettime(clk_id, &tv))
40		clk_id = CLOCK_REALTIME;
41
42	return (uint64_t)(tv.tv_sec) * UINT64_C(1000) + tv.tv_nsec / 1000000;
43#else
44	struct timeval tv;
45	gettimeofday(&tv, NULL);
46	return (uint64_t)(tv.tv_sec) * UINT64_C(1000) + tv.tv_usec / 1000;
47#endif
48}
49
50
51extern void
52mytime_set_start_time(void)
53{
54	start_time = mytime_now();
55	next_flush = start_time + opt_flush_timeout;
56	flush_needed = false;
57	return;
58}
59
60
61extern uint64_t
62mytime_get_elapsed(void)
63{
64	return mytime_now() - start_time;
65}
66
67
68extern void
69mytime_set_flush_time(void)
70{
71	next_flush = mytime_now() + opt_flush_timeout;
72	flush_needed = false;
73	return;
74}
75
76
77extern int
78mytime_get_flush_timeout(void)
79{
80	if (opt_flush_timeout == 0 || opt_mode != MODE_COMPRESS)
81		return -1;
82
83	const uint64_t now = mytime_now();
84	if (now >= next_flush)
85		return 0;
86
87	const uint64_t remaining = next_flush - now;
88	return remaining > INT_MAX ? INT_MAX : (int)remaining;
89}
90