The monotone time function under Linux system

Source: Internet
Author: User
Tags posix

Welcome reprint, Reprint please indicate source: http://forever.blog.chinaunix.net

When writing applications under Linux, sometimes the concept of high-precision relative time is used, such as interval 100ms. So which time function should be used more accurately?
1. Time
This function returns the number of seconds since 1970, and is clearly not accurate enough to use
2, Gettimeofday
The function returns the number of seconds and microseconds since 1970, and the accuracy is clearly enough. I think a lot of programmers also use this function to calculate the relative time, if the system time because of NTP and other causes of time jumps, then use this function to calculate the relative time is not a problem. So the function can't be used either.
3, Clock_gettime
The function provides 4 types of clock_realtime, Clock_monotonic, Clock_process_cputimeid, clock_thread_cputime_id. From the literal sense, Clock_monotonic provides a monotonically increasing timestamp, the function returns the number of seconds and nanoseconds since the start of the system, but the function does not take into account the NTP situation, so it is not a monotonically increasing in absolute sense (see II).
Clock_realtime is affected by settime ()/settimeofday () calls and can also being frequency corrected by NTP via Adjtimex ().
Clock_monotonic is isn't affected by settime ()/settimeofday () and is frequency adjusted by NTP via Adjtimex (). With LINUX,NTP normally uses settimeofday () for large corrections (over half a second). The Adjtimex () inteface allows for small clock frequency changes (slewing). This can is done with a few different ways, see the Mans page for Adjtimex.

Clock_monotonic_raw that'll is not being modified at all, and would have a linear correlation with the hardware counters.
4, Syscall (Sys_clock_gettime, Clock_monotonic_raw, &monotonic_time)
This function provides a true sense of monotonically increasing time (see three)


Second, the principle of clock_gettime (clock_monotonic) in glibc
See the GLIBC code to see that the value is computed by the kernel.

__vdso_clock_gettime-------->do_monotonic
The implementation of this function is as follows:

Click (here) to collapse or open

  1. notrace static noinline int do_monotonic (struct timespec *ts)
  2. {
  3. unsigned long seq, NS, secs;
  4. do {
  5. Seq = Read_seqbegin (&gtod->lock);
  6. secs = gtod->wall_time_sec;
  7. NS = gtod->wall_time_nsec + vgetns ();
  8. secs + = gtod->wall_to_monotonic.tv_sec;
  9. NS + = gtod->wall_to_monotonic.tv_nsec;
  10. } while (Unlikely (Read_seqretry (&gtod->lock, seq)));
  11. /* wall_time_nsec, Vgetns (), and wall_to_monotonic.tv_nsec
  12. * is all guaranteed to is nonnegative.
  13. */
  14. while (ns >= nsec_per_sec) {
  15. NS-= nsec_per_sec;
  16. ++secs;
  17. }
  18. ts->tv_sec = secs;
  19. TS->TV_NSEC = ns;
  20. return 0;
  21. }

This code reads the time on the wall, and then adds to the cost of the monotony time, thus getting a monotonous time, but this does not take into account the fact that NTP adjusts the small time skew by Adjtimex (), so this is still not an absolute monotonically increasing.
Third, kernel clock_gettime system call
The kernel implements Clock_gettime system calls in KERNEL/POSIX-TIMERS.C, including Clock_realtime, Clock_monotonic, Clock_monotonic_raw, CLOCK_ Realtime_coarse, Clock_monotonic_coarse, clock_boottime and other types, here we look at the implementation of Clock_monotonic_raw

Click (here) to collapse or open

  1. struct K_clock Clock_monotonic_raw = {
  2. . Clock_getres = Hrtimer_get_res,
  3. . Clock_get = Posix_get_monotonic_raw,
  4. };
  5. Posix_timers_register_clock (Clock_monotonic_raw, &clock_monotonic_raw);
  6. /*
  7. * Get Monotonic-raw time for POSIX timers
  8. */
  9. static int Posix_get_monotonic_raw (clockid_t which_clock, struct timespec *tp)
  10. {
  11. Getrawmonotonic (TP);
  12. return 0;
  13. }
  14. /**
  15. * Getrawmonotonic-returns The raw monotonic time in a Timespec
  16. * @ts: Pointer to the TIMESPEC to be set
  17. *
  18. * Returns The raw monotonic time (completely un-modified by NTP)
  19. */
  20. void Getrawmonotonic (struct timespec *ts)
  21. {
  22. unsigned long seq;
  23. S64 Nsecs;
  24. do {
  25. Seq = Read_seqbegin (&xtime_lock);
  26. Nsecs = Timekeeping_get_ns_raw ();
  27. *ts = Raw_time;
  28. } while (Read_seqretry (&xtime_lock, seq));
  29. Timespec_add_ns (ts, nsecs);
  30. }
  31. Export_symbol (Getrawmonotonic);
  32. Static inline S64 timekeeping_get_ns_raw (void)
  33. {
  34. cycle_t Cycle_now, Cycle_delta;
  35. struct Clocksource *clock;
  36. /* Read Clocksource: */
  37. Clock = timekeeper.clock;
  38. Cycle_now = Clock->read (clock);
  39. /* Calculate the Delta since the last update_wall_time: */
  40. Cycle_delta = (cycle_now-clock->cycle_last) & clock->mask;
  41. /* Return delta Convert to nanoseconds using NTP adjusted mult. */
  42. Return Clocksource_cyc2ns (Cycle_delta, Clock->mult, Clock->shift);
  43. }


Iv. about wall time and monotonic time
Wall Time:xtime, depending on the clocksource used for xtime timing, its accuracy can even reach the nanosecond level, the kernel spends most of its time using Xtime to get current time information, Xtime records the number of nanoseconds that have elapsed since the current moment in 1970.

Monotonic time: It has been monotonically increasing since the system was powered on (NTP Adjtimex will affect its monotonicity), unlike Xtime, which can be skipped due to the user's tuning time, but this time does not compute the time of sleep, that is, when the system sleeps (Total_ Sleep_time), Monotoic time does not increment.

Raw monotonic time: This is similar to monotonic time and is a monotonically increasing time, the only difference being that raw monotonic time is not affected by the NTP timing, which represents the time statistics of the system's independent clock hardware.
Boot time: Same as monotonic, but with the time of system hibernation (Total_sleep_time), it represents the total time after the system has been power up.
V. Summary
Get high-precision monotonically increasing time under Linux, only using Syscall (Sys_clock_gettime, Clock_monotonic_raw, &monotonic_time)!

The monotone time function under Linux system

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.