Timers: Replace old timers with microsecond timers
The old timer interface is still kept, but implemented by new timers. The plan is to switch from the old inteface to the new interface, then clean it up.
This commit is contained in:
parent
28a7d3943e
commit
025525266f
20 changed files with 112 additions and 119 deletions
|
@ -452,7 +452,7 @@ config_undo(void)
|
||||||
extern void cmd_reconfig_undo_notify(void);
|
extern void cmd_reconfig_undo_notify(void);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
config_timeout(struct timer *t UNUSED)
|
config_timeout(timer *t UNUSED)
|
||||||
{
|
{
|
||||||
log(L_INFO "Config timeout expired, starting undo");
|
log(L_INFO "Config timeout expired, starting undo");
|
||||||
cmd_reconfig_undo_notify();
|
cmd_reconfig_undo_notify();
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#ifndef _BIRD_BIRDLIB_H_
|
#ifndef _BIRD_BIRDLIB_H_
|
||||||
#define _BIRD_BIRDLIB_H_
|
#define _BIRD_BIRDLIB_H_
|
||||||
|
|
||||||
#include "sysdep/unix/timer.h"
|
|
||||||
#include "lib/alloca.h"
|
#include "lib/alloca.h"
|
||||||
|
|
||||||
/* Ugly structure offset handling macros */
|
/* Ugly structure offset handling macros */
|
||||||
|
@ -70,6 +69,7 @@ static inline int u64_cmp(u64 i1, u64 i2)
|
||||||
/* Microsecond time */
|
/* Microsecond time */
|
||||||
|
|
||||||
typedef s64 btime;
|
typedef s64 btime;
|
||||||
|
typedef s64 bird_clock_t;
|
||||||
|
|
||||||
#define S_ *1000000
|
#define S_ *1000000
|
||||||
#define MS_ *1000
|
#define MS_ *1000
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
tbf_update(struct tbf *f)
|
tbf_update(struct tbf *f)
|
||||||
|
|
11
lib/timer.c
11
lib/timer.c
|
@ -56,6 +56,17 @@ current_time(void)
|
||||||
return timeloop_current()->last_time;
|
return timeloop_current()->last_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btime
|
||||||
|
current_real_time(void)
|
||||||
|
{
|
||||||
|
struct timeloop *loop = timeloop_current();
|
||||||
|
|
||||||
|
if (!loop->real_time)
|
||||||
|
times_update_real_time(loop);
|
||||||
|
|
||||||
|
return loop->real_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define TIMER_LESS(a,b) ((a)->expires < (b)->expires)
|
#define TIMER_LESS(a,b) ((a)->expires < (b)->expires)
|
||||||
#define TIMER_SWAP(heap,a,b,t) (t = heap[a], heap[a] = heap[b], heap[b] = t, \
|
#define TIMER_SWAP(heap,a,b,t) (t = heap[a], heap[a] = heap[b], heap[b] = t, \
|
||||||
|
|
12
lib/timer.h
12
lib/timer.h
|
@ -44,6 +44,11 @@ static inline timer2 *timers_first(struct timeloop *loop)
|
||||||
extern struct timeloop main_timeloop;
|
extern struct timeloop main_timeloop;
|
||||||
|
|
||||||
btime current_time(void);
|
btime current_time(void);
|
||||||
|
btime current_real_time(void);
|
||||||
|
|
||||||
|
#define now (current_time() TO_S)
|
||||||
|
#define now_real (current_real_time() TO_S)
|
||||||
|
extern btime boot_time;
|
||||||
|
|
||||||
timer2 *tm2_new(pool *p);
|
timer2 *tm2_new(pool *p);
|
||||||
void tm2_set(timer2 *t, btime when);
|
void tm2_set(timer2 *t, btime when);
|
||||||
|
@ -59,8 +64,8 @@ tm2_active(timer2 *t)
|
||||||
static inline btime
|
static inline btime
|
||||||
tm2_remains(timer2 *t)
|
tm2_remains(timer2 *t)
|
||||||
{
|
{
|
||||||
btime now = current_time();
|
btime now_ = current_time();
|
||||||
return (t->expires > now) ? (t->expires - now) : 0;
|
return (t->expires > now_) ? (t->expires - now_) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline timer2 *
|
static inline timer2 *
|
||||||
|
@ -81,18 +86,17 @@ tm2_set_max(timer2 *t, btime when)
|
||||||
tm2_set(t, when);
|
tm2_set(t, when);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
static inline void
|
static inline void
|
||||||
tm2_start_max(timer2 *t, btime after)
|
tm2_start_max(timer2 *t, btime after)
|
||||||
{
|
{
|
||||||
btime rem = tm2_remains(t);
|
btime rem = tm2_remains(t);
|
||||||
tm2_start(t, MAX_(rem, after));
|
tm2_start(t, MAX_(rem, after));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/* In sysdep code */
|
/* In sysdep code */
|
||||||
void times_init(struct timeloop *loop);
|
void times_init(struct timeloop *loop);
|
||||||
void times_update(struct timeloop *loop);
|
void times_update(struct timeloop *loop);
|
||||||
|
void times_update_real_time(struct timeloop *loop);
|
||||||
|
|
||||||
/* For I/O loop */
|
/* For I/O loop */
|
||||||
void timers_init(struct timeloop *loop, pool *p);
|
void timers_init(struct timeloop *loop, pool *p);
|
||||||
|
|
|
@ -28,7 +28,7 @@ cmd_show_status(void)
|
||||||
tm_format_datetime(tim, &config->tf_base, now);
|
tm_format_datetime(tim, &config->tf_base, now);
|
||||||
cli_msg(-1011, "Router ID is %R", config->router_id);
|
cli_msg(-1011, "Router ID is %R", config->router_id);
|
||||||
cli_msg(-1011, "Current server time is %s", tim);
|
cli_msg(-1011, "Current server time is %s", tim);
|
||||||
tm_format_datetime(tim, &config->tf_base, boot_time);
|
tm_format_datetime(tim, &config->tf_base, boot_time TO_S);
|
||||||
cli_msg(-1011, "Last reboot on %s", tim);
|
cli_msg(-1011, "Last reboot on %s", tim);
|
||||||
tm_format_datetime(tim, &config->tf_base, config->load_time);
|
tm_format_datetime(tim, &config->tf_base, config->load_time);
|
||||||
cli_msg(-1011, "Last reconfiguration on %s", tim);
|
cli_msg(-1011, "Last reconfiguration on %s", tim);
|
||||||
|
|
|
@ -43,7 +43,7 @@ static char *c_states[] = { "DOWN", "START", "UP", "FLUSHING" };
|
||||||
|
|
||||||
extern struct protocol proto_unix_iface;
|
extern struct protocol proto_unix_iface;
|
||||||
|
|
||||||
static void proto_shutdown_loop(struct timer *);
|
static void proto_shutdown_loop(timer *);
|
||||||
static void proto_rethink_goal(struct proto *p);
|
static void proto_rethink_goal(struct proto *p);
|
||||||
static char *proto_state_name(struct proto *p);
|
static char *proto_state_name(struct proto *p);
|
||||||
static void channel_verify_limits(struct channel *c);
|
static void channel_verify_limits(struct channel *c);
|
||||||
|
@ -1046,7 +1046,7 @@ proto_rethink_goal(struct proto *p)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void graceful_restart_done(struct timer *t);
|
static void graceful_restart_done(timer *t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* graceful_restart_recovery - request initial graceful restart recovery
|
* graceful_restart_recovery - request initial graceful restart recovery
|
||||||
|
@ -1099,7 +1099,7 @@ graceful_restart_init(void)
|
||||||
* restart wait timer fires (but there are still some locks).
|
* restart wait timer fires (but there are still some locks).
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
graceful_restart_done(struct timer *t UNUSED)
|
graceful_restart_done(timer *t UNUSED)
|
||||||
{
|
{
|
||||||
log(L_INFO "Graceful restart done");
|
log(L_INFO "Graceful restart done");
|
||||||
graceful_restart_state = GRS_DONE;
|
graceful_restart_state = GRS_DONE;
|
||||||
|
@ -1298,7 +1298,7 @@ protos_build(void)
|
||||||
int proto_restart;
|
int proto_restart;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proto_shutdown_loop(struct timer *t UNUSED)
|
proto_shutdown_loop(timer *t UNUSED)
|
||||||
{
|
{
|
||||||
struct proto *p, *p_next;
|
struct proto *p, *p_next;
|
||||||
|
|
||||||
|
|
|
@ -1367,7 +1367,7 @@ babel_iface_timer(timer *t)
|
||||||
static inline void
|
static inline void
|
||||||
babel_iface_kick_timer(struct babel_iface *ifa)
|
babel_iface_kick_timer(struct babel_iface *ifa)
|
||||||
{
|
{
|
||||||
if (ifa->timer->expires > (now + 1))
|
if (ifa->timer->expires TO_S > (now + 1))
|
||||||
tm_start(ifa->timer, 1);
|
tm_start(ifa->timer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1948,7 +1948,7 @@ babel_timer(timer *t)
|
||||||
static inline void
|
static inline void
|
||||||
babel_kick_timer(struct babel_proto *p)
|
babel_kick_timer(struct babel_proto *p)
|
||||||
{
|
{
|
||||||
if (p->timer->expires > (now + 1))
|
if (p->timer->expires TO_S > (now + 1))
|
||||||
tm_start(p->timer, 1);
|
tm_start(p->timer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,8 @@
|
||||||
|
|
||||||
#undef LOCAL_DEBUG
|
#undef LOCAL_DEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
#include "nest/iface.h"
|
#include "nest/iface.h"
|
||||||
#include "nest/protocol.h"
|
#include "nest/protocol.h"
|
||||||
|
@ -324,8 +326,8 @@ bgp_start_timer(timer *t, int value)
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
/* The randomization procedure is specified in RFC 1771: 9.2.3.3 */
|
/* The randomization procedure is specified in RFC 1771: 9.2.3.3 */
|
||||||
t->randomize = value / 4;
|
int randomize = random() % ((value / 4) + 1);
|
||||||
tm_start(t, value - t->randomize);
|
tm_start(t, value - randomize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tm_stop(t);
|
tm_stop(t);
|
||||||
|
@ -2006,17 +2008,18 @@ bgp_show_proto_info(struct proto *P)
|
||||||
struct bgp_conn *oc = &p->outgoing_conn;
|
struct bgp_conn *oc = &p->outgoing_conn;
|
||||||
|
|
||||||
if ((p->start_state < BSS_CONNECT) &&
|
if ((p->start_state < BSS_CONNECT) &&
|
||||||
(p->startup_timer->expires))
|
(tm_active(p->startup_timer)))
|
||||||
cli_msg(-1006, " Error wait: %d/%d",
|
cli_msg(-1006, " Error wait: %d/%d",
|
||||||
p->startup_timer->expires - now, p->startup_delay);
|
(int) tm_remains(p->startup_timer), p->startup_delay);
|
||||||
|
|
||||||
if ((oc->state == BS_ACTIVE) &&
|
if ((oc->state == BS_ACTIVE) &&
|
||||||
(oc->connect_timer->expires))
|
(tm_active(oc->connect_timer)))
|
||||||
cli_msg(-1006, " Connect delay: %d/%d",
|
cli_msg(-1006, " Connect delay: %d/%d",
|
||||||
oc->connect_timer->expires - now, p->cf->connect_delay_time);
|
(int) tm_remains(oc->connect_timer), p->cf->connect_delay_time);
|
||||||
|
|
||||||
if (p->gr_active_num && p->gr_timer->expires)
|
if (p->gr_active_num && tm_active(p->gr_timer))
|
||||||
cli_msg(-1006, " Restart timer: %d/-", p->gr_timer->expires - now);
|
cli_msg(-1006, " Restart timer: %d/-",
|
||||||
|
(int) tm_remains(p->gr_timer));
|
||||||
}
|
}
|
||||||
else if (P->proto_state == PS_UP)
|
else if (P->proto_state == PS_UP)
|
||||||
{
|
{
|
||||||
|
|
|
@ -210,10 +210,10 @@ struct bgp_conn {
|
||||||
|
|
||||||
struct bgp_caps *local_caps;
|
struct bgp_caps *local_caps;
|
||||||
struct bgp_caps *remote_caps;
|
struct bgp_caps *remote_caps;
|
||||||
struct timer *connect_timer;
|
timer *connect_timer;
|
||||||
struct timer *hold_timer;
|
timer *hold_timer;
|
||||||
struct timer *keepalive_timer;
|
timer *keepalive_timer;
|
||||||
struct event *tx_ev;
|
event *tx_ev;
|
||||||
u32 packets_to_send; /* Bitmap of packet types to be sent */
|
u32 packets_to_send; /* Bitmap of packet types to be sent */
|
||||||
u32 channels_to_send; /* Bitmap of channels with packets to be sent */
|
u32 channels_to_send; /* Bitmap of channels with packets to be sent */
|
||||||
u8 last_channel; /* Channel used last time for TX */
|
u8 last_channel; /* Channel used last time for TX */
|
||||||
|
@ -254,9 +254,9 @@ struct bgp_proto {
|
||||||
struct bfd_request *bfd_req; /* BFD request, if BFD is used */
|
struct bfd_request *bfd_req; /* BFD request, if BFD is used */
|
||||||
ip_addr source_addr; /* Local address used as an advertised next hop */
|
ip_addr source_addr; /* Local address used as an advertised next hop */
|
||||||
ip_addr link_addr; /* Link-local version of source_addr */
|
ip_addr link_addr; /* Link-local version of source_addr */
|
||||||
struct event *event; /* Event for respawning and shutting process */
|
event *event; /* Event for respawning and shutting process */
|
||||||
struct timer *startup_timer; /* Timer used to delay protocol startup due to previous errors (startup_delay) */
|
timer *startup_timer; /* Timer used to delay protocol startup due to previous errors (startup_delay) */
|
||||||
struct timer *gr_timer; /* Timer waiting for reestablishment after graceful restart */
|
timer *gr_timer; /* Timer waiting for reestablishment after graceful restart */
|
||||||
unsigned startup_delay; /* Time to delay protocol startup by due to errors */
|
unsigned startup_delay; /* Time to delay protocol startup by due to errors */
|
||||||
bird_clock_t last_proto_error; /* Time of last error that leads to protocol stop */
|
bird_clock_t last_proto_error; /* Time of last error that leads to protocol stop */
|
||||||
u8 last_error_class; /* Error class of last error */
|
u8 last_error_class; /* Error class of last error */
|
||||||
|
@ -422,7 +422,7 @@ extern struct linpool *bgp_linpool;
|
||||||
extern struct linpool *bgp_linpool2;
|
extern struct linpool *bgp_linpool2;
|
||||||
|
|
||||||
|
|
||||||
void bgp_start_timer(struct timer *t, int value);
|
void bgp_start_timer(timer *t, int value);
|
||||||
void bgp_check_config(struct bgp_config *c);
|
void bgp_check_config(struct bgp_config *c);
|
||||||
void bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len);
|
void bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len);
|
||||||
void bgp_close_conn(struct bgp_conn *c);
|
void bgp_close_conn(struct bgp_conn *c);
|
||||||
|
|
|
@ -715,9 +715,9 @@ ospf_iface_change_timer(timer *tm, uint val)
|
||||||
if (!tm)
|
if (!tm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tm->recurrent = val;
|
tm->recurrent = val S;
|
||||||
|
|
||||||
if (tm->expires)
|
if (tm_active(tm))
|
||||||
tm_start(tm, val);
|
tm_start(tm, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -654,7 +654,7 @@ ospf_sh_neigh_info(struct ospf_neighbor *n)
|
||||||
char etime[6];
|
char etime[6];
|
||||||
int exp, sec, min;
|
int exp, sec, min;
|
||||||
|
|
||||||
exp = n->inactim->expires - now;
|
exp = tm_remains(n->inactim);
|
||||||
sec = exp % 60;
|
sec = exp % 60;
|
||||||
min = exp / 60;
|
min = exp / 60;
|
||||||
if (min > 59)
|
if (min > 59)
|
||||||
|
|
|
@ -676,7 +676,7 @@ ospf_reconfigure(struct proto *P, struct proto_config *CF)
|
||||||
p->asbr = new->asbr;
|
p->asbr = new->asbr;
|
||||||
p->ecmp = new->ecmp;
|
p->ecmp = new->ecmp;
|
||||||
p->tick = new->tick;
|
p->tick = new->tick;
|
||||||
p->disp_timer->recurrent = p->tick;
|
p->disp_timer->recurrent = p->tick S;
|
||||||
tm_start(p->disp_timer, 1);
|
tm_start(p->disp_timer, 1);
|
||||||
|
|
||||||
/* Mark all areas and ifaces */
|
/* Mark all areas and ifaces */
|
||||||
|
|
|
@ -154,12 +154,7 @@ radv_iface_new(struct radv_proto *p, struct iface *iface, struct radv_iface_conf
|
||||||
|
|
||||||
add_tail(&p->iface_list, NODE ifa);
|
add_tail(&p->iface_list, NODE ifa);
|
||||||
|
|
||||||
timer *tm = tm_new(pool);
|
ifa->timer = tm_new_set(pool, radv_timer, ifa, 0, 0);
|
||||||
tm->hook = radv_timer;
|
|
||||||
tm->data = ifa;
|
|
||||||
tm->randomize = 0;
|
|
||||||
tm->recurrent = 0;
|
|
||||||
ifa->timer = tm;
|
|
||||||
|
|
||||||
struct object_lock *lock = olock_new(pool);
|
struct object_lock *lock = olock_new(pool);
|
||||||
lock->addr = IPA_NONE;
|
lock->addr = IPA_NONE;
|
||||||
|
|
|
@ -902,7 +902,7 @@ rip_timer(timer *t)
|
||||||
static inline void
|
static inline void
|
||||||
rip_kick_timer(struct rip_proto *p)
|
rip_kick_timer(struct rip_proto *p)
|
||||||
{
|
{
|
||||||
if (p->timer->expires > (now + 1))
|
if (p->timer->expires TO_S > (now + 1))
|
||||||
tm_start(p->timer, 1); /* Or 100 ms */
|
tm_start(p->timer, 1); /* Or 100 ms */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,7 +962,7 @@ rip_iface_timer(timer *t)
|
||||||
static inline void
|
static inline void
|
||||||
rip_iface_kick_timer(struct rip_iface *ifa)
|
rip_iface_kick_timer(struct rip_iface *ifa)
|
||||||
{
|
{
|
||||||
if (ifa->timer->expires > (now + 1))
|
if (ifa->timer->expires TO_S > (now + 1))
|
||||||
tm_start(ifa->timer, 1); /* Or 100 ms */
|
tm_start(ifa->timer, 1); /* Or 100 ms */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -382,7 +382,7 @@ rpki_do_we_recv_prefix_pdu_in_last_seconds(struct rpki_cache *cache)
|
||||||
* |End of Data| PDU and has run by some &ERROR is occurred.
|
* |End of Data| PDU and has run by some &ERROR is occurred.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
rpki_refresh_hook(struct timer *tm)
|
rpki_refresh_hook(timer *tm)
|
||||||
{
|
{
|
||||||
struct rpki_cache *cache = tm->data;
|
struct rpki_cache *cache = tm->data;
|
||||||
|
|
||||||
|
@ -428,7 +428,7 @@ rpki_refresh_hook(struct timer *tm)
|
||||||
* ends by reaching of &ESTABLISHED state again.
|
* ends by reaching of &ESTABLISHED state again.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
rpki_retry_hook(struct timer *tm)
|
rpki_retry_hook(timer *tm)
|
||||||
{
|
{
|
||||||
struct rpki_cache *cache = tm->data;
|
struct rpki_cache *cache = tm->data;
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ rpki_retry_hook(struct timer *tm)
|
||||||
* of the protocol.
|
* of the protocol.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
rpki_expire_hook(struct timer *tm)
|
rpki_expire_hook(timer *tm)
|
||||||
{
|
{
|
||||||
struct rpki_cache *cache = tm->data;
|
struct rpki_cache *cache = tm->data;
|
||||||
|
|
||||||
|
@ -789,8 +789,8 @@ rpki_get_status(struct proto *P, byte *buf)
|
||||||
static void
|
static void
|
||||||
rpki_show_proto_info_timer(const char *name, uint num, timer *t)
|
rpki_show_proto_info_timer(const char *name, uint num, timer *t)
|
||||||
{
|
{
|
||||||
if (t->expires)
|
if (tm_active(t))
|
||||||
cli_msg(-1006, " %-17s %us (remains %us)", name, num, tm_remains(t));
|
cli_msg(-1006, " %-17s %us (remains %ds)", name, num, (int) tm_remains(t));
|
||||||
else
|
else
|
||||||
cli_msg(-1006, " %-17s ---", name);
|
cli_msg(-1006, " %-17s ---", name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,11 +122,13 @@ tracked_fopen(pool *p, char *name, char *mode)
|
||||||
* for the other fields see |timer.h|.
|
* for the other fields see |timer.h|.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define NEAR_TIMER_LIMIT 4
|
#define NEAR_TIMER_LIMIT 4
|
||||||
|
|
||||||
static list near_timers, far_timers;
|
static list near_timers, far_timers;
|
||||||
static bird_clock_t first_far_timer = TIME_INFINITY;
|
static bird_clock_t first_far_timer = TIME_INFINITY;
|
||||||
|
|
||||||
|
|
||||||
/* now must be different from 0, because 0 is a special value in timer->expires */
|
/* now must be different from 0, because 0 is a special value in timer->expires */
|
||||||
bird_clock_t now = 1, now_real, boot_time;
|
bird_clock_t now = 1, now_real, boot_time;
|
||||||
|
|
||||||
|
@ -183,7 +185,6 @@ init_times(void)
|
||||||
log(L_WARN "Monotonic timer is missing");
|
log(L_WARN "Monotonic timer is missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tm_free(resource *r)
|
tm_free(resource *r)
|
||||||
{
|
{
|
||||||
|
@ -382,6 +383,7 @@ tm_shot(void)
|
||||||
t->hook(t);
|
t->hook(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tm_parse_datetime - parse a date and time
|
* tm_parse_datetime - parse a date and time
|
||||||
|
@ -484,6 +486,8 @@ tm_format_datetime(char *x, struct timeformat *fmt_spec, bird_clock_t t)
|
||||||
* Time clock
|
* Time clock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
btime boot_time;
|
||||||
|
|
||||||
void
|
void
|
||||||
times_init(struct timeloop *loop)
|
times_init(struct timeloop *loop)
|
||||||
{
|
{
|
||||||
|
@ -520,6 +524,19 @@ times_update(struct timeloop *loop)
|
||||||
loop->real_time = 0;
|
loop->real_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
times_update_real_time(struct timeloop *loop)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
if (rv < 0)
|
||||||
|
die("clock_gettime: %m");
|
||||||
|
|
||||||
|
loop->real_time = ((s64) ts.tv_sec S) + (ts.tv_nsec / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOC: Sockets
|
* DOC: Sockets
|
||||||
|
@ -2349,9 +2366,6 @@ io_update_time(void)
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (!clock_monotonic_available)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is third time-tracking procedure (after update_times() above and
|
* This is third time-tracking procedure (after update_times() above and
|
||||||
* times_update() in BFD), dedicated to internal event log and latency
|
* times_update() in BFD), dedicated to internal event log and latency
|
||||||
|
@ -2490,14 +2504,12 @@ volatile int async_shutdown_flag;
|
||||||
void
|
void
|
||||||
io_init(void)
|
io_init(void)
|
||||||
{
|
{
|
||||||
init_list(&near_timers);
|
|
||||||
init_list(&far_timers);
|
|
||||||
init_list(&sock_list);
|
init_list(&sock_list);
|
||||||
init_list(&global_event_list);
|
init_list(&global_event_list);
|
||||||
krt_io_init();
|
krt_io_init();
|
||||||
init_times();
|
// XXX init_times();
|
||||||
update_times();
|
// XXX update_times();
|
||||||
boot_time = now;
|
boot_time = current_time();
|
||||||
srandom((int) now_real);
|
srandom((int) now_real);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2508,7 +2520,6 @@ void
|
||||||
io_loop(void)
|
io_loop(void)
|
||||||
{
|
{
|
||||||
int poll_tout, timeout;
|
int poll_tout, timeout;
|
||||||
time_t tout;
|
|
||||||
int nfds, events, pout;
|
int nfds, events, pout;
|
||||||
timer2 *t;
|
timer2 *t;
|
||||||
sock *s;
|
sock *s;
|
||||||
|
@ -2522,17 +2533,10 @@ io_loop(void)
|
||||||
times_update(&main_timeloop);
|
times_update(&main_timeloop);
|
||||||
events = ev_run_list(&global_event_list);
|
events = ev_run_list(&global_event_list);
|
||||||
timers_fire(&main_timeloop);
|
timers_fire(&main_timeloop);
|
||||||
timers:
|
|
||||||
update_times();
|
|
||||||
tout = tm_first_shot();
|
|
||||||
if (tout <= now)
|
|
||||||
{
|
|
||||||
tm_shot();
|
|
||||||
goto timers;
|
|
||||||
}
|
|
||||||
io_close_event();
|
io_close_event();
|
||||||
|
|
||||||
poll_tout = (events ? 0 : MIN(tout - now, 3)) * 1000; /* Time in milliseconds */
|
// FIXME
|
||||||
|
poll_tout = (events ? 0 : 3000); /* Time in milliseconds */
|
||||||
if (t = timers_first(&main_timeloop))
|
if (t = timers_first(&main_timeloop))
|
||||||
{
|
{
|
||||||
times_update(&main_timeloop);
|
times_update(&main_timeloop);
|
||||||
|
|
|
@ -122,7 +122,7 @@ kif_force_scan(void)
|
||||||
void
|
void
|
||||||
kif_request_scan(void)
|
kif_request_scan(void)
|
||||||
{
|
{
|
||||||
if (kif_proto && kif_scan_timer->expires > now)
|
if (kif_proto && (kif_scan_timer->expires TO_S > (now + 1)))
|
||||||
tm_start(kif_scan_timer, 1);
|
tm_start(kif_scan_timer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ kif_start(struct proto *P)
|
||||||
kif_scan_timer = tm_new(P->pool);
|
kif_scan_timer = tm_new(P->pool);
|
||||||
kif_scan_timer->hook = kif_scan;
|
kif_scan_timer->hook = kif_scan;
|
||||||
kif_scan_timer->data = p;
|
kif_scan_timer->data = p;
|
||||||
kif_scan_timer->recurrent = KIF_CF->scan_time;
|
kif_scan_timer->recurrent = KIF_CF->scan_time S;
|
||||||
kif_scan(kif_scan_timer);
|
kif_scan(kif_scan_timer);
|
||||||
tm_start(kif_scan_timer, KIF_CF->scan_time);
|
tm_start(kif_scan_timer, KIF_CF->scan_time);
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ kif_reconfigure(struct proto *p, struct proto_config *new)
|
||||||
if (o->scan_time != n->scan_time)
|
if (o->scan_time != n->scan_time)
|
||||||
{
|
{
|
||||||
tm_stop(kif_scan_timer);
|
tm_stop(kif_scan_timer);
|
||||||
kif_scan_timer->recurrent = n->scan_time;
|
kif_scan_timer->recurrent = n->scan_time S;
|
||||||
kif_scan(kif_scan_timer);
|
kif_scan(kif_scan_timer);
|
||||||
tm_start(kif_scan_timer, n->scan_time);
|
tm_start(kif_scan_timer, n->scan_time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ async_dump(void)
|
||||||
|
|
||||||
rdump(&root_pool);
|
rdump(&root_pool);
|
||||||
sk_dump_all();
|
sk_dump_all();
|
||||||
tm_dump_all();
|
// XXXX tm_dump_all();
|
||||||
if_dump_all();
|
if_dump_all();
|
||||||
neigh_dump_all();
|
neigh_dump_all();
|
||||||
rta_dump_all();
|
rta_dump_all();
|
||||||
|
|
|
@ -11,58 +11,38 @@
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "lib/resource.h"
|
#include "lib/birdlib.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
|
|
||||||
typedef time_t bird_clock_t; /* Use instead of time_t */
|
|
||||||
|
|
||||||
typedef struct timer {
|
typedef struct timer2 timer;
|
||||||
resource r;
|
|
||||||
void (*hook)(struct timer *);
|
|
||||||
void *data;
|
|
||||||
uint randomize; /* Amount of randomization */
|
|
||||||
uint recurrent; /* Timer recurrence */
|
|
||||||
node n; /* Internal link */
|
|
||||||
bird_clock_t expires; /* 0=inactive */
|
|
||||||
} timer;
|
|
||||||
|
|
||||||
timer *tm_new(pool *);
|
static inline timer *tm_new(pool *p)
|
||||||
void tm_start(timer *, uint after);
|
{ return (void *) tm2_new(p); }
|
||||||
void tm_stop(timer *);
|
|
||||||
void tm_dump_all(void);
|
|
||||||
|
|
||||||
extern bird_clock_t now; /* Relative, monotonic time in seconds */
|
static inline void tm_start(timer *t, bird_clock_t after)
|
||||||
extern bird_clock_t now_real; /* Time in seconds since fixed known epoch */
|
{ tm2_start(t, after S_); }
|
||||||
extern bird_clock_t boot_time;
|
|
||||||
|
|
||||||
static inline int
|
static inline void tm_stop(timer *t)
|
||||||
tm_active(timer *t)
|
{ tm2_stop(t); }
|
||||||
{
|
|
||||||
return t->expires != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bird_clock_t
|
// void tm_dump_all(void);
|
||||||
tm_remains(timer *t)
|
|
||||||
{
|
|
||||||
return t->expires ? t->expires - now : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
//extern bird_clock_t now; /* Relative, monotonic time in seconds */
|
||||||
tm_start_max(timer *t, bird_clock_t after)
|
//extern bird_clock_t now_real; /* Time in seconds since fixed known epoch */
|
||||||
{
|
//extern bird_clock_t boot_time;
|
||||||
bird_clock_t rem = tm_remains(t);
|
|
||||||
tm_start(t, (rem > after) ? rem : after);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline timer *
|
static inline int tm_active(timer *t)
|
||||||
tm_new_set(pool *p, void (*hook)(struct timer *), void *data, uint rand, uint rec)
|
{ return tm2_active(t); }
|
||||||
{
|
|
||||||
timer *t = tm_new(p);
|
static inline bird_clock_t tm_remains(timer *t)
|
||||||
t->hook = hook;
|
{ return tm2_remains(t) TO_S; }
|
||||||
t->data = data;
|
|
||||||
t->randomize = rand;
|
static inline void tm_start_max(timer *t, bird_clock_t after)
|
||||||
t->recurrent = rec;
|
{ tm2_start_max(t, after S_); }
|
||||||
return t;
|
|
||||||
}
|
static inline timer * tm_new_set(pool *p, void (*hook)(timer *), void *data, uint rand, uint rec)
|
||||||
|
{ return tm2_new_init(p, hook, data, rec S_, rand S_); }
|
||||||
|
|
||||||
|
|
||||||
struct timeformat {
|
struct timeformat {
|
||||||
|
@ -77,12 +57,7 @@ bird_clock_t tm_parse_datetime(char *); /* Convert date to bird_clock_t */
|
||||||
void
|
void
|
||||||
tm_format_datetime(char *x, struct timeformat *fmt_spec, bird_clock_t t);
|
tm_format_datetime(char *x, struct timeformat *fmt_spec, bird_clock_t t);
|
||||||
|
|
||||||
#define TIME_T_IS_64BIT (sizeof(time_t) == 8)
|
#define TIME_INFINITY ((s64) 0x7fffffffffffffff)
|
||||||
#define TIME_T_IS_SIGNED ((time_t) -1 < 0)
|
|
||||||
|
|
||||||
#define TIME_INFINITY \
|
|
||||||
((time_t) (TIME_T_IS_SIGNED ? \
|
|
||||||
(TIME_T_IS_64BIT ? 0x7fffffffffffffff : 0x7fffffff): \
|
|
||||||
(TIME_T_IS_64BIT ? 0xffffffffffffffff : 0xffffffff)))
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue