22

As I understand on Linux starting point for CLOCK_MONOTONIC is boot time. In my current work I prefer to use monotonic clock instead of CLOCK_REALTIME (for calculation) but in same time I need to provide human friendly timestamps (with year/month/day) in reporting. They can be not very precise so I was thinking to join monotonic counter with boot time.

From where I can get this time on linux system using api calls?

Aliaksandr Belik
  • 12,725
  • 6
  • 64
  • 90
rimas
  • 757
  • 2
  • 8
  • 18

3 Answers3

16

Assuming the Linux kernel starts the uptime counter at the same time as it starts keeping track of the monotonic clock, you can derive the boot time (relative to the Epoch) by subtracting uptime from the current time.

Linux offers the system uptime in seconds via the sysinfo structure; the current time in seconds since the Epoch can be acquired on POSIX compliant libraries via the time function.

#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <sys/sysinfo.h>

int main(void) {
    /* get uptime in seconds */
    struct sysinfo info;
    sysinfo(&info);

    /* calculate boot time in seconds since the Epoch */
    const time_t boottime = time(NULL) - info.uptime;

    /* get monotonic clock time */
    struct timespec monotime;
    clock_gettime(CLOCK_MONOTONIC, &monotime);

    /* calculate current time in seconds since the Epoch */
    time_t curtime = boottime + monotime.tv_sec;

    /* get realtime clock time for comparison */
    struct timespec realtime;
    clock_gettime(CLOCK_REALTIME, &realtime);

    printf("Boot time = %s", ctime(&boottime));
    printf("Current time = %s", ctime(&curtime));
    printf("Real Time = %s", ctime(&realtime.tv_sec));

    return 0;
}

Unfortunately, the monotonic clock may not match up relative to boot time exactly. When I tested out the above code on my machine, the monotonic clock was a second off from the system uptime. However, you can still use the monotonic clock as long as you take the respective offset into account.

Portability note: although Linux may return current monotonic time relative to boot time, POSIX machines in general are permitted to return current monotonic time from any arbitrary -- yet consistent -- point in time (often the Epoch).


As a side note, you may not need to derive boot time as I did. I suspect there is a way to get the boot time via the Linux API, as there are many Linux utilities which display the boot time in a human-readable format. For example:

$ who -b
         system boot  2013-06-21 12:56

I wasn't able to find such a call, but inspection of the source code for some of these common utilities may reveal how they determine the human-readable boot time.

In the case of the who utility, I suspect it utilizes the utmp file to acquire the system boot time.

pevik
  • 4,523
  • 3
  • 33
  • 44
Vilhelm Gray
  • 11,516
  • 10
  • 61
  • 114
  • 1
    Actually there is no syscall for that; the system boot time is recorded in utmp (/var/run/utmp) since at least the days of UNIX v6 :) – dom0 Jan 10 '17 at 17:29
4

http://www.kernel.org/doc/man-pages/online/pages/man2/clock_getres.2.html:

  CLOCK_MONOTONIC
          Clock that cannot be set and represents monotonic time since some
          unspecified starting point.

Means that you can use CLOCK_MONOTONIC for interval calculations and other things but you can't really convert it to a human readable representation.

Moreover, you prabably want CLOCK_MONOTONIC_RAW instead of CLOCK_MONOTONIC:

  CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
          Similar  to  CLOCK_MONOTONIC, but provides access to a raw hard‐
          ware-based time that is not subject to NTP adjustments.

Keep using CLOCK_REALTIME for human-readable times.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 1
    Yes, I know difference between monotonic and realtime clock. I was trying to combine both approaches because dont want to store 2 timestamps in object - monotonic and realtime. I want use monotonic for work and somehow get information about starting point to later, on client side just add monotonic part to it. – rimas Feb 06 '13 at 10:38
  • 1
    I tried that once (on Windows, which has awful timing support). The answer is: don't go there. If you must, you can try to estimate the current monotonic-to-realtime offset by reading both clocks, but that offset can change without warning. – Andy Lutomirski Jun 24 '13 at 17:55
  • Link now reads "On Linux, that point corresponds to the number of seconds that the system has been running since it was booted." – LHLaurini Mar 21 '23 at 10:35
0

CLOCK_MONOTONIC is generally not affected by any adjustments to system time. For example, if the system clock is adjusted via NTP, CLOCK_MONOTONIC has no way of knowing (nor does it need to).

For this reason, don't use CLOCK_MONOTONIC if you need human-readable timestamps.

See Difference between CLOCK_REALTIME and CLOCK_MONOTONIC? for a discussion.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 2
    Linux did not get right `CLOCK_MONOTONIC`. To fix they added `CLOCK_MONOTONIC_RAW`. – Maxim Egorushkin Feb 06 '13 at 10:17
  • CLOCK_MONOTONIC is monotonic but it can be adjusted. This is done by skewing the counter. Some ticks will take slightly more/less time than others in order to maintain time. – jterm Oct 11 '18 at 19:27