2 years ago

#46265

test-img

Folkert van Heusden

what is that configures the clock_gettime resolution?

I'm experimenting with the time-management of linux on a raspberry pi. For that I'm looking at clock_gettime (and clock_getres) for CLOCK_REALTIME.

I noticed that when I check clock_getres, it always says nanoseconds resolution (it returns 0 for tv_sec and 1 for tv_nsec) and also the values returned by clock_gettime point in that direction (e.g. I get values like 1642070078.415542996) but only if the system is fully booted with systemd etc running! When I put my test-program as a replacement for init (e.g. init=/test-clock in cmdline.txt), then suddenly getres still returns 1 for tv_nsec but all values returned by clock_gettime are with microsecond resolution!

test-program:

#include <stdint.h>
#include <stdio.h>
#include <time.h>

void test_clock(const clockid_t id, const char *const name)
{
    struct timespec ts { 0, 0 };

    uint64_t n = 0;

    struct timespec start { 0, 0 }, end { 0, 0 };
    clock_gettime(id, &start);
    uint64_t start_ts = start.tv_sec * uint64_t(1000000000) + start.tv_nsec, end_ts = 0;

    do {
        clock_gettime(id, &end);
        n++;

        end_ts = end.tv_sec * uint64_t(1000000000) + end.tv_nsec;
    }
    while(end_ts - start_ts < 2500000000);

    struct timespec now { 0, 0 };
    int ns = 0;

    for(int i=0; i<1000; i++) {
        clock_gettime(id, &now);

        if (now.tv_nsec % 1000)
            ns++;
    }

    if (clock_getres(id, &ts))
        fprintf(stderr, "clock_getres(%d) failed (%s)\n", id, name);
    else
        printf("%s:\t%ld.%09ld\t%f/s\t%d\t%ld.%09ld\n", name, ts.tv_sec, ts.tv_nsec, n / 2.5, ns, now.tv_sec, now.tv_nsec);
}

int main(int argc, char *argv[])
{
    printf("clock\tresolution\tcalls/s\t# with ns\tnow\n");

    test_clock(CLOCK_REALTIME, "CLOCK_REALTIME");
    test_clock(CLOCK_TAI, "CLOCK_TAI");
    test_clock(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
    test_clock(CLOCK_MONOTONIC_RAW, "CLOCK_MONOTONIC_RAW");

    return 0;
}

Compile with:

g++ -Ofast -ggdb3 -o test-clock test-clock.cpp -lrt

Expected output:

clock   resolution  calls/s # with ns   now
CLOCK_REALTIME: 0.000000001 48881594.400000/s   1000    1642071062.213603835
CLOCK_TAI:  0.000000001 49500959.200000/s   1000    1642071101.713668922
CLOCK_MONOTONIC:    0.000000001 49248353.200000/s   1000    2402707.303582035
CLOCK_MONOTONIC_RAW:    0.000000001 47072281.600000/s   1000    2402705.604860726

What I see when starting test-clock as init replacement:

clock   resolution  calls/s # with ns   now
CLOCK_REALTIME: 0.000000001     853001.200000/s 0       19.216404000
CLOCK_TAI:      0.000000001     736536.000000/s 0       21.718848000
CLOCK_MONOTONIC:        0.000000001     853367.200000/s 0       24.220166000
CLOCK_MONOTONIC_RAW:    0.000000001     855598.800000/s 0       26.721360000

The 4th column tells me that no readings were with nanosecond resolution.

So what I would like to know is: how can I configure the kernel/glibc/whatever so that it gives me nanosecond resolution at boot as well?

Any ideas?

c++

linux

time

raspberry-pi

glibc

0 Answers

Your Answer

Accepted video resources