2017-05-31 01:12:35 +08:00
|
|
|
/*
|
|
|
|
* BIRD -- Timers
|
|
|
|
*
|
|
|
|
* (c) 2013--2017 Ondrej Zajicek <santiago@crfreenet.org>
|
|
|
|
* (c) 2013--2017 CZ.NIC z.s.p.o.
|
|
|
|
*
|
|
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
|
|
*/
|
|
|
|
|
2017-11-29 00:43:20 +08:00
|
|
|
#ifndef _BIRD_TIMER_H_
|
|
|
|
#define _BIRD_TIMER_H_
|
2017-05-31 01:12:35 +08:00
|
|
|
|
|
|
|
#include "nest/bird.h"
|
|
|
|
#include "lib/buffer.h"
|
|
|
|
#include "lib/resource.h"
|
|
|
|
|
|
|
|
|
2017-11-29 00:43:20 +08:00
|
|
|
typedef struct timer
|
2017-05-31 01:12:35 +08:00
|
|
|
{
|
|
|
|
resource r;
|
2017-11-29 00:43:20 +08:00
|
|
|
void (*hook)(struct timer *);
|
2017-05-31 01:12:35 +08:00
|
|
|
void *data;
|
|
|
|
|
|
|
|
btime expires; /* 0=inactive */
|
|
|
|
uint randomize; /* Amount of randomization */
|
|
|
|
uint recurrent; /* Timer recurrence */
|
|
|
|
|
|
|
|
int index;
|
2017-11-29 00:43:20 +08:00
|
|
|
} timer;
|
2017-05-31 01:12:35 +08:00
|
|
|
|
|
|
|
struct timeloop
|
|
|
|
{
|
2017-12-10 20:16:31 +08:00
|
|
|
BUFFER_(timer *) timers;
|
2017-05-31 01:12:35 +08:00
|
|
|
btime last_time;
|
|
|
|
btime real_time;
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline uint timers_count(struct timeloop *loop)
|
|
|
|
{ return loop->timers.used - 1; }
|
|
|
|
|
2017-11-29 00:43:20 +08:00
|
|
|
static inline timer *timers_first(struct timeloop *loop)
|
2017-05-31 01:12:35 +08:00
|
|
|
{ return (loop->timers.used > 1) ? loop->timers.data[1] : NULL; }
|
|
|
|
|
|
|
|
extern struct timeloop main_timeloop;
|
|
|
|
|
|
|
|
btime current_time(void);
|
2022-04-19 06:24:14 +08:00
|
|
|
btime current_time_now(void);
|
2017-06-01 18:33:20 +08:00
|
|
|
btime current_real_time(void);
|
|
|
|
|
2017-11-29 00:06:10 +08:00
|
|
|
//#define now (current_time() TO_S)
|
|
|
|
//#define now_real (current_real_time() TO_S)
|
2017-06-01 18:33:20 +08:00
|
|
|
extern btime boot_time;
|
2017-05-31 01:12:35 +08:00
|
|
|
|
2017-11-29 00:43:20 +08:00
|
|
|
timer *tm_new(pool *p);
|
|
|
|
void tm_set(timer *t, btime when);
|
|
|
|
void tm_start(timer *t, btime after);
|
|
|
|
void tm_stop(timer *t);
|
2017-05-31 01:12:35 +08:00
|
|
|
|
|
|
|
static inline int
|
2017-11-29 00:43:20 +08:00
|
|
|
tm_active(timer *t)
|
2017-05-31 01:12:35 +08:00
|
|
|
{
|
|
|
|
return t->expires != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline btime
|
2017-11-29 00:43:20 +08:00
|
|
|
tm_remains(timer *t)
|
2017-05-31 01:12:35 +08:00
|
|
|
{
|
2017-06-01 18:33:20 +08:00
|
|
|
btime now_ = current_time();
|
|
|
|
return (t->expires > now_) ? (t->expires - now_) : 0;
|
2017-05-31 01:12:35 +08:00
|
|
|
}
|
|
|
|
|
2017-11-29 00:43:20 +08:00
|
|
|
static inline timer *
|
|
|
|
tm_new_init(pool *p, void (*hook)(struct timer *), void *data, uint rec, uint rand)
|
2017-05-31 01:12:35 +08:00
|
|
|
{
|
2017-11-29 00:43:20 +08:00
|
|
|
timer *t = tm_new(p);
|
2017-05-31 01:12:35 +08:00
|
|
|
t->hook = hook;
|
|
|
|
t->data = data;
|
|
|
|
t->recurrent = rec;
|
|
|
|
t->randomize = rand;
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2017-11-29 00:43:20 +08:00
|
|
|
tm_set_max(timer *t, btime when)
|
2017-05-31 01:12:35 +08:00
|
|
|
{
|
|
|
|
if (when > t->expires)
|
2017-11-29 00:43:20 +08:00
|
|
|
tm_set(t, when);
|
2017-05-31 01:12:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2017-11-29 00:43:20 +08:00
|
|
|
tm_start_max(timer *t, btime after)
|
2017-05-31 01:12:35 +08:00
|
|
|
{
|
2017-11-29 00:43:20 +08:00
|
|
|
btime rem = tm_remains(t);
|
|
|
|
tm_start(t, MAX_(rem, after));
|
2017-05-31 01:12:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* In sysdep code */
|
|
|
|
void times_init(struct timeloop *loop);
|
|
|
|
void times_update(struct timeloop *loop);
|
2017-06-01 18:33:20 +08:00
|
|
|
void times_update_real_time(struct timeloop *loop);
|
2017-05-31 01:12:35 +08:00
|
|
|
|
|
|
|
/* For I/O loop */
|
|
|
|
void timers_init(struct timeloop *loop, pool *p);
|
|
|
|
void timers_fire(struct timeloop *loop);
|
|
|
|
|
|
|
|
void timer_init(void);
|
|
|
|
|
|
|
|
|
2017-06-06 22:47:30 +08:00
|
|
|
struct timeformat {
|
2020-04-09 04:25:15 +08:00
|
|
|
const char *fmt1, *fmt2;
|
2017-06-06 22:47:30 +08:00
|
|
|
btime limit;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TM_ISO_SHORT_S (struct timeformat){"%T", "%F", (s64) (20*3600) S_}
|
|
|
|
#define TM_ISO_SHORT_MS (struct timeformat){"%T.%3f", "%F", (s64) (20*3600) S_}
|
|
|
|
#define TM_ISO_SHORT_US (struct timeformat){"%T.%6f", "%F", (s64) (20*3600) S_}
|
|
|
|
|
|
|
|
#define TM_ISO_LONG_S (struct timeformat){"%F %T", NULL, 0}
|
|
|
|
#define TM_ISO_LONG_MS (struct timeformat){"%F %T.%3f", NULL, 0}
|
|
|
|
#define TM_ISO_LONG_US (struct timeformat){"%F %T.%6f", NULL, 0}
|
|
|
|
|
|
|
|
#define TM_DATETIME_BUFFER_SIZE 32 /* Buffer size required by tm_format_time() */
|
|
|
|
|
2020-04-09 04:25:15 +08:00
|
|
|
btime tm_parse_time(const char *x);
|
2017-06-06 22:47:30 +08:00
|
|
|
void tm_format_time(char *x, struct timeformat *fmt, btime t);
|
2018-11-21 00:38:19 +08:00
|
|
|
int tm_format_real_time(char *x, size_t max, const char *fmt, btime t);
|
2017-06-06 22:47:30 +08:00
|
|
|
|
2017-05-31 01:12:35 +08:00
|
|
|
#endif
|