diff -up ntp-4.2.6p1/include/ntp_refclock.h.sleep ntp-4.2.6p1/include/ntp_refclock.h --- ntp-4.2.6p1/include/ntp_refclock.h.sleep 2009-12-09 08:36:35.000000000 +0100 +++ ntp-4.2.6p1/include/ntp_refclock.h 2010-03-10 19:27:46.000000000 +0100 @@ -260,6 +260,7 @@ extern void refclock_control (sockaddr_u struct refclockstat *); extern int refclock_open (char *, u_int, u_int); extern int refclock_setup (int, u_int, u_int); +extern int refclock_timer_needed (struct peer *); extern void refclock_timer (struct peer *); extern void refclock_transmit (struct peer *); extern int refclock_ioctl (int, u_int); diff -up ntp-4.2.6p1/include/ntp_stdlib.h.sleep ntp-4.2.6p1/include/ntp_stdlib.h --- ntp-4.2.6p1/include/ntp_stdlib.h.sleep 2009-12-09 08:36:35.000000000 +0100 +++ ntp-4.2.6p1/include/ntp_stdlib.h 2010-03-10 19:27:46.000000000 +0100 @@ -116,6 +116,7 @@ extern const char * FindConfig (const ch extern void signal_no_reset (int, RETSIGTYPE (*func)(int)); extern void getauthkeys (const char *); +extern int auth_agekeys_needed (void); extern void auth_agekeys (void); extern void rereadkeys (void); diff -up ntp-4.2.6p1/include/ntpd.h.sleep ntp-4.2.6p1/include/ntpd.h --- ntp-4.2.6p1/include/ntpd.h.sleep 2009-12-09 08:36:35.000000000 +0100 +++ ntp-4.2.6p1/include/ntpd.h 2010-03-10 19:27:46.000000000 +0100 @@ -112,8 +112,10 @@ extern void block_io_and_alarm (void); /* ntp_loopfilter.c */ extern void init_loopfilter(void); extern int local_clock(struct peer *, double); -extern void adj_host_clock(void); +extern int adj_host_clock_needed(void); +extern void adj_host_clock(int); extern void loop_config(int, double); +extern int huffpuff_enabled(void); extern void huffpuff(void); extern u_long sys_clocktime; extern u_int sys_tai; @@ -219,6 +221,8 @@ extern void hack_restrict (int, sockaddr /* ntp_timer.c */ extern void init_timer (void); extern void reinit_timer (void); +extern double get_timeout (l_fp *); +extern int timer_elapsed (l_fp, int); extern void timer (void); extern void timer_clr_stats (void); extern void timer_interfacetimeout (u_long); diff -up ntp-4.2.6p1/libntp/authkeys.c.sleep ntp-4.2.6p1/libntp/authkeys.c --- ntp-4.2.6p1/libntp/authkeys.c.sleep 2009-12-09 08:36:35.000000000 +0100 +++ ntp-4.2.6p1/libntp/authkeys.c 2010-03-10 19:27:46.000000000 +0100 @@ -445,6 +445,25 @@ auth_delkeys(void) } } +int +auth_agekeys_needed(void) { + struct savekey *sk; + int i; + + if (authnumkeys > 20) + return 1; + + for (i = 0; i < HASHSIZE; i++) { + sk = key_hash[i]; + while (sk != 0) { + if (sk->lifetime > 0) + return 1; + sk = sk->next; + } + } + return 0; +} + /* * auth_agekeys - delete keys whose lifetimes have expired */ diff -up ntp-4.2.6p1/ntpd/ntp_loopfilter.c.sleep ntp-4.2.6p1/ntpd/ntp_loopfilter.c --- ntp-4.2.6p1/ntpd/ntp_loopfilter.c.sleep 2009-12-09 08:36:36.000000000 +0100 +++ ntp-4.2.6p1/ntpd/ntp_loopfilter.c 2010-03-10 19:27:46.000000000 +0100 @@ -677,6 +677,13 @@ local_clock( #endif /* LOCKCLOCK */ } +int +adj_host_clock_needed(void) +{ + return !(!ntp_enable || mode_ntpdate || (pll_control && + kern_enable)); +} + /* * adj_host_clock - Called once every second to update the local clock. @@ -686,7 +693,7 @@ local_clock( */ void adj_host_clock( - void + int time_elapsed ) { double adjustment; @@ -698,7 +705,7 @@ adj_host_clock( * since the poll interval can exceed one day, the old test * would be counterproductive. */ - sys_rootdisp += clock_phi; + sys_rootdisp += clock_phi * time_elapsed; #ifndef LOCKCLOCK /* @@ -819,6 +826,12 @@ set_freq( #endif /* KERNEL_PLL */ } +int +huffpuff_enabled(void) +{ + return sys_huffpuff != NULL; +} + /* * huff-n'-puff filter */ diff -up ntp-4.2.6p1/ntpd/ntp_refclock.c.sleep ntp-4.2.6p1/ntpd/ntp_refclock.c --- ntp-4.2.6p1/ntpd/ntp_refclock.c.sleep 2009-12-09 08:36:36.000000000 +0100 +++ ntp-4.2.6p1/ntpd/ntp_refclock.c 2010-03-10 19:27:46.000000000 +0100 @@ -268,6 +268,21 @@ refclock_unpeer( } +int +refclock_timer_needed( + struct peer *peer /* peer structure pointer */ + ) +{ + u_char clktype; + int unit; + + clktype = peer->refclktype; + unit = peer->refclkunit; + if (refclock_conf[clktype]->clock_timer != noentry) + return 1; + return 0; +} + /* * refclock_timer - called once per second for housekeeping. */ diff -up ntp-4.2.6p1/ntpd/ntp_timer.c.sleep ntp-4.2.6p1/ntpd/ntp_timer.c --- ntp-4.2.6p1/ntpd/ntp_timer.c.sleep 2009-12-09 08:36:35.000000000 +0100 +++ ntp-4.2.6p1/ntpd/ntp_timer.c 2010-03-11 15:23:59.000000000 +0100 @@ -56,7 +56,6 @@ static u_long adjust_timer; /* second ti static u_long stats_timer; /* stats timer */ static u_long huffpuff_timer; /* huff-n'-puff timer */ u_long leapsec; /* leapseconds countdown */ -l_fp sys_time; /* current system time */ #ifdef OPENSSL static u_long revoke_timer; /* keys revoke timer */ static u_long keys_timer; /* session key timer */ @@ -74,6 +73,12 @@ volatile u_long alarm_overflow; #define DAY (24 * HOUR) u_long current_time; /* seconds since startup */ +l_fp timer_base; +int time_elapsed; + +#define TIMEOUT_TS_SIZE 2 +l_fp timeout_ts[TIMEOUT_TS_SIZE]; +unsigned int timeout_ts_index; /* * Stats. Number of overflows and number of calls to transmit(). @@ -110,6 +115,8 @@ static RETSIGTYPE alarming (int); void reinit_timer(void) { + get_systime(&timer_base); +#if 0 #if !defined(SYS_WINNT) && !defined(VMS) # if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) timer_gettime(ntpd_timerid, &itimer); @@ -143,6 +150,7 @@ reinit_timer(void) setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); # endif # endif /* VMS */ +#endif } /* @@ -165,6 +173,12 @@ init_timer(void) timer_xmtcalls = 0; timer_timereset = 0; + get_systime(&timer_base); + + for (timeout_ts_index = 0; timeout_ts_index < TIMEOUT_TS_SIZE; timeout_ts_index++) + L_CLR(&timeout_ts[timeout_ts_index]); + timeout_ts_index = 0; +#if 0 #if !defined(SYS_WINNT) /* * Set up the alarm interrupt. The first comes 2**EVENT_TIMEOUT @@ -226,6 +240,7 @@ init_timer(void) } #endif /* SYS_WINNT */ +#endif } #if defined(SYS_WINNT) @@ -236,6 +251,104 @@ get_timer_handle(void) } #endif +double +get_timeout(l_fp *now) +{ + register struct peer *peer, *next_peer; + u_int n; + double r; + int next; + l_fp ts; + + ts = *now; + L_SUB(&ts, &timeout_ts[timeout_ts_index]); + timeout_ts[timeout_ts_index] = *now; + timeout_ts_index = (timeout_ts_index + 1) % TIMEOUT_TS_SIZE; + + /* don't waste CPU time if called too frequently */ + if (ts.l_ui == 0) { + next = 1; + goto finish; + } + + next = current_time + HOUR; + + if (adj_host_clock_needed()) { + next = 1; + goto finish; + } + for (n = 0; n < NTP_HASH_SIZE; n++) { + for (peer = peer_hash[n]; peer != 0; peer = next_peer) { + next_peer = peer->next; +#ifdef REFCLOCK + if (peer->flags & FLAG_REFCLOCK && refclock_timer_needed(peer)) { + next = 1; + goto finish; + } +#endif /* REFCLOCK */ + if (peer->action) + next = min(next, peer->nextaction); + next = min(next, peer->nextdate); + } + } + + if (leapsec > 0) + next = min(next, leapsec); + + if (huffpuff_enabled()) + next = min(next, huffpuff_timer); + +#ifdef OPENSSL + if (auth_agekeys_needed()) + next = min(next, keys_timer); + if (sys_leap != LEAP_NOTINSYNC) + next = min(next, revoke_timer); +#endif /* OPENSSL */ + + if (interface_interval) + next = min(next, interface_timer); + + next = min(next, stats_timer); + + next -= current_time; + if (next <= 0) + next = 1; +finish: + ts = timer_base; + ts.l_ui += next; + L_SUB(&ts, now); + LFPTOD(&ts, r); +#ifdef DEBUG + DPRINTF(2, ("timer: timeout %f\n", r)); +#endif + + return r; +} + +int +timer_elapsed(l_fp now, int timeout) +{ + int elapsed; + + L_SUB(&now, &timer_base); + elapsed = now.l_i; + if (elapsed < 0 || elapsed > timeout + 10) { +#ifdef DEBUG + DPRINTF(2, ("timer: unexpected time jump\n")); +#endif + elapsed = 0; + reinit_timer(); + + } + timer_base.l_ui += elapsed; + time_elapsed += elapsed; + current_time += elapsed; +#ifdef DEBUG + DPRINTF(2, ("timer: time elapsed %d\n", time_elapsed)); +#endif + return time_elapsed; +} + /* * timer - event timer */ @@ -251,11 +364,9 @@ timer(void) * kiss-o'-deatch function and implement the association * polling function.. */ - current_time++; - get_systime(&sys_time); if (adjust_timer <= current_time) { - adjust_timer += 1; - adj_host_clock(); + adjust_timer += time_elapsed; + adj_host_clock(time_elapsed); #ifdef REFCLOCK for (n = 0; n < NTP_HASH_SIZE; n++) { for (peer = peer_hash[n]; peer != 0; peer = next_peer) { @@ -286,7 +397,7 @@ timer(void) * 128 s or less. */ if (peer->throttle > 0) - peer->throttle--; + peer->throttle -= min(peer->throttle, time_elapsed); if (peer->nextdate <= current_time) { #ifdef REFCLOCK if (peer->flags & FLAG_REFCLOCK) @@ -333,7 +444,7 @@ timer(void) * set. */ if (leapsec > 0) { - leapsec--; + leapsec -= min(leapsec, time_elapsed); if (leapsec == 0) { sys_leap = LEAP_NOWARNING; sys_tai = leap_tai; @@ -398,11 +509,15 @@ timer(void) * Finally, write hourly stats. */ if (stats_timer <= current_time) { + l_fp sys_time; + get_systime(&sys_time); stats_timer += HOUR; write_stats(); if (sys_tai != 0 && sys_time.l_ui > leap_expire) report_event(EVNT_LEAPVAL, NULL, NULL); } + + time_elapsed = 0; } diff -up ntp-4.2.6p1/ntpd/ntpd.c.sleep ntp-4.2.6p1/ntpd/ntpd.c --- ntp-4.2.6p1/ntpd/ntpd.c.sleep 2010-03-10 19:27:46.000000000 +0100 +++ ntp-4.2.6p1/ntpd/ntpd.c 2010-03-10 19:27:46.000000000 +0100 @@ -195,8 +195,6 @@ extern const char *Version; char const *progname; -int was_alarmed; - #ifdef DECL_SYSCALL /* * We put this here, since the argument profile is syscall-specific @@ -1033,7 +1031,7 @@ getgroup: #else /* normal I/O */ BLOCK_IO_AND_ALARM(); - was_alarmed = 0; + for (;;) { # if !defined(HAVE_SIGNALED_IO) @@ -1041,42 +1039,39 @@ getgroup: extern int maxactivefd; fd_set rdfdes; - int nfound; -# endif + int nfound, time_elapsed; - if (alarm_flag) /* alarmed? */ - { - was_alarmed = 1; - alarm_flag = 0; - } + time_elapsed = 0; +# endif - if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE) + if (has_full_recv_buffer() == ISC_FALSE) { /* * Nothing to do. Wait for something. */ # ifndef HAVE_SIGNALED_IO + double timeout; + rdfdes = activefds; -# if defined(VMS) || defined(SYS_VXWORKS) - /* make select() wake up after one second */ - { - struct timeval t1; + get_systime(&now); + timeout = get_timeout(&now); - t1.tv_sec = 1; t1.tv_usec = 0; + if (timeout > 0.0) { + struct timeval t1; + + t1.tv_sec = timeout; + t1.tv_usec = (timeout - t1.tv_sec) * 1000000; nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, (fd_set *)0, &t1); - } -# else - nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, - (fd_set *)0, (struct timeval *)0); -# endif /* VMS */ - if (nfound > 0) - { - l_fp ts; + get_systime(&now); + } else + nfound = 0; - get_systime(&ts); + time_elapsed = timer_elapsed(now, timeout); - (void)input_handler(&ts); + if (nfound > 0) + { + (void)input_handler(&now); } else if (nfound == -1 && errno != EINTR) msyslog(LOG_ERR, "select() error: %m"); @@ -1085,17 +1080,13 @@ getgroup: msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound); # endif /* DEBUG */ # else /* HAVE_SIGNALED_IO */ +# error not supported by sleep patch wait_for_signal(); # endif /* HAVE_SIGNALED_IO */ - if (alarm_flag) /* alarmed? */ - { - was_alarmed = 1; - alarm_flag = 0; - } } - if (was_alarmed) + if (time_elapsed > 0) { UNBLOCK_IO_AND_ALARM(); /* @@ -1103,7 +1094,6 @@ getgroup: * to process expiry. */ timer(); - was_alarmed = 0; BLOCK_IO_AND_ALARM(); } @@ -1121,19 +1111,8 @@ getgroup: rbuf = get_full_recv_buffer(); while (rbuf != NULL) { - if (alarm_flag) - { - was_alarmed = 1; - alarm_flag = 0; - } UNBLOCK_IO_AND_ALARM(); - if (was_alarmed) - { /* avoid timer starvation during lengthy I/O handling */ - timer(); - was_alarmed = 0; - } - /* * Call the data procedure to handle each received * packet.