diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 529a3e46ca..c4eacb5042 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -2155,15 +2155,6 @@ bgp_marker_all_one (struct stream *s, int length) return 1; } -/* Recent thread time. - On same clock base as bgp_clock (MONOTONIC) - but can be time of last context switch to bgp_read thread. */ -static time_t -bgp_recent_clock (void) -{ - return recent_relative_time().tv_sec; -} - /* Starting point of packet process function. */ int bgp_read (struct thread *thread) @@ -2290,14 +2281,14 @@ bgp_read (struct thread *thread) bgp_open_receive (peer, size); /* XXX return value ignored! */ break; case BGP_MSG_UPDATE: - peer->readtime = bgp_recent_clock (); + peer->readtime = monotime (NULL); bgp_update_receive (peer, size); break; case BGP_MSG_NOTIFY: bgp_notify_receive (peer, size); break; case BGP_MSG_KEEPALIVE: - peer->readtime = bgp_recent_clock (); + peer->readtime = monotime (NULL); bgp_keepalive_receive (peer, size); break; case BGP_MSG_ROUTE_REFRESH_NEW: diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 61d2095659..3602a1e18f 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -348,7 +348,7 @@ time_t bgp_clock (void) { struct timeval tv; - quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv); + monotime(&tv); return tv.tv_sec; } diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 086f5b23da..c1fb062e55 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1149,7 +1149,7 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid) unsigned long long start_time, end_time; /* Get time that can't roll backwards. */ - quagga_gettime(QUAGGA_CLK_MONOTONIC, &time_now); + monotime(&time_now); start_time = time_now.tv_sec; start_time = (start_time * 1000000) + time_now.tv_usec; @@ -1243,7 +1243,7 @@ out: spftree->pending = 0; spftree->runcount++; spftree->last_run_timestamp = time (NULL); - quagga_gettime(QUAGGA_CLK_MONOTONIC, &time_now); + monotime(&time_now); end_time = time_now.tv_sec; end_time = (end_time * 1000000) + time_now.tv_usec; spftree->last_run_duration = end_time - start_time; diff --git a/lib/Makefile.am b/lib/Makefile.am index f2c076c475..5dd38ee45a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -46,7 +46,8 @@ pkginclude_HEADERS = \ ptm_lib.h csv.h bfd.h vrf.h ns.h systemd.h bitfield.h \ fifo.h memory_vty.h mpls.h imsg.h openbsd-queue.h openbsd-tree.h \ skiplist.h qobj.h wheel.h \ - event_counter.h + event_counter.h \ + monotime.h noinst_HEADERS = \ plist_int.h diff --git a/lib/bfd.c b/lib/bfd.c index 5db08fea60..a5edaea217 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -362,7 +362,7 @@ bfd_last_update (time_t last_update, char *buf, size_t len) } /* Get current time. */ - quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv); + monotime(&tv); curr = tv.tv_sec; diff = curr - last_update; tm = gmtime (&diff); diff --git a/lib/log.c b/lib/log.c index 13592a0240..b8e505f347 100644 --- a/lib/log.c +++ b/lib/log.c @@ -118,7 +118,6 @@ quagga_timestamp(int timestamp_precision, char *buf, size_t buflen) } cache; struct timeval clock; - /* would it be sufficient to use global 'recent_time' here? I fear not... */ gettimeofday(&clock, NULL); /* first, we update the cache if the time has changed */ diff --git a/lib/monotime.h b/lib/monotime.h new file mode 100644 index 0000000000..0fd4940431 --- /dev/null +++ b/lib/monotime.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017 David Lamparter, for NetDEF, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FRR_MONOTIME_H +#define _FRR_MONOTIME_H + +#include +#include +#include + +#ifndef TIMESPEC_TO_TIMEVAL +/* should be in sys/time.h on BSD & Linux libcs */ +#define TIMESPEC_TO_TIMEVAL(tv, ts) do { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ + } while (0) +#endif +#ifndef TIMEVAL_TO_TIMESPEC +/* should be in sys/time.h on BSD & Linux libcs */ +#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ + } while (0) +#endif + +static inline time_t monotime(struct timeval *tvo) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + if (tvo) { + TIMESPEC_TO_TIMEVAL(tvo, &ts); + } + return ts.tv_sec; +} + +/* the following two return microseconds, not time_t! + * + * also, they're negative forms of each other, but having both makes the + * code more readable + */ +static inline int64_t monotime_since(const struct timeval *ref, + struct timeval *out) +{ + struct timeval tv; + monotime(&tv); + timersub(&tv, ref, &tv); + if (out) + *out = tv; + return (int64_t)tv.tv_sec * 1000000LL + tv.tv_usec; +} + +static inline int64_t monotime_until(const struct timeval *ref, + struct timeval *out) +{ + struct timeval tv; + monotime(&tv); + timersub(ref, &tv, &tv); + if (out) + *out = tv; + return (int64_t)tv.tv_sec * 1000000LL + tv.tv_usec; +} + +#endif /* _FRR_MONOTIME_H */ diff --git a/lib/thread.c b/lib/thread.c index 64eaae45b9..de7066bb82 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -41,151 +41,16 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats") #include #endif -/* Recent absolute time of day */ -struct timeval recent_time; /* Relative time, since startup */ -static struct timeval relative_time; - static struct hash *cpu_record = NULL; -/* Adjust so that tv_usec is in the range [0,TIMER_SECOND_MICRO). - And change negative values to 0. */ -static struct timeval -timeval_adjust (struct timeval a) -{ - while (a.tv_usec >= TIMER_SECOND_MICRO) - { - a.tv_usec -= TIMER_SECOND_MICRO; - a.tv_sec++; - } - - while (a.tv_usec < 0) - { - a.tv_usec += TIMER_SECOND_MICRO; - a.tv_sec--; - } - - if (a.tv_sec < 0) - /* Change negative timeouts to 0. */ - a.tv_sec = a.tv_usec = 0; - - return a; -} - -static struct timeval -timeval_subtract (struct timeval a, struct timeval b) -{ - struct timeval ret; - - ret.tv_usec = a.tv_usec - b.tv_usec; - ret.tv_sec = a.tv_sec - b.tv_sec; - - return timeval_adjust (ret); -} - -static long -timeval_cmp (struct timeval a, struct timeval b) -{ - return (a.tv_sec == b.tv_sec - ? a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec); -} - -unsigned long +static unsigned long timeval_elapsed (struct timeval a, struct timeval b) { return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO) + (a.tv_usec - b.tv_usec)); } -/* gettimeofday wrapper, to keep recent_time updated */ -static int -quagga_gettimeofday (struct timeval *tv) -{ - int ret; - - assert (tv); - - if (!(ret = gettimeofday (&recent_time, NULL))) - { - /* avoid copy if user passed recent_time pointer.. */ - if (tv != &recent_time) - *tv = recent_time; - return 0; - } - return ret; -} - -static int -quagga_get_relative (struct timeval *tv) -{ - int ret; - -#ifdef HAVE_CLOCK_MONOTONIC - { - struct timespec tp; - if (!(ret = clock_gettime (CLOCK_MONOTONIC, &tp))) - { - relative_time.tv_sec = tp.tv_sec; - relative_time.tv_usec = tp.tv_nsec / 1000; - } - } -#elif defined(__APPLE__) - { - uint64_t ticks; - uint64_t useconds; - static mach_timebase_info_data_t timebase_info; - - ticks = mach_absolute_time(); - if (timebase_info.denom == 0) - mach_timebase_info(&timebase_info); - - useconds = ticks * timebase_info.numer / timebase_info.denom / 1000; - relative_time.tv_sec = useconds / 1000000; - relative_time.tv_usec = useconds % 1000000; - - return 0; - } -#else /* !HAVE_CLOCK_MONOTONIC && !__APPLE__ */ -#error no monotonic clock on this system -#endif /* HAVE_CLOCK_MONOTONIC */ - - if (tv) - *tv = relative_time; - - return ret; -} - -/* Exported Quagga timestamp function. - * Modelled on POSIX clock_gettime. - */ -int -quagga_gettime (enum quagga_clkid clkid, struct timeval *tv) -{ - switch (clkid) - { - case QUAGGA_CLK_MONOTONIC: - return quagga_get_relative (tv); - default: - errno = EINVAL; - return -1; - } -} - -time_t -quagga_monotime (void) -{ - struct timeval tv; - quagga_get_relative(&tv); - return tv.tv_sec; -} - -/* Public export of recent_relative_time by value */ -struct timeval -recent_relative_time (void) -{ - return relative_time; -} - static unsigned int cpu_record_hash_key (struct cpu_thread_history *a) { @@ -437,11 +302,9 @@ thread_timer_cmp(void *a, void *b) struct thread *thread_a = a; struct thread *thread_b = b; - long cmp = timeval_cmp(thread_a->u.sands, thread_b->u.sands); - - if (cmp < 0) + if (timercmp (&thread_a->u.sands, &thread_b->u.sands, <)) return -1; - if (cmp > 0) + if (timercmp (&thread_a->u.sands, &thread_b->u.sands, >)) return 1; return 0; } @@ -671,12 +534,8 @@ thread_master_free (struct thread_master *m) unsigned long thread_timer_remain_second (struct thread *thread) { - quagga_get_relative (NULL); - - if (thread->u.sands.tv_sec - relative_time.tv_sec > 0) - return thread->u.sands.tv_sec - relative_time.tv_sec; - else - return 0; + int64_t remain = monotime_until(&thread->u.sands, NULL) / 1000000LL; + return remain < 0 ? 0 : remain; } #define debugargdef const char *funcname, const char *schedfrom, int fromln @@ -685,9 +544,9 @@ thread_timer_remain_second (struct thread *thread) struct timeval thread_timer_remain(struct thread *thread) { - quagga_get_relative(NULL); - - return timeval_subtract(thread->u.sands, relative_time); + struct timeval remain; + monotime_until(&thread->u.sands, &remain); + return remain; } /* Get new thread. */ @@ -887,7 +746,6 @@ funcname_thread_add_timer_timeval (struct thread_master *m, { struct thread *thread; struct pqueue *queue; - struct timeval alarm_time; assert (m != NULL); @@ -897,11 +755,8 @@ funcname_thread_add_timer_timeval (struct thread_master *m, queue = ((type == THREAD_TIMER) ? m->timer : m->background); thread = thread_get (m, type, func, arg, debugargpass); - /* Do we need jitter here? */ - quagga_get_relative (NULL); - alarm_time.tv_sec = relative_time.tv_sec + time_relative->tv_sec; - alarm_time.tv_usec = relative_time.tv_usec + time_relative->tv_usec; - thread->u.sands = timeval_adjust(alarm_time); + monotime(&thread->u.sands); + timeradd(&thread->u.sands, time_relative, &thread->u.sands); pqueue_enqueue(thread, queue); return thread; @@ -1137,7 +992,7 @@ thread_timer_wait (struct pqueue *queue, struct timeval *timer_val) if (queue->size) { struct thread *next_timer = queue->array[0]; - *timer_val = timeval_subtract (next_timer->u.sands, relative_time); + monotime_until(&next_timer->u.sands, timer_val); return timer_val; } return NULL; @@ -1265,7 +1120,7 @@ thread_timer_process (struct pqueue *queue, struct timeval *timenow) while (queue->size) { thread = queue->array[0]; - if (timeval_cmp (*timenow, thread->u.sands) < 0) + if (timercmp (timenow, &thread->u.sands, <)) return ready; pqueue_dequeue(queue); thread->type = THREAD_READY; @@ -1303,6 +1158,7 @@ thread_fetch (struct thread_master *m, struct thread *fetch) thread_fd_set readfd; thread_fd_set writefd; thread_fd_set exceptfd; + struct timeval now; struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 }; struct timeval timer_val_bg; struct timeval *timer_wait = &timer_val; @@ -1339,15 +1195,20 @@ thread_fetch (struct thread_master *m, struct thread *fetch) /* Calculate select wait timer if nothing else to do */ if (m->ready.count == 0) { - quagga_get_relative (NULL); timer_wait = thread_timer_wait (m->timer, &timer_val); timer_wait_bg = thread_timer_wait (m->background, &timer_val_bg); if (timer_wait_bg && - (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0))) + (!timer_wait || (timercmp (timer_wait, timer_wait_bg, >)))) timer_wait = timer_wait_bg; } + if (timer_wait && timer_wait->tv_sec < 0) + { + timerclear(&timer_val); + timer_wait = &timer_val; + } + num = fd_select (m, FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait); /* Signals should get quick treatment */ @@ -1362,8 +1223,8 @@ thread_fetch (struct thread_master *m, struct thread *fetch) /* Check foreground timers. Historically, they have had higher priority than I/O threads, so let's push them onto the ready list in front of the I/O threads. */ - quagga_get_relative (NULL); - thread_timer_process (m->timer, &relative_time); + monotime(&now); + thread_timer_process (m->timer, &now); /* Got IO, process it */ if (num > 0) @@ -1379,7 +1240,7 @@ thread_fetch (struct thread_master *m, struct thread *fetch) #endif /* Background timer/events, lowest priority */ - thread_timer_process (m->background, &relative_time); + thread_timer_process (m->background, &now); if ((thread = thread_trim_head (&m->ready)) != NULL) return thread_run (m, thread, fetch); @@ -1408,9 +1269,7 @@ thread_consumed_time (RUSAGE_T *now, RUSAGE_T *start, unsigned long *cputime) int thread_should_yield (struct thread *thread) { - quagga_get_relative (NULL); - return (timeval_elapsed(relative_time, thread->real) > - thread->yield); + return monotime_since(&thread->real, NULL) > (int64_t)thread->yield; } void @@ -1422,17 +1281,8 @@ thread_set_yield_time (struct thread *thread, unsigned long yield_time) void thread_getrusage (RUSAGE_T *r) { - quagga_get_relative (NULL); + monotime(&r->real); getrusage(RUSAGE_SELF, &(r->cpu)); - r->real = relative_time; - -#ifdef HAVE_CLOCK_MONOTONIC - /* quagga_get_relative() only updates recent_time if gettimeofday - * based, not when using CLOCK_MONOTONIC. As we export recent_time - * and guarantee to update it before threads are run... - */ - quagga_gettimeofday(&recent_time); -#endif /* HAVE_CLOCK_MONOTONIC */ } struct thread *thread_current = NULL; diff --git a/lib/thread.h b/lib/thread.h index c22bb4828d..a0801e1ecd 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -23,6 +23,7 @@ #define _ZEBRA_THREAD_H #include +#include "monotime.h" struct rusage_t { @@ -239,7 +240,6 @@ extern void thread_call (struct thread *); extern unsigned long thread_timer_remain_second (struct thread *); extern struct timeval thread_timer_remain(struct thread*); extern int thread_should_yield (struct thread *); -extern unsigned long timeval_elapsed (struct timeval a, struct timeval b); /* set yield time for thread */ extern void thread_set_yield_time (struct thread *, unsigned long); @@ -247,13 +247,6 @@ extern void thread_set_yield_time (struct thread *, unsigned long); extern void thread_getrusage (RUSAGE_T *); extern void thread_cmd_init (void); -/* replacements for the system gettimeofday(), clock_gettime() and - * time() functions, providing support for non-decrementing clock on - * all systems, and fully monotonic on /some/ systems. - */ -extern int quagga_gettime (enum quagga_clkid, struct timeval *); -extern time_t quagga_monotime (void); - /* Returns elapsed real (wall clock) time. */ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before, unsigned long *cpu_time_elapsed); @@ -262,8 +255,6 @@ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before, be used instead of calling gettimeofday if a recent value is sufficient. This is guaranteed to be refreshed before a thread is called. */ extern struct timeval recent_time; -/* Similar to recent_time, but a monotonically increasing time value */ -extern struct timeval recent_relative_time (void); /* only for use in logging functions! */ extern struct thread *thread_current; diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index f75a35fa50..2e31535d24 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -433,7 +433,7 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route, else { summary->type = route->type; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &summary->changed); + monotime(&summary->changed); } summary->path.router_bits = route->path.router_bits; diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index d9cf97a713..198526a0eb 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -388,7 +388,7 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa) if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec) { - result = timeval_elapsed (recent_relative_time (), oa->ts_spf); + result = monotime_since(&oa->ts_spf, NULL); if (result/TIMER_SECOND_MICRO > 0) { vty_out (vty, "SPF last executed %ld.%lds ago%s", diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c index 28126918b5..fed5021208 100644 --- a/ospf6d/ospf6_bfd.c +++ b/ospf6d/ospf6_bfd.c @@ -245,7 +245,7 @@ ospf6_bfd_interface_dest_update (int command, struct zclient *zclient, old_status = bfd_info->status; bfd_info->status = status; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv); + monotime(&tv); bfd_info->last_update = tv.tv_sec; if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 14c16c0241..6ac93d8984 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -224,7 +224,7 @@ ospf6_install_lsa (struct ospf6_lsa *lsa) ospf6_flood_clear (old); } - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); if (! OSPF6_LSA_IS_MAXAGE (lsa)) lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa, OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec); @@ -862,7 +862,7 @@ ospf6_receive_lsa (struct ospf6_neighbor *from, if (old) { struct timeval now, res; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &old->installed, &res); time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec/1000); if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) @@ -875,7 +875,7 @@ ospf6_receive_lsa (struct ospf6_neighbor *from, } } - quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received); + monotime(&new->received); if (is_debug) zlog_debug ("Install, Flood, Possibly acknowledge the received LSA"); diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 0ed8d30a8b..c458098099 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -961,7 +961,7 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp) vty_out (vty, " Number of I/F scoped LSAs is %u%s", oi->lsdb->count, VNL); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timerclear (&res); if (oi->thread_send_lsupdate) diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 586bd77f75..d93406fb68 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -1485,11 +1485,11 @@ ospf6_brouter_debug_print (struct ospf6_route *brouter) ospf6_linkstate_prefix2str (&brouter->prefix, destination, sizeof (destination)); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &brouter->installed, &res); timerstring (&res, installed, sizeof (installed)); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &brouter->changed, &res); timerstring (&res, changed, sizeof (changed)); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 06962ec069..bea153c928 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -207,9 +207,7 @@ ospf6_lsa_age_set (struct ospf6_lsa *lsa) assert (lsa && lsa->header); - if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &now) < 0) - zlog_warn ("LSA: quagga_gettime failed, may fail LSA AGEs: %s", - safe_strerror (errno)); + monotime(&now); lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age); lsa->birth.tv_usec = now.tv_usec; @@ -230,9 +228,7 @@ ospf6_lsa_age_current (struct ospf6_lsa *lsa) assert (lsa->header); /* current time */ - if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &now) < 0) - zlog_warn ("LSA: quagga_gettime failed, may fail LSA AGEs: %s", - safe_strerror (errno)); + monotime(&now); if (ntohs (lsa->header->age) >= OSPF_LSA_MAXAGE) { @@ -513,7 +509,7 @@ ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) inet_ntop (AF_INET, &lsa->header->adv_router, adv_router, sizeof (adv_router)); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &lsa->installed, &res); timerstring (&res, duration, sizeof (duration)); diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index e9a25d37e5..578b39a641 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1817,10 +1817,7 @@ ospf6_dbdesc_send (struct thread *thread) if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) && (on->dbdesc_seqnum == 0)) { - struct timeval tv; - if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0) - tv.tv_sec = 1; - on->dbdesc_seqnum = tv.tv_sec; + on->dbdesc_seqnum = monotime(NULL); } dbdesc->options[0] = on->ospf6_if->area->options[0]; diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index e9bb2493ff..ec79a1552b 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -97,7 +97,7 @@ ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi) on->ospf6_if = oi; on->state = OSPF6_NEIGHBOR_DOWN; on->state_change = 0; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed); + monotime(&on->last_changed); on->router_id = router_id; on->summary_list = ospf6_lsdb_create (on); @@ -163,7 +163,7 @@ ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int e return; on->state_change++; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed); + monotime(&on->last_changed); /* log */ if (IS_OSPF6_DEBUG_NEIGHBOR (STATE)) @@ -633,7 +633,7 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on) { char router_id[16]; char duration[16]; - struct timeval now, res; + struct timeval res; char nstate[16]; char deadtime[16]; long h, m, s; @@ -645,13 +645,11 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on) } #endif /*HAVE_GETNAMEINFO*/ - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); - /* Dead time */ h = m = s = 0; if (on->inactivity_timer) { - s = on->inactivity_timer->u.sands.tv_sec - recent_relative_time().tv_sec; + s = monotime_until(&on->inactivity_timer->u.sands, NULL) / 1000000LL; h = s / 3600; s -= h * 3600; m = s / 60; @@ -673,7 +671,7 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on) } /* Duration */ - timersub (&now, &on->last_changed, &res); + monotime_since(&on->last_changed, &res); timerstring (&res, duration, sizeof (duration)); /* @@ -707,7 +705,7 @@ ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on) inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter)); inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter)); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &on->last_changed, &res); timerstring (&res, duration, sizeof (duration)); @@ -731,7 +729,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on) inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter)); inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter)); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &on->last_changed, &res); timerstring (&res, duration, sizeof (duration)); diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 2f416e2689..29956c61a0 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -600,7 +600,7 @@ ospf6_route_add (struct ospf6_route *route, else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) zlog_debug ("%s: route add: %s", ospf6_route_table_name (table), buf); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); node = route_node_get (table->table, &route->prefix); route->rnode = node; @@ -1020,7 +1020,7 @@ ospf6_route_show (struct vty *vty, struct ospf6_route *route) struct listnode *node; struct ospf6_nexthop *nh; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &route->changed, &res); timerstring (&res, duration, sizeof (duration)); @@ -1068,7 +1068,7 @@ ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route) struct listnode *node; struct ospf6_nexthop *nh; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); /* destination */ if (route->type == OSPF6_DEST_TYPE_LINKSTATE) diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 04519e7d46..333ce5588e 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -603,7 +603,7 @@ ospf6_spf_calculation_thread (struct thread *t) ospf6->t_spf_calc = NULL; /* execute SPF calculation */ - quagga_gettime (QUAGGA_CLK_MONOTONIC, &start); + monotime(&start); if (ospf6_is_router_abr (ospf6)) ospf6_abr_range_reset_cost (ospf6); @@ -644,7 +644,7 @@ ospf6_spf_calculation_thread (struct thread *t) if (ospf6_is_router_abr (ospf6)) ospf6_abr_defaults_to_stub (ospf6); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &end); + monotime(&end); timersub (&end, &start, &runtime); ospf6->ts_spf_duration = runtime; @@ -670,7 +670,6 @@ void ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason) { unsigned long delay, elapsed, ht; - struct timeval now, result; ospf6_set_spf_reason(ospf6, reason); @@ -694,11 +693,7 @@ ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason) return; } - /* XXX Monotic timers: we only care about relative time here. */ - now = recent_relative_time (); - timersub (&now, &ospf6->ts_spf, &result); - - elapsed = (result.tv_sec * 1000) + (result.tv_usec / 1000); + elapsed = monotime_since(&ospf6->ts_spf, NULL) / 1000LL; ht = ospf6->spf_holdtime * ospf6->spf_hold_multiplier; if (ht > ospf6->spf_max_holdtime) diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 6da9680fe2..92111c73fc 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -124,7 +124,7 @@ ospf6_create (void) o = XCALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6)); /* initialize */ - quagga_gettime (QUAGGA_CLK_MONOTONIC, &o->starttime); + monotime(&o->starttime); o->area_list = list_new (); o->area_list->cmp = ospf6_area_cmp; o->lsdb = ospf6_lsdb_create (o); @@ -891,7 +891,7 @@ ospf6_show (struct vty *vty, struct ospf6 *o) router_id, VNL); /* running time */ - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); timersub (&now, &o->starttime, &running); timerstring (&running, duration, sizeof (duration)); vty_out (vty, " Running %s%s", duration, VNL); diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index b41e8ff001..f0bc022749 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -58,21 +58,6 @@ extern struct thread_master *master; #define OSPF6_NEIGHBOR(x) ((struct ospf6_neighbor *) (x)) /* operation on timeval structure */ -#ifndef timerclear -#define timerclear(a) (a)->tv_sec = (tvp)->tv_usec = 0 -#endif /*timerclear*/ -#ifndef timersub -#define timersub(a, b, res) \ - do { \ - (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((res)->tv_usec < 0) \ - { \ - (res)->tv_sec--; \ - (res)->tv_usec += 1000000; \ - } \ - } while (0) -#endif /*timersub*/ #define timerstring(tv, buf, size) \ do { \ if ((tv)->tv_sec / 60 / 60 / 24) \ @@ -87,15 +72,6 @@ extern struct thread_master *master; (tv)->tv_sec / 60LL % 60, \ (tv)->tv_sec % 60LL); \ } while (0) -#define timerstring_local(tv, buf, size) \ - do { \ - int ret; \ - struct tm *tm; \ - tm = localtime (&(tv)->tv_sec); \ - ret = strftime (buf, size, "%Y/%m/%d %H:%M:%S", tm); \ - if (ret == 0) \ - zlog_warn ("strftime error"); \ - } while (0) #define threadtimer_string(now, t, buf, size) \ do { \ diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index fe40b10171..b063f317e2 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -649,7 +649,7 @@ ospf_ase_calculate_timer (struct thread *t) { ospf->ase_calc = 0; - quagga_gettime(QUAGGA_CLK_MONOTONIC, &start_time); + monotime(&start_time); /* Calculate external route for each AS-external-LSA */ LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) @@ -681,7 +681,7 @@ ospf_ase_calculate_timer (struct thread *t) ospf->old_external_route = ospf->new_external_route; ospf->new_external_route = route_table_init (); - quagga_gettime(QUAGGA_CLK_MONOTONIC, &stop_time); + monotime(&stop_time); zlog_info ("SPF Processing Time(usecs): External Routes: %lld\n", (stop_time.tv_sec - start_time.tv_sec)*1000000LL+ diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index b4d50a6b9f..74bc38220b 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -249,7 +249,7 @@ ospf_bfd_interface_dest_update (int command, struct zclient *zclient, old_status = bfd_info->status; bfd_info->status = status; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv); + monotime(&tv); bfd_info->last_update = tv.tv_sec; if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 4e9797184d..6e9e59f9b7 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -22,6 +22,7 @@ #include +#include "monotime.h" #include "linklist.h" #include "thread.h" #include "prefix.h" @@ -317,8 +318,8 @@ ospf_timer_dump (struct thread *t, char *buf, size_t size) struct timeval result; if (!t) return "inactive"; - - result = tv_sub (t->u.sands, recent_relative_time()); + + monotime_until (&t->u.sands, &result); return ospf_timeval_dump (&result, buf, size); } diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 7f83ddeaae..417a7aa8d2 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -22,6 +22,7 @@ #include +#include "monotime.h" #include "linklist.h" #include "prefix.h" #include "if.h" @@ -277,8 +278,8 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, "while local one is initial instance."); ; /* Accept this LSA for quick LSDB resynchronization. */ } - else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv), - msec2tv (ospf->min_ls_arrival)) < 0) + else if (monotime_since (¤t->tv_recv, NULL) + < ospf->min_ls_arrival * 1000LL) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("LSA[Flooding]: LSA is received recently."); @@ -969,7 +970,7 @@ ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area) more time for the ACK to be received and avoid retransmissions */ lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - lsa->tv_recv = recent_relative_time (); + monotime(&lsa->tv_recv); lsa->tv_orig = lsa->tv_recv; ospf_flood_through_area (area, NULL, lsa); ospf_lsa_maxage (area->ospf, lsa); @@ -982,7 +983,7 @@ ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa) more time for the ACK to be received and avoid retransmissions */ lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - lsa->tv_recv = recent_relative_time (); + monotime(&lsa->tv_recv); lsa->tv_orig = lsa->tv_recv; ospf_flood_through_as (ospf, NULL, lsa); ospf_lsa_maxage (ospf, lsa); diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 916d4d01c9..cf9943893a 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -22,6 +22,7 @@ #include +#include "monotime.h" #include "linklist.h" #include "prefix.h" #include "if.h" @@ -62,40 +63,6 @@ get_metric (u_char *metric) } -struct timeval -tv_adjust (struct timeval a) -{ - while (a.tv_usec >= 1000000) - { - a.tv_usec -= 1000000; - a.tv_sec++; - } - - while (a.tv_usec < 0) - { - a.tv_usec += 1000000; - a.tv_sec--; - } - - return a; -} - -int -tv_ceil (struct timeval a) -{ - a = tv_adjust (a); - - return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec); -} - -int -tv_floor (struct timeval a) -{ - a = tv_adjust (a); - - return a.tv_sec; -} - struct timeval int2tv (int a) { @@ -115,50 +82,22 @@ msec2tv (int a) ret.tv_sec = a/1000; ret.tv_usec = (a%1000) * 1000; - return tv_adjust (ret); -} - -struct timeval -tv_add (struct timeval a, struct timeval b) -{ - struct timeval ret; - - ret.tv_sec = a.tv_sec + b.tv_sec; - ret.tv_usec = a.tv_usec + b.tv_usec; - - return tv_adjust (ret); -} - -struct timeval -tv_sub (struct timeval a, struct timeval b) -{ - struct timeval ret; - - ret.tv_sec = a.tv_sec - b.tv_sec; - ret.tv_usec = a.tv_usec - b.tv_usec; - - return tv_adjust (ret); -} - -int -tv_cmp (struct timeval a, struct timeval b) -{ - return (a.tv_sec == b.tv_sec ? - a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec); + return ret; } int ospf_lsa_refresh_delay (struct ospf_lsa *lsa) { - struct timeval delta, now; + struct timeval delta; int delay = 0; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); - delta = tv_sub (now, lsa->tv_orig); - - if (tv_cmp (delta, msec2tv (OSPF_MIN_LS_INTERVAL)) < 0) + if (monotime_since (&lsa->tv_orig, &delta) < OSPF_MIN_LS_INTERVAL * 1000LL) { - delay = tv_ceil (tv_sub (msec2tv (OSPF_MIN_LS_INTERVAL), delta)); + struct timeval minv = msec2tv (OSPF_MIN_LS_INTERVAL); + timersub (&minv, &delta, &minv); + + /* TBD: remove padding to full sec, return timeval instead */ + delay = minv.tv_sec + !!minv.tv_usec; if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds", @@ -174,12 +113,10 @@ ospf_lsa_refresh_delay (struct ospf_lsa *lsa) int get_age (struct ospf_lsa *lsa) { - int age; + struct timeval rel; - age = ntohs (lsa->data->ls_age) - + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv)); - - return age; + monotime_since (&lsa->tv_recv, &rel); + return ntohs (lsa->data->ls_age) + rel.tv_sec; } @@ -228,7 +165,7 @@ ospf_lsa_new () new->flags = 0; new->lock = 1; new->retransmit_counter = 0; - new->tv_recv = recent_relative_time (); + monotime(&new->tv_recv); new->tv_orig = new->tv_recv; new->refresh_list = -1; @@ -3701,8 +3638,8 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa) */ delay = (random() % (max_delay - min_delay)) + min_delay; - current_index = ospf->lsa_refresh_queue.index + (quagga_monotime () - - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY; + current_index = ospf->lsa_refresh_queue.index + (monotime(NULL) + - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY; index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY) % (OSPF_LSA_REFRESHER_SLOTS); @@ -3765,7 +3702,7 @@ ospf_lsa_refresh_walker (struct thread *t) modulus. */ ospf->lsa_refresh_queue.index = ((unsigned long)(ospf->lsa_refresh_queue.index + - (quagga_monotime () - ospf->lsa_refresher_started) + (monotime(NULL) - ospf->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS; @@ -3806,7 +3743,7 @@ ospf_lsa_refresh_walker (struct thread *t) ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker, ospf, ospf->lsa_refresh_interval); - ospf->lsa_refresher_started = quagga_monotime (); + ospf->lsa_refresher_started = monotime(NULL); for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa)) { diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 28ecc9d4d6..8b9a0d4c49 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -227,14 +227,8 @@ struct as_external_lsa /* Prototypes. */ /* XXX: Eek, time functions, similar are in lib/thread.c */ -extern struct timeval tv_adjust (struct timeval); -extern int tv_ceil (struct timeval); -extern int tv_floor (struct timeval); extern struct timeval int2tv (int); extern struct timeval msec2tv (int); -extern struct timeval tv_add (struct timeval, struct timeval); -extern struct timeval tv_sub (struct timeval, struct timeval); -extern int tv_cmp (struct timeval, struct timeval); extern int get_age (struct ospf_lsa *); extern u_int16_t ospf_lsa_checksum (struct lsa_header *); diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 17cc1f66c2..ccb82bf8fe 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -630,10 +630,10 @@ nsm_notice_state_change (struct ospf_neighbor *nbr, int next_state, int event) /* Advance in NSM */ if (next_state > nbr->state) - nbr->ts_last_progress = recent_relative_time (); + monotime(&nbr->ts_last_progress); else /* regression in NSM */ { - nbr->ts_last_regress = recent_relative_time (); + monotime(&nbr->ts_last_regress); nbr->last_regress_str = ospf_nsm_event_str [event]; } diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index f7d1d0fa7d..bf78336ad5 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -22,6 +22,7 @@ #include +#include "monotime.h" #include "thread.h" #include "memory.h" #include "linklist.h" @@ -521,16 +522,18 @@ ospf_ls_upd_timer (struct thread *thread) struct ospf_lsa *lsa; if ((lsa = rn->info) != NULL) - /* Don't retransmit an LSA if we received it within - the last RxmtInterval seconds - this is to allow the - neighbour a chance to acknowledge the LSA as it may - have ben just received before the retransmit timer - fired. This is a small tweak to what is in the RFC, - but it will cut out out a lot of retransmit traffic - - MAG */ - if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv), - int2tv (retransmit_interval)) >= 0) - listnode_add (update, rn->info); + { + /* Don't retransmit an LSA if we received it within + the last RxmtInterval seconds - this is to allow the + neighbour a chance to acknowledge the LSA as it may + have ben just received before the retransmit timer + fired. This is a small tweak to what is in the RFC, + but it will cut out out a lot of retransmit traffic + - MAG */ + if (monotime_since (&lsa->tv_recv, NULL) + >= retransmit_interval * 1000000LL) + listnode_add (update, rn->info); + } } } @@ -1469,10 +1472,8 @@ ospf_db_desc (struct ip *iph, struct ospf_header *ospfh, } else { - struct timeval t, now; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); - t = tv_sub (now, nbr->last_send_ts); - if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0) + if (monotime_since (&nbr->last_send_ts, NULL) + < nbr->v_inactivity * 1000000LL) { /* In states Loading and Full the slave must resend its last Database Description packet in response to @@ -2074,12 +2075,8 @@ ospf_ls_upd (struct ospf *ospf, struct ip *iph, struct ospf_header *ospfh, recent) LSA instance. */ else { - struct timeval now; - - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); - - if (tv_cmp (tv_sub (now, current->tv_orig), - msec2tv (ospf->min_ls_arrival)) >= 0) + if (monotime_since (¤t->tv_orig, NULL) + >= ospf->min_ls_arrival * 1000LL) /* Trap NSSA type later.*/ ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT); DISCARD_LSA (lsa, 8); @@ -3577,7 +3574,7 @@ ospf_db_desc_send (struct ospf_neighbor *nbr) if (nbr->last_send) ospf_packet_free (nbr->last_send); nbr->last_send = ospf_packet_dup (op); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts); + monotime(&nbr->last_send_ts); } /* Re-send Database Description. */ diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 5dfd41dd1e..077d0e68ad 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include +#include "monotime.h" #include "thread.h" #include "memory.h" #include "hash.h" @@ -1279,7 +1280,7 @@ ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table, /* Increment SPF Calculation Counter. */ area->spf_calculation++; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &area->ospf->ts_spf); + monotime(&area->ospf->ts_spf); area->ts_spf = area->ospf->ts_spf; if (IS_DEBUG_OSPF_EVENT) @@ -1300,7 +1301,7 @@ ospf_spf_calculate_timer (struct thread *thread) struct route_table *new_table, *new_rtrs; struct ospf_area *area; struct listnode *node, *nnode; - struct timeval start_time, stop_time, spf_start_time; + struct timeval start_time, spf_start_time; int areas_processed = 0; unsigned long ia_time, prune_time, rt_time; unsigned long abr_time, total_spf_time, spf_time; @@ -1311,7 +1312,7 @@ ospf_spf_calculate_timer (struct thread *thread) ospf->t_spf_calc = NULL; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &spf_start_time); + monotime(&spf_start_time); /* Allocate new table tree. */ new_table = route_table_init (); new_rtrs = route_table_init (); @@ -1338,24 +1339,19 @@ ospf_spf_calculate_timer (struct thread *thread) areas_processed++; } - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); - spf_time = timeval_elapsed (stop_time, spf_start_time); + spf_time = monotime_since(&spf_start_time, NULL); ospf_vl_shut_unapproved (ospf); - start_time = stop_time; /* saving a call */ - + monotime(&start_time); ospf_ia_routing (ospf, new_table, new_rtrs); + ia_time = monotime_since(&start_time, NULL); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); - ia_time = timeval_elapsed (stop_time, start_time); - - quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time); + monotime(&start_time); ospf_prune_unreachable_networks (new_table); ospf_prune_unreachable_routers (new_rtrs); + prune_time = monotime_since(&start_time, NULL); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); - prune_time = timeval_elapsed (stop_time, start_time); /* AS-external-LSA calculation should not be performed here. */ /* If new Router Route is installed, @@ -1365,13 +1361,11 @@ ospf_spf_calculate_timer (struct thread *thread) ospf_ase_calculate_timer_add (ospf); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time); - /* Update routing table. */ + monotime(&start_time); ospf_route_install (ospf, new_table); + rt_time = monotime_since(&start_time, NULL); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); - rt_time = timeval_elapsed (stop_time, start_time); /* Update ABR/ASBR routing table */ if (ospf->old_rtrs) { @@ -1383,17 +1377,12 @@ ospf_spf_calculate_timer (struct thread *thread) ospf->old_rtrs = ospf->new_rtrs; ospf->new_rtrs = new_rtrs; - quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time); + monotime(&start_time); if (IS_OSPF_ABR (ospf)) ospf_abr_task (ospf); + abr_time = monotime_since(&start_time, NULL); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); - abr_time = timeval_elapsed (stop_time, start_time); - - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); - total_spf_time = timeval_elapsed (stop_time, spf_start_time); - ospf->ts_spf_duration.tv_sec = total_spf_time/1000000; - ospf->ts_spf_duration.tv_usec = total_spf_time % 1000000; + total_spf_time = monotime_since(&spf_start_time, &ospf->ts_spf_duration); ospf_get_spf_reason_str (rbuf); @@ -1421,7 +1410,6 @@ void ospf_spf_calculate_schedule (struct ospf *ospf, ospf_spf_reason_t reason) { unsigned long delay, elapsed, ht; - struct timeval result; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("SPF: calculation timer scheduled"); @@ -1440,11 +1428,9 @@ ospf_spf_calculate_schedule (struct ospf *ospf, ospf_spf_reason_t reason) (void *)ospf->t_spf_calc); return; } - - /* XXX Monotic timers: we only care about relative time here. */ - result = tv_sub (recent_relative_time (), ospf->ts_spf); - - elapsed = (result.tv_sec * 1000) + (result.tv_usec / 1000); + + elapsed = monotime_since (&ospf->ts_spf, NULL) / 1000; + ht = ospf->spf_holdtime * ospf->spf_hold_multiplier; if (ht > ospf->spf_max_holdtime) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index ce12974d40..2a627f9221 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -23,6 +23,7 @@ #include #include +#include "monotime.h" #include "memory.h" #include "thread.h" #include "prefix.h" @@ -2809,10 +2810,8 @@ show_ip_ospf_area (struct vty *vty, struct ospf_area *area, json_object *json_ar json_object_boolean_true_add(json_area, "indefiniteActiveAdmin"); if (area->t_stub_router) { - struct timeval result; - unsigned long time_store = 0; - result = tv_sub (area->t_stub_router->u.sands, recent_relative_time()); - time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000); + long time_store; + time_store = monotime_until(&area->t_stub_router->u.sands, NULL) / 1000LL; json_object_int_add(json_area, "activeStartupRemainderMsecs", time_store); } } @@ -2971,9 +2970,8 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) { if (use_json) { - unsigned long time_store = 0; - result = tv_sub (ospf->t_deferred_shutdown->u.sands, recent_relative_time()); - time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000); + long time_store; + time_store = monotime_until(&ospf->t_deferred_shutdown->u.sands, NULL) / 1000LL; json_object_int_add(json, "deferredShutdownMsecs", time_store); } else @@ -3066,11 +3064,9 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) { if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) { - unsigned long time_store = 0; + long time_store = 0; - result = tv_sub (recent_relative_time(), ospf->ts_spf); - result = tv_sub (result, recent_relative_time()); - time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000); + time_store = monotime_since(&ospf->ts_spf, NULL) / 1000LL; json_object_int_add(json, "spfLastExecutedMsecs", time_store); time_store = (1000 * ospf->ts_spf_duration.tv_sec) + (ospf->ts_spf_duration.tv_usec / 1000); @@ -3084,7 +3080,7 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) vty_out (vty, " SPF algorithm "); if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) { - result = tv_sub (recent_relative_time(), ospf->ts_spf); + monotime_since(&ospf->ts_spf, &result); vty_out (vty, "last executed %s ago%s", ospf_timeval_dump (&result, timebuf, sizeof (timebuf)), VTY_NEWLINE); @@ -3098,13 +3094,10 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) if (use_json) { - struct timeval temp_time; - unsigned long time_store = 0; - if (ospf->t_spf_calc) { - temp_time = tv_sub (ospf->t_spf_calc->u.sands, recent_relative_time()); - time_store = (1000 * temp_time.tv_sec) + (temp_time.tv_usec / 1000); + long time_store; + time_store = monotime_until(&ospf->t_spf_calc->u.sands, NULL) / 1000LL; json_object_int_add(json, "spfTimerDueInMsecs", time_store); } @@ -3509,16 +3502,9 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct interface char timebuf[OSPF_TIME_DUMP_SIZE]; if (use_json) { - struct timeval result; - unsigned long time_store = 0; - if (oi->t_hello) - result = tv_sub (oi->t_hello->u.sands, recent_relative_time()); - else - { - result.tv_sec = 0; - result.tv_usec = 0; - } - time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000); + long time_store = 0; + if (oi->t_hello) + time_store = monotime_until(&oi->t_hello->u.sands, NULL) / 1000LL; json_object_int_add(json_interface_sub, "timerHelloInMsecs", time_store); } else @@ -3708,11 +3694,9 @@ show_ip_ospf_neighbor_sub (struct vty *vty, struct ospf_interface *oi, json_obje json_neighbor = json_object_new_object(); ospf_nbr_state_message (nbr, msgbuf, 16); - struct timeval result; - unsigned long time_store = 0; + long time_store; - result = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time()); - time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000); + time_store = monotime_until(&nbr->t_inactivity->u.sands, NULL) / 1000LL; json_object_int_add (json_neighbor, "priority", nbr->priority); json_object_string_add (json_neighbor, "state", msgbuf); @@ -4093,9 +4077,8 @@ show_ip_ospf_nbr_nbma_detail_sub (struct vty *vty, struct ospf_interface *oi, st /* Show poll-interval timer. */ if (use_json) { - struct timeval res = tv_sub (nbr_nbma->t_poll->u.sands, recent_relative_time ()); - unsigned long time_store = 0; - time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000); + long time_store; + time_store = monotime_until(&nbr_nbma->t_poll->u.sands, NULL) / 1000LL; json_object_int_add(json_sub, "pollIntervalTimerDueMsec", time_store); } else @@ -4170,11 +4153,12 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi, if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec) { - struct timeval res = tv_sub (recent_relative_time (), nbr->ts_last_progress); + struct timeval res; + long time_store; + + time_store = monotime_since(&nbr->ts_last_progress, &res) / 1000LL; if (use_json) { - unsigned long time_store = 0; - time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000); json_object_int_add(json_sub, "lastPrgrsvChangeMsec", time_store); } else @@ -4189,11 +4173,12 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi, if (nbr->ts_last_regress.tv_sec || nbr->ts_last_regress.tv_usec) { - struct timeval res = tv_sub (recent_relative_time (), nbr->ts_last_regress); + struct timeval res; + long time_store; + + time_store = monotime_since(&nbr->ts_last_regress, &res) / 1000LL; if (use_json) { - unsigned long time_store = 0; - time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000); json_object_int_add(json_sub, "lastRegressiveChangeMsec", time_store); if (nbr->last_regress_str) json_object_string_add(json_sub, "lastRegressiveChangeReason", nbr->last_regress_str); @@ -4234,9 +4219,8 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi, { if (nbr->t_inactivity) { - struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ()); - unsigned long time_store = 0; - time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000); + long time_store; + time_store = monotime_until(&nbr->t_inactivity->u.sands, NULL) / 1000LL; json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store); } else diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index b7542c2a8b..0398bc21b8 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -273,7 +273,7 @@ ospf_new (u_short instance) new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT; new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker, new, new->lsa_refresh_interval); - new->lsa_refresher_started = quagga_monotime (); + new->lsa_refresher_started = monotime(NULL); if ((new->fd = ospf_sock_init()) < 0) { @@ -1583,7 +1583,7 @@ ospf_timers_refresh_set (struct ospf *ospf, int interval) return 1; time_left = ospf->lsa_refresh_interval - - (quagga_monotime () - ospf->lsa_refresher_started); + (monotime(NULL) - ospf->lsa_refresher_started); if (time_left > interval) { @@ -1602,7 +1602,7 @@ ospf_timers_refresh_unset (struct ospf *ospf) int time_left; time_left = ospf->lsa_refresh_interval - - (quagga_monotime () - ospf->lsa_refresher_started); + (monotime(NULL) - ospf->lsa_refresher_started); if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) { diff --git a/tests/test-timer-performance.c b/tests/test-timer-performance.c index ee45ede6ac..a7d09beecc 100644 --- a/tests/test-timer-performance.c +++ b/tests/test-timer-performance.c @@ -61,7 +61,7 @@ int main(int argc, char **argv) for (i = 0; i < SCHEDULE_TIMERS; i++) thread_cancel(timers[i]); - quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv_start); + monotime(&tv_start); for (i = 0; i < SCHEDULE_TIMERS; i++) { @@ -72,7 +72,7 @@ int main(int argc, char **argv) NULL, interval_msec); } - quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv_lap); + monotime(&tv_lap); for (i = 0; i < REMOVE_TIMERS; i++) { @@ -84,7 +84,7 @@ int main(int argc, char **argv) timers[index] = NULL; } - quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv_stop); + monotime(&tv_stop); t_schedule = 1000 * (tv_lap.tv_sec - tv_start.tv_sec); t_schedule += (tv_lap.tv_usec - tv_start.tv_usec) / 1000; diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index d91cda9fb0..afa557096c 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -296,20 +296,6 @@ zfpm_state_to_str (zfpm_state_t state) } } -/* - * zfpm_get_time - */ -static time_t -zfpm_get_time (void) -{ - struct timeval tv; - - if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0) - zlog_warn ("FPM: quagga_gettime failed!!"); - - return tv.tv_sec; -} - /* * zfpm_get_elapsed_time * @@ -320,7 +306,7 @@ zfpm_get_elapsed_time (time_t reference) { time_t now; - now = zfpm_get_time (); + now = monotime(NULL); if (now < reference) { @@ -1179,7 +1165,7 @@ zfpm_connect_cb (struct thread *t) */ zfpm_g->connect_calls++; zfpm_g->stats.connect_calls++; - zfpm_g->last_connect_call_time = zfpm_get_time (); + zfpm_g->last_connect_call_time = monotime(NULL); ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv)); if (ret >= 0) @@ -1533,7 +1519,7 @@ zfpm_clear_stats (struct vty *vty) zfpm_stop_stats_timer (); zfpm_start_stats_timer (); - zfpm_g->last_stats_clear_time = zfpm_get_time(); + zfpm_g->last_stats_clear_time = monotime(NULL); vty_out (vty, "Cleared FPM stats%s", VTY_NEWLINE); } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 315d4832dd..182cfe552d 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -922,7 +922,7 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr } stream_putw_at (s, 0, stream_get_endp (s)); - client->nh_last_upd_time = quagga_monotime(); + client->nh_last_upd_time = monotime(NULL); client->last_write_cmd = cmd; return zebra_server_send_message(client); } diff --git a/zebra/zserv.c b/zebra/zserv.c index 5a46de9ce9..6f72ad1758 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -101,7 +101,7 @@ zserv_flush_data(struct thread *thread) break; } - client->last_write_time = quagga_monotime(); + client->last_write_time = monotime(NULL); return 0; } @@ -135,7 +135,7 @@ zebra_server_send_message(struct zserv *client) break; } - client->last_write_time = quagga_monotime(); + client->last_write_time = monotime(NULL); return 0; } @@ -825,7 +825,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length, s = client->ibuf; - client->nh_reg_time = quagga_monotime(); + client->nh_reg_time = monotime(NULL); while (l < length) { @@ -913,7 +913,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length, rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type); if (rnh) { - client->nh_dereg_time = quagga_monotime(); + client->nh_dereg_time = monotime(NULL); zebra_remove_rnh_client(rnh, client, type); } } @@ -1825,7 +1825,7 @@ zebra_client_create (int sock) /* Set table number. */ client->rtm_table = zebrad.rtm_table_default; - client->connect_time = quagga_monotime(); + client->connect_time = monotime(NULL); /* Initialize flags */ for (afi = AFI_IP; afi < AFI_MAX; afi++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++) @@ -1951,7 +1951,7 @@ zebra_client_read (struct thread *thread) zlog_debug ("zebra message received [%s] %d in VRF %u", zserv_command_string (command), length, vrf_id); - client->last_read_time = quagga_monotime(); + client->last_read_time = monotime(NULL); client->last_read_cmd = command; zvrf = zebra_vrf_lookup_by_id (vrf_id); @@ -2265,7 +2265,7 @@ zserv_time_buf(time_t *time1, char *buf, int buflen) return (buf); } - now = quagga_monotime(); + now = monotime(NULL); now -= *time1; tm = gmtime(&now);