Message ID | 20201223033517.1464263-3-gengcixi@gmail.com |
---|---|
State | Changes Requested |
Headers | show |
Series | add rtctime libs and rtc02 case | expand |
> static struct timespec real_begin, mono_begin; > > +static struct rtc_time rtc_begin; > + > static int clock_saved; > > void tst_wallclock_save(void) > @@ -58,3 +61,42 @@ void tst_wallclock_restore(void) > if (tst_clock_settime(CLOCK_REALTIME, &adjust)) > tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed"); > } > + > +void tst_rtctime_save(void) > +{ > + /* save initial monotonic time to restore it when needed */ > + if (tst_rtc_gettime(&rtc_begin)) > + tst_brk(TBROK | TERRNO, "tst_rtc_gettime() realtime failed"); > + > + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin)) > + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); > + > + clock_saved = 1; It would be better if we defined rtc_clock_saved for the rtc* functions instead. > +} > + > +void tst_rtctime_restore(void) > +{ > + static struct timespec mono_end, elapsed; > + static struct timespec rtc_begin_tm, rtc_adjust; > + static struct rtc_time rtc_restore; > + > + if (!clock_saved) > + return; > + > + clock_saved = 0; > + > + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end)) > + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); > + > + elapsed = tst_timespec_diff(mono_end, mono_begin); > + > + rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin); We should clear the tv_nsec here otherwise it will contain garbage. > + rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed); > + > + tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore); > + > + /* restore realtime clock based on monotonic delta */ > + if (tst_rtc_settime(&rtc_restore)) > + tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed"); > +} Other than this, it looks good.
Cyril Hrubis <chrubis@suse.cz> 于2021年1月7日周四 下午9:56写道: > > > static struct timespec real_begin, mono_begin; > > > > +static struct rtc_time rtc_begin; > > + > > static int clock_saved; > > > > void tst_wallclock_save(void) > > @@ -58,3 +61,42 @@ void tst_wallclock_restore(void) > > if (tst_clock_settime(CLOCK_REALTIME, &adjust)) > > tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed"); > > } > > + > > +void tst_rtctime_save(void) > > +{ > > + /* save initial monotonic time to restore it when needed */ > > + if (tst_rtc_gettime(&rtc_begin)) > > + tst_brk(TBROK | TERRNO, "tst_rtc_gettime() realtime failed"); > > + > > + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin)) > > + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); > > + > > + clock_saved = 1; > > It would be better if we defined rtc_clock_saved for the rtc* functions > instead. > > > +} > > + > > +void tst_rtctime_restore(void) > > +{ > > + static struct timespec mono_end, elapsed; > > + static struct timespec rtc_begin_tm, rtc_adjust; > > + static struct rtc_time rtc_restore; > > + > > + if (!clock_saved) > > + return; > > + > > + clock_saved = 0; > > + > > + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end)) > > + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); > > + > > + elapsed = tst_timespec_diff(mono_end, mono_begin); > > + > > + rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin); > > We should clear the tv_nsec here otherwise it will contain garbage. The rtc_begin_tm is defined in this function, and tv_nsec never assigned, so I think it will not produce any garbage. > > > + rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed); > > + > > + tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore); > > + > > + /* restore realtime clock based on monotonic delta */ > > + if (tst_rtc_settime(&rtc_restore)) > > + tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed"); > > +} > > Other than this, it looks good. > > -- > Cyril Hrubis > chrubis@suse.cz
Hi! > > > +void tst_rtctime_restore(void) > > > +{ > > > + static struct timespec mono_end, elapsed; > > > + static struct timespec rtc_begin_tm, rtc_adjust; > > > + static struct rtc_time rtc_restore; > > > + > > > + if (!clock_saved) > > > + return; > > > + > > > + clock_saved = 0; > > > + > > > + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end)) > > > + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); > > > + > > > + elapsed = tst_timespec_diff(mono_end, mono_begin); > > > + > > > + rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin); > > > > We should clear the tv_nsec here otherwise it will contain garbage. > The rtc_begin_tm is defined in this function??? and tv_nsec never assigned??? > so I think it will not produce any garbage. It's never assigned and declared on stack, so it will contain garbage which will be eventually added to the rtc_adjust.tv_sec. Technically the tv_nsec is long, so on 64 bit platform it may add up to 10^10 seconds to the result if we are unlucky and upper bits are set. On 32 bit there is not much room for error btw, up to 2 seconds since long is only 4bytes there. > > > + rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed); > > > + > > > + tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore); > > > + > > > + /* restore realtime clock based on monotonic delta */ > > > + if (tst_rtc_settime(&rtc_restore)) > > > + tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed"); > > > +} > > > > Other than this, it looks good. > > > > -- > > Cyril Hrubis > > chrubis@suse.cz
Cyril Hrubis <chrubis@suse.cz> 于2021年1月8日周五 下午5:33写道: > > Hi! > > > > +void tst_rtctime_restore(void) > > > > +{ > > > > + static struct timespec mono_end, elapsed; > > > > + static struct timespec rtc_begin_tm, rtc_adjust; > > > > + static struct rtc_time rtc_restore; > > > > + > > > > + if (!clock_saved) > > > > + return; > > > > + > > > > + clock_saved = 0; > > > > + > > > > + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end)) > > > > + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); > > > > + > > > > + elapsed = tst_timespec_diff(mono_end, mono_begin); > > > > + > > > > + rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin); > > > > > > We should clear the tv_nsec here otherwise it will contain garbage. > > The rtc_begin_tm is defined in this function??? and tv_nsec never assigned??? > > so I think it will not produce any garbage. > > It's never assigned and declared on stack, so it will contain garbage > which will be eventually added to the rtc_adjust.tv_sec. Technically > the tv_nsec is long, so on 64 bit platform it may add up to 10^10 > seconds to the result if we are unlucky and upper bits are set. On 32 > bit there is not much room for error btw, up to 2 seconds since long is > only 4bytes there. > ok,I got it, thanks for you explain, I will fixed this issue > > > > + rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed); > > > > + > > > > + tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore); > > > > + > > > > + /* restore realtime clock based on monotonic delta */ > > > > + if (tst_rtc_settime(&rtc_restore)) > > > > + tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed"); > > > > +} > > > > > > Other than this, it looks good. > > > > > > -- > > > Cyril Hrubis > > > chrubis@suse.cz > > -- > Cyril Hrubis > chrubis@suse.cz
diff --git a/include/tst_wallclock.h b/include/tst_wallclock.h index 7d6723a7a..5103c8321 100644 --- a/include/tst_wallclock.h +++ b/include/tst_wallclock.h @@ -12,4 +12,8 @@ void tst_wallclock_save(void); void tst_wallclock_restore(void); +void tst_rtctime_save(void); + +void tst_rtctime_restore(void); + #endif /* TST_WALLCLK_H__ */ diff --git a/lib/tst_wallclock.c b/lib/tst_wallclock.c index 282d6ada3..5be1f46d8 100644 --- a/lib/tst_wallclock.c +++ b/lib/tst_wallclock.c @@ -11,11 +11,14 @@ #include "tst_test.h" #include "tst_timer.h" #include "tst_clocks.h" +#include "tst_rtctime.h" #include "tst_wallclock.h" #include "lapi/posix_clocks.h" static struct timespec real_begin, mono_begin; +static struct rtc_time rtc_begin; + static int clock_saved; void tst_wallclock_save(void) @@ -58,3 +61,42 @@ void tst_wallclock_restore(void) if (tst_clock_settime(CLOCK_REALTIME, &adjust)) tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed"); } + +void tst_rtctime_save(void) +{ + /* save initial monotonic time to restore it when needed */ + if (tst_rtc_gettime(&rtc_begin)) + tst_brk(TBROK | TERRNO, "tst_rtc_gettime() realtime failed"); + + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin)) + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); + + clock_saved = 1; +} + +void tst_rtctime_restore(void) +{ + static struct timespec mono_end, elapsed; + static struct timespec rtc_begin_tm, rtc_adjust; + static struct rtc_time rtc_restore; + + if (!clock_saved) + return; + + clock_saved = 0; + + if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end)) + tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed"); + + elapsed = tst_timespec_diff(mono_end, mono_begin); + + rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin); + + rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed); + + tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore); + + /* restore realtime clock based on monotonic delta */ + if (tst_rtc_settime(&rtc_restore)) + tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed"); +}