In Linux, the current time is maintained by keeping the number of seconds elapsed since midnight of January 01, 1970 (called epoch); the second elements in each of these represent the time elapsed since the last second in microseconds and nanoseconds, respectively:
struct timespec { __kernel_time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; #endif struct timeval { __kernel_time_t tv_sec; /* seconds */ __kernel_suseconds_t tv_usec; /* microseconds */ };
Time (counter value) read from the clock source needs to be accumulated and tracked somewhere; the structure struct tk_read_base, defined in include/linux/timekeeper_internal.h, serves this purpose:
struct tk_read_base { struct clocksource *clock; cycle_t (*read)(struct clocksource *cs); cycle_t mask; cycle_t cycle_last; u32 mult; u32 shift; u64 xtime_nsec; ktime_t base_mono; };
The structure struct timekeeper, defined in include/linux/timekeeper_internal.h, keeps various timekeeping values. It's the primary data structure to maintain and manipulate the timekeeping data for different timelines, such as monotonic and raw:
struct timekeeper { struct tk_read_base tkr; u64 xtime_sec; unsigned long ktime_sec; struct timespec64 wall_to_monotonic; ktime_t offs_real; ktime_t offs_boot; ktime_t offs_tai; s32 tai_offset; ktime_t base_raw; struct timespec64 raw_time; /* The following members are for timekeeping internal use */ cycle_t cycle_interval; u64 xtime_interval; s64 xtime_remainder; u32 raw_interval; u64 ntp_tick; /* Difference between accumulated time and NTP time in ntp * shifted nano seconds. */ s64 ntp_error; u32 ntp_error_shift; u32 ntp_err_mult; };