Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clock issues #357

Closed
eyberg opened this issue Jan 10, 2019 · 15 comments · Fixed by #941
Closed

clock issues #357

eyberg opened this issue Jan 10, 2019 · 15 comments · Fixed by #941
Assignees

Comments

@eyberg
Copy link
Contributor

eyberg commented Jan 10, 2019

taken form #354

eyberg@s1:~/cl$ cat main.c
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <sys/sysinfo.h>

int main(void){
    struct sysinfo info;
    sysinfo(&info);

    const time_t boottime = time(NULL) - info.uptime;

    struct timespec monotime;
    clock_gettime(CLOCK_MONOTONIC, &monotime);

    time_t curtime = boottime + monotime.tv_sec;

    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;
}
eyberg@s1:~/cl$ ./main
0
1
Boot time = Wed Aug 22 18:38:07 2018
Current time = Thu Jan 10 00:40:00 2019
Real Time = Thu Jan 10 00:40:01 2019
eyberg@s1:~/cl$ ops run -p8083 -f main
Finding dependent shared libs
booting image ...
warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
pages heap: 000000007fb75000, length 00000000002f7000
physical memory:
   base 0000000000200000, length 000000007f600000
assigned: 10.0.2.15
0
1
Boot time = Thu Jan 10 00:40:15 2019
Current time = Thu Jan 19 01:20:31 2068
Real Time = Thu Jan 10 00:40:16 2019
exit_groupexit status 1

and if you look @ http://man7.org/linux/man-pages/man3/sleep.3.html you can see it uses nanosleep which uses... http://man7.org/linux/man-pages/man2/nanosleep.2.html

&&&.... https://golang.org/src/time/time.go

@eyberg
Copy link
Contributor Author

eyberg commented Jan 10, 2019

#343

@mkhon mkhon self-assigned this Jan 10, 2019
@billhuey
Copy link
Contributor

billhuey commented Feb 14, 2019

Relevant MSR bits are in this document for the clock implementation are in :

https://www.kernel.org/doc/Documentation/virtual/kvm/msr.txt

@billhuey
Copy link
Contributor

As I understand it, the differences between CLOCK_REALTIME and CLOCK_MONOTONIC is that the CLOCK_REALTIME value can be changed by setting the system clock via ntp etc.

CLOCK_MONOTONIC is not affect by any change via ntp

@billhuey
Copy link
Contributor

The implementation currently ignores CLOCK_MONOTONIC and treats all clk_id fields passed to clock_gettime as CLOCK_REALTIME which is incorrect. Changes to just return zeros CLOCK_MONOTONIC gives acceptable results for short running programs but will cause programs that need a monotonic clock for time stamping objects to be incorrect.

It would return the same time stamp during the execution of the program no matter how long. I have a simple fix that just returns zeros for CLOCK_MONOTONIC but a more complete implementation is needed

@billhuey
Copy link
Contributor

The current now() implementation is implemented specifically for KVM. There's a monotonic clock source that I can use within KVM.

Not all cloud virtualization infrastructure uses KVM, like with Microsoft, but start with a KVM specific version for now

@billhuey
Copy link
Contributor

MSR_KVM_SYSTEM_TIME_NEW: 0x4b564d01

Looks there's a monotonic clock in the KVM paravirtualization API that can be useful here for implementing a monotonic clock

@billhuey
Copy link
Contributor

billh@dungeon:~/project$ ./main#375
Boot time = Wed Dec 5 11:43:29 2018

Monotonic Time = Fri Mar 13 17:58:19 1970
Current (boot) = 1544039009
Current (mono) = 6227899
Current time = Fri Feb 15 13:41:48 2019
Real Time = Fri Feb 15 13:41:49 2019

Monotonic Time = Fri Mar 13 17:58:21 1970
Current (boot) = 1544039009
Current (mono) = 6227901
Current time = Fri Feb 15 13:41:50 2019
Real Time = Fri Feb 15 13:41:51 2019

Monotonic Time = Fri Mar 13 17:58:23 1970
Current (boot) = 1544039009
Current (mono) = 6227903
Current time = Fri Feb 15 13:41:52 2019
Real Time = Fri Feb 15 13:41:53 2019

Monotonic Time = Fri Mar 13 17:58:25 1970
Current (boot) = 1544039009
Current (mono) = 6227905
Current time = Fri Feb 15 13:41:54 2019
Real Time = Fri Feb 15 13:41:55 2019

billh@dungeon:~/project$ ops run main#375
Finding dependent shared libs
booting image ...
warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
assigned: 10.0.2.15
Boot time = Fri Feb 15 21:42:00 2019

Monotonic Time = Fri Feb 15 21:42:01 2019
Current (boot) = 1550266920
Current (mono) = 1550266921
Current time = Sun Apr 1 19:24:01 2068
Real Time = Fri Feb 15 21:42:01 2019

Monotonic Time = Fri Feb 15 21:42:03 2019
Current (boot) = 1550266920
Current (mono) = 1550266923
Current time = Sun Apr 1 19:24:03 2068
Real Time = Fri Feb 15 21:42:03 2019

