#ifndef UCS_WHEEL_H
#define UCS_WHEEL_H
#include <ucs/datastruct/list.h>
#include <ucs/time/time.h>
#include <ucs/debug/log.h>
typedef struct ucs_wtimer ucs_wtimer_t;
typedef struct ucs_timer_wheel ucs_twheel_t;
typedef void (*ucs_twheel_callback_t)(ucs_wtimer_t *self);
struct ucs_wtimer {
ucs_twheel_callback_t cb;
ucs_list_link_t list;
int is_active;
};
struct ucs_timer_wheel {
ucs_time_t res;
ucs_time_t now;
uint64_t current;
ucs_list_link_t *wheel;
unsigned res_order;
unsigned num_slots;
unsigned count;
};
ucs_status_t ucs_twheel_init(ucs_twheel_t *twheel, ucs_time_t resolution,
ucs_time_t current_time);
void ucs_twheel_cleanup(ucs_twheel_t *twheel);
ucs_status_t ucs_wtimer_init(ucs_wtimer_t *t, ucs_twheel_callback_t cb);
void __ucs_twheel_sweep(ucs_twheel_t *t, ucs_time_t current_time);
static inline void ucs_twheel_sweep(ucs_twheel_t *t, ucs_time_t current_time)
{
if (ucs_unlikely(current_time - t->now >= t->res)) {
__ucs_twheel_sweep(t, current_time);
}
}
static inline ucs_time_t ucs_twheel_get_time(ucs_twheel_t *t)
{
return t->now;
}
static UCS_F_ALWAYS_INLINE int ucs_twheel_is_empty(ucs_twheel_t *t)
{
return !t->count;
}
void __ucs_wtimer_add(ucs_twheel_t *t, ucs_wtimer_t *timer, ucs_time_t delta);
static inline ucs_status_t ucs_wtimer_add(ucs_twheel_t *t, ucs_wtimer_t *timer,
ucs_time_t delta)
{
if (ucs_likely(timer->is_active)) {
return UCS_ERR_BUSY;
}
__ucs_wtimer_add(t, timer, delta);
return UCS_OK;
}
static inline void ucs_wtimer_remove(ucs_twheel_t *t, ucs_wtimer_t *timer)
{
if (ucs_likely(timer->is_active)) {
ucs_list_del(&timer->list);
timer->is_active = 0;
t->count--;
}
}
#endif