void test_SubFullOflow() { int i,j; for (i = -4; i <= 4; ++i) for (j = -4; j <= 4; ++j) { struct timeval a = timeval_init(i, 100); struct timeval b = timeval_init(j, 999900); struct timeval E = timeval_init(i - j - 1, 200); struct timeval c; c = sub_tval(a, b); TEST_ASSERT_EQUAL_timeval(E, c); } }
void test_SubFullNorm() { int i,j; for (i = -4; i <= 4; ++i) for (j = -4; j <= 4; ++j) { struct timeval a = timeval_init(i, 600); struct timeval b = timeval_init(j, 400); struct timeval E = timeval_init(i - j, 600 - 400); struct timeval c; c = sub_tval(a, b); TEST_ASSERT_EQUAL_timeval(E, c); } }
/* * Test function calling the old and new code mentioned in * http://bugs.ntp.org/show_bug.cgi?id=2803#c22 */ static int do_test( struct timeval timetv, struct timeval tvlast ) { struct timeval tvdiff_old; struct timeval tvdiff_new; int cond_old; int cond_new; int failed; cond_old = 0; cond_new = 0; // Here is the old code: tvdiff_old = abs_tval(sub_tval(timetv, tvlast)); if (tvdiff_old.tv_sec > 0) { cond_old = 1; } // Here is the new code: tvdiff_new = sub_tval(timetv, tvlast); if (tvdiff_new.tv_sec != 0) { cond_new = 1; } failed = cond_new != cond_old; if ( failed || verbose ) printf( "timetv %lli|%07li, tvlast %lli|%07li: tvdiff_old: %lli|%07li -> %i, tvdiff_new: %lli|%07li -> %i, same cond: %s\n", (long long) timetv.tv_sec, timetv.tv_usec, (long long) tvlast.tv_sec, tvlast.tv_usec, (long long) tvdiff_old.tv_sec, tvdiff_old.tv_usec, cond_old, (long long) tvdiff_new.tv_sec, tvdiff_new.tv_usec, cond_new, failed ? "NO <<" : "yes" ); return failed ? -1 : 0; }
bool AssertTimevalClose(const struct timeval m, const struct timeval n, const struct timeval limit) { struct timeval diff; diff = abs_tval(sub_tval(m, n)); if (cmp_tval(limit, diff) >= 0) return TRUE; else { printf("m_expr which is %ld.%lu \nand\nn_expr which is %ld.%lu\nare not close; diff=%ld.%luusec\n", m.tv_sec, m.tv_usec, n.tv_sec, n.tv_usec, diff.tv_sec, diff.tv_usec); //I don't have variables m_expr and n_expr in unity, those are command line arguments which only getst has!!! return FALSE; } }
bool AssertTimevalClose(const struct timeval m, const struct timeval n, const struct timeval limit) { struct timeval diff; diff = abs_tval(sub_tval(m, n)); if (cmp_tval(limit, diff) >= 0) return TRUE; else { //printf(""); //<< m_expr << " which is " << timeval_wrap(m) //<< "\nand\n" //<< n_expr << " which is " << timeval_wrap(n) //<< "\nare not close; diff=" << timeval_wrap(diff); return FALSE; } }
::testing::AssertionResult AssertTimevalClose::operator()( const char* m_expr, const char* n_expr, const struct timeval & m, const struct timeval & n ) { struct timeval diff; diff = abs_tval(sub_tval(m, n)); if (cmp_tval(limit, diff) >= 0) return ::testing::AssertionSuccess(); return ::testing::AssertionFailure() << m_expr << " which is " << timeval_wrap(m) << "\nand\n" << n_expr << " which is " << timeval_wrap(n) << "\nare not close; diff=" << timeval_wrap(diff); }
/* * gettimeofday_cached() * * Clones the event_base_gettimeofday_cached() interface but ensures the * times are always on the gettimeofday() 1970 scale. Older libevent 2 * sometimes used gettimeofday(), sometimes the since-system-start * clock_gettime(CLOCK_MONOTONIC), depending on the platform. * * It is not cleanly possible to tell which timescale older libevent is * using. * * The strategy involves 1 hour thresholds chosen to be far longer than * the duration of a round of libevent callbacks, which share a cached * start-of-round time. First compare the last cached time with the * current gettimeofday() time. If they are within one hour, libevent * is using the proper timescale so leave the offset 0. Otherwise, * compare libevent's cached time and the current time on the monotonic * scale. If they are within an hour, libevent is using the monotonic * scale so calculate the offset to add to such times to bring them to * gettimeofday()'s scale. */ int gettimeofday_cached( struct event_base * b, struct timeval * caller_tv ) { #if defined(_EVENT_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) static struct event_base * cached_b; static struct timeval cached; static struct timeval adj_cached; static struct timeval offset; static int offset_ready; struct timeval latest; struct timeval systemt; struct timespec ts; struct timeval mono; struct timeval diff; int cgt_rc; int gtod_rc; event_base_gettimeofday_cached(b, &latest); if (b == cached_b && !memcmp(&latest, &cached, sizeof(latest))) { *caller_tv = adj_cached; return 0; } cached = latest; cached_b = b; if (!offset_ready) { cgt_rc = clock_gettime(CLOCK_MONOTONIC, &ts); gtod_rc = gettimeofday(&systemt, NULL); if (0 != gtod_rc) { msyslog(LOG_ERR, "%s: gettimeofday() error %m", progname); exit(1); } diff = sub_tval(systemt, latest); if (debug > 1) printf("system minus cached %+ld.%06ld\n", (long)diff.tv_sec, (long)diff.tv_usec); if (0 != cgt_rc || labs((long)diff.tv_sec) < 3600) { /* * Either use_monotonic == 0, or this libevent * has been repaired. Leave offset at zero. */ } else { mono.tv_sec = ts.tv_sec; mono.tv_usec = ts.tv_nsec / 1000; diff = sub_tval(latest, mono); if (debug > 1) printf("cached minus monotonic %+ld.%06ld\n", (long)diff.tv_sec, (long)diff.tv_usec); if (labs((long)diff.tv_sec) < 3600) { /* older libevent2 using monotonic */ offset = sub_tval(systemt, mono); TRACE(1, ("%s: Offsetting libevent CLOCK_MONOTONIC times by %+ld.%06ld\n", "gettimeofday_cached", (long)offset.tv_sec, (long)offset.tv_usec)); } } offset_ready = TRUE; } adj_cached = add_tval(cached, offset); *caller_tv = adj_cached; return 0; #else return event_base_gettimeofday_cached(b, caller_tv); #endif }
int step_systime( double step ) { time_t pivot; /* for ntp era unfolding */ struct timeval timetv, tvlast, tvdiff; struct timespec timets; struct calendar jd; l_fp fp_ofs, fp_sys; /* offset and target system time in FP */ /* * Get pivot time for NTP era unfolding. Since we don't step * very often, we can afford to do the whole calculation from * scratch. And we're not in the time-critical path yet. */ #if SIZEOF_TIME_T > 4 /* * This code makes sure the resulting time stamp for the new * system time is in the 2^32 seconds starting at 1970-01-01, * 00:00:00 UTC. */ pivot = 0x80000000; #if USE_COMPILETIME_PIVOT /* * Add the compile time minus 10 years to get a possible target * area of (compile time - 10 years) to (compile time + 126 * years). This should be sufficient for a given binary of * NTPD. */ if (ntpcal_get_build_date(&jd)) { jd.year -= 10; pivot += ntpcal_date_to_time(&jd); } else { msyslog(LOG_ERR, "step-systime: assume 1970-01-01 as build date"); } #else UNUSED_LOCAL(jd); #endif /* USE_COMPILETIME_PIVOT */ #else UNUSED_LOCAL(jd); /* This makes sure the resulting time stamp is on or after * 1969-12-31/23:59:59 UTC and gives us additional two years, * from the change of NTP era in 2036 to the UNIX rollover in * 2038. (Minus one second, but that won't hurt.) We *really* * need a longer 'time_t' after that! Or a different baseline, * but that would cause other serious trouble, too. */ pivot = 0x7FFFFFFF; #endif /* get the complete jump distance as l_fp */ DTOLFP(sys_residual, &fp_sys); DTOLFP(step, &fp_ofs); L_ADD(&fp_ofs, &fp_sys); /* ---> time-critical path starts ---> */ /* get the current time as l_fp (without fuzz) and as struct timeval */ get_ostime(&timets); fp_sys = tspec_stamp_to_lfp(timets); tvlast.tv_sec = timets.tv_sec; tvlast.tv_usec = (timets.tv_nsec + 500) / 1000; /* get the target time as l_fp */ L_ADD(&fp_sys, &fp_ofs); /* unfold the new system time */ timetv = lfp_stamp_to_tval(fp_sys, &pivot); /* now set new system time */ if (ntp_set_tod(&timetv, NULL) != 0) { msyslog(LOG_ERR, "step-systime: %m"); return FALSE; } /* <--- time-critical path ended with 'ntp_set_tod()' <--- */ sys_residual = 0; lamport_violated = (step < 0); if (step_callback) (*step_callback)(); #ifdef NEED_HPUX_ADJTIME /* * CHECKME: is this correct when called by ntpdate????? */ _clear_adjtime(); #endif /* * FreeBSD, for example, has: * struct utmp { * char ut_line[UT_LINESIZE]; * char ut_name[UT_NAMESIZE]; * char ut_host[UT_HOSTSIZE]; * long ut_time; * }; * and appends line="|", name="date", host="", time for the OLD * and appends line="{", name="date", host="", time for the NEW * to _PATH_WTMP . * * Some OSes have utmp, some have utmpx. */ /* * Write old and new time entries in utmp and wtmp if step * adjustment is greater than one second. * * This might become even Uglier... */ tvdiff = abs_tval(sub_tval(timetv, tvlast)); if (tvdiff.tv_sec > 0) { #ifdef HAVE_UTMP_H struct utmp ut; #endif #ifdef HAVE_UTMPX_H struct utmpx utx; #endif #ifdef HAVE_UTMP_H ZERO(ut); #endif #ifdef HAVE_UTMPX_H ZERO(utx); #endif /* UTMP */ #ifdef UPDATE_UTMP # ifdef HAVE_PUTUTLINE # ifndef _PATH_UTMP # define _PATH_UTMP UTMP_FILE # endif utmpname(_PATH_UTMP); ut.ut_type = OLD_TIME; strlcpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line)); ut.ut_time = tvlast.tv_sec; setutent(); pututline(&ut); ut.ut_type = NEW_TIME; strlcpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line)); ut.ut_time = timetv.tv_sec; setutent(); pututline(&ut); endutent(); # else /* not HAVE_PUTUTLINE */ # endif /* not HAVE_PUTUTLINE */ #endif /* UPDATE_UTMP */ /* UTMPX */ #ifdef UPDATE_UTMPX # ifdef HAVE_PUTUTXLINE utx.ut_type = OLD_TIME; strlcpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line)); utx.ut_tv = tvlast; setutxent(); pututxline(&utx); utx.ut_type = NEW_TIME; strlcpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line)); utx.ut_tv = timetv; setutxent(); pututxline(&utx); endutxent(); # else /* not HAVE_PUTUTXLINE */ # endif /* not HAVE_PUTUTXLINE */ #endif /* UPDATE_UTMPX */ /* WTMP */ #ifdef UPDATE_WTMP # ifdef HAVE_PUTUTLINE # ifndef _PATH_WTMP # define _PATH_WTMP WTMP_FILE # endif utmpname(_PATH_WTMP); ut.ut_type = OLD_TIME; strlcpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line)); ut.ut_time = tvlast.tv_sec; setutent(); pututline(&ut); ut.ut_type = NEW_TIME; strlcpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line)); ut.ut_time = timetv.tv_sec; setutent(); pututline(&ut); endutent(); # else /* not HAVE_PUTUTLINE */ # endif /* not HAVE_PUTUTLINE */ #endif /* UPDATE_WTMP */ /* WTMPX */ #ifdef UPDATE_WTMPX # ifdef HAVE_PUTUTXLINE utx.ut_type = OLD_TIME; utx.ut_tv = tvlast; strlcpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line)); # ifdef HAVE_UPDWTMPX updwtmpx(WTMPX_FILE, &utx); # else /* not HAVE_UPDWTMPX */ # endif /* not HAVE_UPDWTMPX */ # else /* not HAVE_PUTUTXLINE */ # endif /* not HAVE_PUTUTXLINE */ # ifdef HAVE_PUTUTXLINE utx.ut_type = NEW_TIME; utx.ut_tv = timetv; strlcpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line)); # ifdef HAVE_UPDWTMPX updwtmpx(WTMPX_FILE, &utx); # else /* not HAVE_UPDWTMPX */ # endif /* not HAVE_UPDWTMPX */ # else /* not HAVE_PUTUTXLINE */ # endif /* not HAVE_PUTUTXLINE */ #endif /* UPDATE_WTMPX */ } return TRUE; }