@billhuey
Copy link
Contributor

billhuey commented Feb 15, 2019

6227901 seconds = 72.0821875 days

billh@dungeon:~/project$ uptime
13:51:56 up 72 days, 2:08, 3 users, load average: 1.04, 1.06, 1.00

Current (mono) = 1550266921 second
is 17942.904178241 days

Monotonic time should return the the number of seconds that have elapsed since the machine started up and not the Unix time

@billhuey
Copy link
Contributor

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

int main(void){
    struct sysinfo info;
    sysinfo(&info);
    int i;

    time_t curtime;
    struct timespec realtime;

    const time_t boottime = time(NULL) - info.uptime;

    struct timespec monotime;

    printf("Boot time   = %s", ctime(&boottime));
    printf("\n");

    for (i = 0; i < 4; i++) {
        clock_gettime(CLOCK_MONOTONIC, &monotime);
        printf("Monotonic Time  = %s", ctime(&monotime.tv_sec));

        curtime = boottime + monotime.tv_sec;
        printf("Current (boot)  = %ld\n", boottime);
        printf("Current (mono)  = %ld\n", monotime.tv_sec);
        printf("Current time    = %s", ctime(&curtime));

        clock_gettime(CLOCK_REALTIME, &realtime);
        printf("Real Time       = %s", ctime(&realtime.tv_sec));
        printf("\n");

        usleep(2000 * 1000);
    }
}

@billhuey
Copy link
Contributor

Updated program above to generate the test output

@billhuey
Copy link
Contributor

billhuey commented Feb 15, 2019

billh@dungeon:~/project$ !gcc
gcc -o main#375 main#375.c  && sudo rm /tmp/{resolv,hostname} && ops run main#375
Finding dependent shared libs
booting image ...
warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
assigned: 10.0.2.15
Boot time       = Fri Feb 15 22:00:48 2019

Monotonic Time  = Thu Jan  1 00:00:00 1970
Current (boot)  = 1550268048
Current (mono)  = 0
Current time    = Fri Feb 15 22:00:48 2019
Real Time       = Fri Feb 15 22:00:49 2019

Monotonic Time  = Thu Jan  1 00:00:02 1970
Current (boot)  = 1550268048
Current (mono)  = 2
Current time    = Fri Feb 15 22:00:50 2019
Real Time       = Fri Feb 15 22:00:51 2019

Monotonic Time  = Thu Jan  1 00:00:04 1970
Current (boot)  = 1550268048
Current (mono)  = 4
Current time    = Fri Feb 15 22:00:52 2019
Real Time       = Fri Feb 15 22:00:53 2019

Monotonic Time  = Thu Jan  1 00:00:06 1970
Current (boot)  = 1550268048
Current (mono)  = 6
Current time    = Fri Feb 15 22:00:54 2019
Real Time       = Fri Feb 15 22:00:55 2019

exit_group
exit status 1

@billhuey
Copy link
Contributor

Above log is how monotonic time should proceed.

@eyberg
Copy link
Contributor Author

eyberg commented Feb 16, 2019

the other issue in this tkt is that if you notice that usleep calls nanosleep(2) underneath - so it basically skips it when ran in nanos

@billhuey
Copy link
Contributor

Yeah, in following discussions. It looks like the test program originally assumes that the second elapsed as boot is the same as monotonic time. Not sure if the patch I submitted should be merged or not but it now currently worse as the above program expects it to work

@eyberg eyberg assigned francescolavra and unassigned mkhon Jun 6, 2019
francescolavra added a commit that referenced this issue Jul 23, 2019
The now() function returns the wall clock time, so it will be
subject to discontinuities if the system time is changed (when
support for changing the system time is actually implemented), and
for this reason it should not be used as time source in
clock_gettime() in case the requested clock is a monotonic clock.
This commit uses uptime() as time source in such cases.

Closes #357.
@francescolavra
Copy link
Member

francescolavra commented Jul 23, 2019

nanosleep() works fine actually. When inserting printf() calls before and after a call to sleep(), it might appear not to be working because the strings being sent to the standard output are buffered, so you will see the content printed by all printf() calls only after sleep() returns. To set the standard output as unbuffered, you can call setbuf(stdout, NULL).

francescolavra added a commit that referenced this issue Jul 24, 2019
The now() function returns the wall clock time, so it will be
subject to discontinuities if the system time is changed (when
support for changing the system time is actually implemented), and
for this reason it should not be used as time source in
clock_gettime() in case the requested clock is a monotonic clock.
This commit uses uptime() as time source in such cases.
In addition, the CLOCK_PROCESS_CPUTIME_ID clock type is now
implemented as well.

Closes #357.
francescolavra added a commit that referenced this issue Jul 24, 2019
The now() function returns the wall clock time, so it will be
subject to discontinuities if the system time is changed (when
support for changing the system time is actually implemented), and
for this reason it should not be used as time source in
clock_gettime() in case the requested clock is a monotonic clock.
This commit uses uptime() as time source in such cases.
In addition, the CLOCK_PROCESS_CPUTIME_ID clock type is now
implemented as well.

Closes #357.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants