Line data Source code
1 : /* Copyright (c) 2003, Roger Dingledine 2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 : /* See LICENSE for licensing information */ 5 : 6 : /** 7 : * \file approx_time.c 8 : * \brief Cache the last result of time(), for performance and testing. 9 : **/ 10 : 11 : #include "orconfig.h" 12 : #include "lib/subsys/subsys.h" 13 : #include "lib/wallclock/approx_time.h" 14 : #include "lib/wallclock/wallclock_sys.h" 15 : 16 : /* ===== 17 : * Cached time 18 : * ===== */ 19 : 20 : #ifndef TIME_IS_FAST 21 : /** Cached estimate of the current time. Updated around once per second; 22 : * may be a few seconds off if we are really busy. This is a hack to avoid 23 : * calling time(NULL) (which not everybody has optimized) on critical paths. 24 : */ 25 : static time_t cached_approx_time = 0; 26 : 27 : /** Return a cached estimate of the current time from when 28 : * update_approx_time() was last called. This is a hack to avoid calling 29 : * time(NULL) on critical paths: please do not even think of calling it 30 : * anywhere else. */ 31 : time_t 32 291749 : approx_time(void) 33 : { 34 291749 : return cached_approx_time; 35 : } 36 : 37 : /** Update the cached estimate of the current time. This function SHOULD be 38 : * called once per second, and MUST be called before the first call to 39 : * get_approx_time. */ 40 : void 41 5933 : update_approx_time(time_t now) 42 : { 43 5933 : cached_approx_time = now; 44 5933 : } 45 : #endif /* !defined(TIME_IS_FAST) */ 46 : 47 : /** 48 : * Initialize the "wallclock" subsystem by setting the current cached time. 49 : **/ 50 : static int 51 5553 : subsys_wallclock_initialize(void) 52 : { 53 5553 : update_approx_time(time(NULL)); 54 5553 : return 0; 55 : } 56 : 57 : /** 58 : * Subsystem function table describing the "wallclock" subsystem. 59 : **/ 60 : const subsys_fns_t sys_wallclock = { 61 : .name = "wallclock", 62 : SUBSYS_DECLARE_LOCATION(), 63 : .supported = true, 64 : /* Approximate time is a diagnostic feature, we want it to init right after 65 : * low-level error handling. */ 66 : .level = -98, 67 : .initialize = subsys_wallclock_initialize, 68 : };