From 7790a2d69ee8439dbed951e77703458bb472dd4f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 23 Jan 2017 16:54:51 +0100 Subject: [PATCH 01/12] lib: time: add new monotime() helpers This adds monotime() to retrieve monotonic clock time, as well as monotime_since() and monotime_until() for relative monotonic time. Signed-off-by: David Lamparter --- lib/Makefile.am | 3 ++- lib/monotime.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 lib/monotime.h 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/monotime.h b/lib/monotime.h new file mode 100644 index 0000000000..10d3bb604d --- /dev/null +++ b/lib/monotime.h @@ -0,0 +1,70 @@ +/* + * 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 + +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 */ From cbf3e3eb3a6452b898b4a082b81e8ec4f9dddb26 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Jan 2017 22:05:56 +0100 Subject: [PATCH 02/12] ospfd: time: replace local helpers with monotime This ditches tv_add, tv_sub, tv_cmp, etc. in favour of monotime{,_since,_until}() which actually makes the code much more readable in some locations. Signed-off-by: David Lamparter --- ospfd/ospf_dump.c | 5 +-- ospfd/ospf_flood.c | 5 +-- ospfd/ospf_lsa.c | 87 +++++++-------------------------------------- ospfd/ospf_lsa.h | 6 ---- ospfd/ospf_packet.c | 37 +++++++++---------- ospfd/ospf_spf.c | 10 +++--- ospfd/ospf_vty.c | 70 ++++++++++++++---------------------- 7 files changed, 66 insertions(+), 154 deletions(-) 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..32dd8e8a91 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."); diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 916d4d01c9..94575d5944 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; } 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_packet.c b/ospfd/ospf_packet.c index f7d1d0fa7d..2aa761d46f 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); diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 5dfd41dd1e..dcbb0151fd 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" @@ -1421,7 +1422,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 +1440,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 From 95ac0ac5ff4146b28c13ba7d821909948b285a5d Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 23 Jan 2017 16:54:56 +0100 Subject: [PATCH 03/12] ospf6d: time: remove unused/duplicate helpers timersub() & timerclear() are in sys/time.h; timerstring_local() is unused. Signed-off-by: David Lamparter --- ospf6d/ospf6d.h | 24 ------------------------ 1 file changed, 24 deletions(-) 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 { \ From 6ced0e7f10d850d51f21200f5d3243cc1b90c453 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Jan 2017 22:46:07 +0100 Subject: [PATCH 04/12] lib: time: remove recent_relative_time() Replace with monotime() [which is not cached]. Signed-off-by: David Lamparter --- bgpd/bgp_packet.c | 13 ++----------- lib/thread.c | 7 ------- lib/thread.h | 2 -- ospf6d/ospf6_area.c | 2 +- ospf6d/ospf6_neighbor.c | 8 +++----- ospf6d/ospf6_spf.c | 7 +------ ospfd/ospf_flood.c | 4 ++-- ospfd/ospf_lsa.c | 2 +- ospfd/ospf_nsm.c | 4 ++-- 9 files changed, 12 insertions(+), 37 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 38470a3c7e..b4f5cc1e8e 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -2153,15 +2153,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) @@ -2288,14 +2279,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/lib/thread.c b/lib/thread.c index 64eaae45b9..711dd3b730 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -179,13 +179,6 @@ quagga_monotime (void) 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) { diff --git a/lib/thread.h b/lib/thread.h index c22bb4828d..a28768e50b 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -262,8 +262,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_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_neighbor.c b/ospf6d/ospf6_neighbor.c index e9bb2493ff..f8a0d7a317 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -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)); /* diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 04519e7d46..9014446374 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -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/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 32dd8e8a91..417a7aa8d2 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -970,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); @@ -983,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 94575d5944..d4811c5b21 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -165,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; 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]; } From 3dad49ca9499dcb917691e10ebc1685dda74cf72 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Jan 2017 22:48:33 +0100 Subject: [PATCH 05/12] lib: time: remove recent_time This isn't even used anywhere. Signed-off-by: David Lamparter --- lib/log.c | 1 - lib/thread.c | 28 ---------------------------- 2 files changed, 29 deletions(-) diff --git a/lib/log.c b/lib/log.c index d48534dc18..4ab8338653 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/thread.c b/lib/thread.c index 711dd3b730..518a69918d 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -41,8 +41,6 @@ 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; @@ -97,24 +95,6 @@ timeval_elapsed (struct timeval a, struct timeval b) + (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) { @@ -1418,14 +1398,6 @@ thread_getrusage (RUSAGE_T *r) quagga_get_relative (NULL); 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; From d9d5c3e8bf8e9bec894ad97a09b0bf435799de1a Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Jan 2017 22:57:57 +0100 Subject: [PATCH 06/12] lib: time: remove local time helpers Signed-off-by: David Lamparter --- lib/thread.c | 65 ++++++++-------------------------------------------- 1 file changed, 9 insertions(+), 56 deletions(-) diff --git a/lib/thread.c b/lib/thread.c index 518a69918d..acec80a636 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -46,48 +46,6 @@ 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 timeval_elapsed (struct timeval a, struct timeval b) { @@ -410,11 +368,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; } @@ -658,9 +614,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. */ @@ -860,7 +816,6 @@ funcname_thread_add_timer_timeval (struct thread_master *m, { struct thread *thread; struct pqueue *queue; - struct timeval alarm_time; assert (m != NULL); @@ -872,9 +827,7 @@ funcname_thread_add_timer_timeval (struct thread_master *m, /* 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); + timeradd (&relative_time, time_relative, &thread->u.sands); pqueue_enqueue(thread, queue); return thread; @@ -1110,7 +1063,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); + timersub (&next_timer->u.sands, &relative_time, timer_val); return timer_val; } return NULL; @@ -1238,7 +1191,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; @@ -1317,7 +1270,7 @@ thread_fetch (struct thread_master *m, struct thread *fetch) 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; } From afe4c21720ed9956ba4034a64508f38d3cedc17e Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 17 Jan 2017 23:07:59 +0100 Subject: [PATCH 07/12] *: remove quagga_gettime() return value checks The next patch will bulk-replace these, and monotime() has time_t as return value, not an error indicator. Signed-off-by: David Lamparter --- ospf6d/ospf6_lsa.c | 8 ++------ ospf6d/ospf6_message.c | 5 +---- zebra/zebra_fpm.c | 20 +++----------------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 06962ec069..92ee9662b7 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)); + quagga_gettime (QUAGGA_CLK_MONOTONIC, &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)); + quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); if (ntohs (lsa->header->age) >= OSPF_LSA_MAXAGE) { diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index e9a25d37e5..229c1ef557 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 = quagga_monotime (); } dbdesc->options[0] = on->ospf6_if->area->options[0]; diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 8b337152b4..d44c75383b 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 = quagga_monotime (); if (now < reference) { @@ -1177,7 +1163,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 = quagga_monotime (); ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv)); if (ret >= 0) @@ -1531,7 +1517,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 = quagga_monotime(); vty_out (vty, "Cleared FPM stats%s", VTY_NEWLINE); } From cf672a865428b5e55844b6d2e01ca9d3bd4afe6b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 18 Jan 2017 01:30:43 +0100 Subject: [PATCH 08/12] *: use monotime() This is largely a bulk-replace made with coccinelle. Signed-off-by: David Lamparter --- bgpd/bgpd.c | 2 +- isisd/isis_spf.c | 4 ++-- lib/bfd.c | 2 +- lib/thread.c | 24 ------------------------ lib/thread.h | 8 +------- ospf6d/ospf6_abr.c | 2 +- ospf6d/ospf6_bfd.c | 2 +- ospf6d/ospf6_flood.c | 6 +++--- ospf6d/ospf6_interface.c | 2 +- ospf6d/ospf6_intra.c | 4 ++-- ospf6d/ospf6_lsa.c | 6 +++--- ospf6d/ospf6_message.c | 2 +- ospf6d/ospf6_neighbor.c | 8 ++++---- ospf6d/ospf6_route.c | 6 +++--- ospf6d/ospf6_spf.c | 4 ++-- ospf6d/ospf6_top.c | 4 ++-- ospfd/ospf_ase.c | 4 ++-- ospfd/ospf_bfd.c | 2 +- ospfd/ospf_lsa.c | 8 ++++---- ospfd/ospf_packet.c | 2 +- ospfd/ospf_spf.c | 22 +++++++++++----------- ospfd/ospfd.c | 6 +++--- tests/test-timer-performance.c | 6 +++--- zebra/zebra_fpm.c | 6 +++--- zebra/zebra_rnh.c | 2 +- zebra/zserv.c | 14 +++++++------- 26 files changed, 64 insertions(+), 94 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 5457822f3b..3cd1ac65c0 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/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/thread.c b/lib/thread.c index acec80a636..cb7676f0e2 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -93,30 +93,6 @@ quagga_get_relative (struct timeval *tv) 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; -} - static unsigned int cpu_record_hash_key (struct cpu_thread_history *a) { diff --git a/lib/thread.h b/lib/thread.h index a28768e50b..348e4e155a 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -23,6 +23,7 @@ #define _ZEBRA_THREAD_H #include +#include "monotime.h" struct rusage_t { @@ -247,13 +248,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); 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_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 92ee9662b7..bea153c928 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -207,7 +207,7 @@ ospf6_lsa_age_set (struct ospf6_lsa *lsa) assert (lsa && lsa->header); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age); lsa->birth.tv_usec = now.tv_usec; @@ -228,7 +228,7 @@ ospf6_lsa_age_current (struct ospf6_lsa *lsa) assert (lsa->header); /* current time */ - quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); + monotime(&now); if (ntohs (lsa->header->age) >= OSPF_LSA_MAXAGE) { @@ -509,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 229c1ef557..578b39a641 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1817,7 +1817,7 @@ ospf6_dbdesc_send (struct thread *thread) if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) && (on->dbdesc_seqnum == 0)) { - on->dbdesc_seqnum = quagga_monotime (); + 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 f8a0d7a317..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)) @@ -705,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)); @@ -729,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 9014446374..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; 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/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_lsa.c b/ospfd/ospf_lsa.c index d4811c5b21..cf9943893a 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -3638,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); @@ -3702,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; @@ -3743,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_packet.c b/ospfd/ospf_packet.c index 2aa761d46f..bf78336ad5 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -3574,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 dcbb0151fd..2b00ff3d74 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -1280,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) @@ -1312,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 (); @@ -1339,7 +1339,7 @@ ospf_spf_calculate_timer (struct thread *thread) areas_processed++; } - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); + monotime(&stop_time); spf_time = timeval_elapsed (stop_time, spf_start_time); ospf_vl_shut_unapproved (ospf); @@ -1348,14 +1348,14 @@ ospf_spf_calculate_timer (struct thread *thread) ospf_ia_routing (ospf, new_table, new_rtrs); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); + monotime(&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); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); + monotime(&stop_time); prune_time = timeval_elapsed (stop_time, start_time); /* AS-external-LSA calculation should not be performed here. */ @@ -1366,12 +1366,12 @@ ospf_spf_calculate_timer (struct thread *thread) ospf_ase_calculate_timer_add (ospf); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time); + monotime(&start_time); /* Update routing table. */ ospf_route_install (ospf, new_table); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); + monotime(&stop_time); rt_time = timeval_elapsed (stop_time, start_time); /* Update ABR/ASBR routing table */ if (ospf->old_rtrs) @@ -1384,14 +1384,14 @@ 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); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); + monotime(&stop_time); abr_time = timeval_elapsed (stop_time, start_time); - quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time); + monotime(&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; 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 d44c75383b..1b2ae29eaa 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -306,7 +306,7 @@ zfpm_get_elapsed_time (time_t reference) { time_t now; - now = quagga_monotime (); + now = monotime(NULL); if (now < reference) { @@ -1163,7 +1163,7 @@ zfpm_connect_cb (struct thread *t) */ zfpm_g->connect_calls++; zfpm_g->stats.connect_calls++; - zfpm_g->last_connect_call_time = quagga_monotime (); + zfpm_g->last_connect_call_time = monotime(NULL); ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv)); if (ret >= 0) @@ -1517,7 +1517,7 @@ zfpm_clear_stats (struct vty *vty) zfpm_stop_stats_timer (); zfpm_start_stats_timer (); - zfpm_g->last_stats_clear_time = quagga_monotime(); + 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 6a15b9a251..dbf4262bd8 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -100,7 +100,7 @@ zserv_flush_data(struct thread *thread) break; } - client->last_write_time = quagga_monotime(); + client->last_write_time = monotime(NULL); return 0; } @@ -134,7 +134,7 @@ zebra_server_send_message(struct zserv *client) break; } - client->last_write_time = quagga_monotime(); + client->last_write_time = monotime(NULL); return 0; } @@ -826,7 +826,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) { @@ -914,7 +914,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); } } @@ -1826,7 +1826,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++) @@ -1952,7 +1952,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); @@ -2263,7 +2263,7 @@ zserv_time_buf(time_t *time1, char *buf, int buflen) return (buf); } - now = quagga_monotime(); + now = monotime(NULL); now -= *time1; tm = gmtime(&now); From 816c2194ca4198767c766d729636fd4af6afedf0 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 23 Jan 2017 18:16:03 +0100 Subject: [PATCH 09/12] ospfd: simplify SPF time consumption calculations monotime_since() does exactly the same thing. ... and timeval_elapsed is now private to lib/thread.c Signed-off-by: David Lamparter --- lib/thread.c | 2 +- lib/thread.h | 1 - ospfd/ospf_spf.c | 30 +++++++++--------------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/lib/thread.c b/lib/thread.c index cb7676f0e2..fe4f5c11c9 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -46,7 +46,7 @@ static struct timeval relative_time; static struct hash *cpu_record = NULL; -unsigned long +static unsigned long timeval_elapsed (struct timeval a, struct timeval b) { return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO) diff --git a/lib/thread.h b/lib/thread.h index 348e4e155a..a0801e1ecd 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -240,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); diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 2b00ff3d74..077d0e68ad 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -1301,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; @@ -1339,24 +1339,19 @@ ospf_spf_calculate_timer (struct thread *thread) areas_processed++; } - monotime(&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); - - monotime(&stop_time); - ia_time = timeval_elapsed (stop_time, start_time); + ia_time = monotime_since(&start_time, NULL); monotime(&start_time); ospf_prune_unreachable_networks (new_table); ospf_prune_unreachable_routers (new_rtrs); + prune_time = monotime_since(&start_time, NULL); - monotime(&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, @@ -1366,13 +1361,11 @@ ospf_spf_calculate_timer (struct thread *thread) ospf_ase_calculate_timer_add (ospf); - monotime(&start_time); - /* Update routing table. */ + monotime(&start_time); ospf_route_install (ospf, new_table); + rt_time = monotime_since(&start_time, NULL); - monotime(&stop_time); - rt_time = timeval_elapsed (stop_time, start_time); /* Update ABR/ASBR routing table */ if (ospf->old_rtrs) { @@ -1387,14 +1380,9 @@ ospf_spf_calculate_timer (struct thread *thread) monotime(&start_time); if (IS_OSPF_ABR (ospf)) ospf_abr_task (ospf); + abr_time = monotime_since(&start_time, NULL); - monotime(&stop_time); - abr_time = timeval_elapsed (stop_time, start_time); - - monotime(&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); From 4b185cb399650082b317809ed7ec18207fef9f5a Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 23 Jan 2017 18:45:43 +0100 Subject: [PATCH 10/12] lib: time: clean out thread.c Remove quagga_get_relative(), replace with monotime(). Signed-off-by: David Lamparter --- lib/thread.c | 72 ++++++++-------------------------------------------- 1 file changed, 11 insertions(+), 61 deletions(-) diff --git a/lib/thread.c b/lib/thread.c index fe4f5c11c9..406eddc9e6 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -42,8 +42,6 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats") #endif /* Relative time, since startup */ -static struct timeval relative_time; - static struct hash *cpu_record = NULL; static unsigned long @@ -53,46 +51,6 @@ timeval_elapsed (struct timeval a, struct timeval b) + (a.tv_usec - b.tv_usec)); } -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; -} - static unsigned int cpu_record_hash_key (struct cpu_thread_history *a) { @@ -576,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 @@ -801,9 +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); - timeradd (&relative_time, time_relative, &thread->u.sands); + monotime(&thread->u.sands); + timeradd(&thread->u.sands, time_relative, &thread->u.sands); pqueue_enqueue(thread, queue); return thread; @@ -1039,7 +992,7 @@ thread_timer_wait (struct pqueue *queue, struct timeval *timer_val) if (queue->size) { struct thread *next_timer = queue->array[0]; - timersub (&next_timer->u.sands, &relative_time, timer_val); + monotime_until(&next_timer->u.sands, timer_val); return timer_val; } return NULL; @@ -1205,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; @@ -1241,7 +1195,6 @@ 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); @@ -1264,8 +1217,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) @@ -1281,7 +1234,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); @@ -1310,9 +1263,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 @@ -1324,9 +1275,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; } struct thread *thread_current = NULL; From e0e2a99068b47824ec563eb24c2ee617499da491 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 23 Jan 2017 18:51:19 +0100 Subject: [PATCH 11/12] lib: cope with negative timeout in thread.c Since time is no longer cached, if we schedule something with zero timeout, it will automatically be negative by the time we reach the event loop. Signed-off-by: David Lamparter --- lib/thread.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/thread.c b/lib/thread.c index 406eddc9e6..de7066bb82 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -1203,6 +1203,12 @@ thread_fetch (struct thread_master *m, struct thread *fetch) 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 */ From 39cea8220a9bcc51d97a7832760591e117cdde7a Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 23 Jan 2017 23:17:35 +0100 Subject: [PATCH 12/12] lib: time: add TIMEVAL_TO_TIMESPEC Should be in system headers, but not specified by any standard. Not currently used anywhere yet. Signed-off-by: David Lamparter --- lib/monotime.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/monotime.h b/lib/monotime.h index 10d3bb604d..0fd4940431 100644 --- a/lib/monotime.h +++ b/lib/monotime.h @@ -28,6 +28,13 @@ (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) {