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 19 uint64_t opt_flush_timeout = 0; 20 bool flush_needed; 21 22 static uint64_t start_time; 23 static 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. 29 static uint64_t 30 mytime_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 51 extern void 52 mytime_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 61 extern uint64_t 62 mytime_get_elapsed(void) 63 { 64 return mytime_now() - start_time; 65 } 66 67 68 extern void 69 mytime_set_flush_time(void) 70 { 71 next_flush = mytime_now() + opt_flush_timeout; 72 flush_needed = false; 73 return; 74 } 75 76 77 extern int 78 mytime_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