DPVS的定时器

本文详细介绍了DPVS的定时器实现,采用O(1)复杂度的时间轮算法,包括数据结构、初始化过程、时间轮操作、回调函数以及添加和刷新超时任务的机制。
摘要由CSDN通过智能技术生成

一,时间轮

DPDK的定时器使用跳表实现的,在处理大量比如会话时间时,session老化啥的,效率不高,DPVS的使用的是复杂度 O(1)的时间轮算法。

二,DPVS的定时器

1.数据结构

struct timer_scheduler {
    /* wheels and cursors */
    rte_spinlock_t      lock;
    uint32_t            cursors[LEVEL_DEPTH];
    struct list_head    *hashs[LEVEL_DEPTH];

    /* leverage dpdk rte_timer to drive us */
    struct rte_timer    rte_tim;
};
static struct timer_scheduler g_timer_sched;

lock是锁,增删改查都要锁。

rte_tim负责时间滴答,也就是tick++。

cursors和hashs 配合使用,构成时间轮。

从 0 到 LEVEL_SIZE (2<<18), LEVEL_DEPTH 值为 2,也就是说 cursors[0] 可以保存 2<<18 个嘀嗒,如果 DPVS_TIMER_HZ = 1000,那么就是 524s. cursors[0] 驱动 cursors[1] 时间轮,两个轮一共 8.7 年时间。hashs 是一个长度为 2 的数组,每个元素是一个链表数组,长度是 LEVEL_SIZE (2<<18), 链表成员就是具体的定时器消息。

2.初始化

int dpvs_timer_init(void)
{
    lcoreid_t cid;
    int err;

    /* per-lcore timer */
    rte_eal_mp_remote_launch(timer_lcore_init, NULL, SKIP_MAIN);
    RTE_LCORE_FOREACH_WORKER(cid) {
        err = rte_eal_wait_lcore(cid);
        if (err < 0) {
            RTE_LOG(ERR, DTIMER, "%s: lcore %d: %s.\n",
                    __func__, cid, dpvs_strerror(err));
            return err;
        }
    }

    /* global timer */
    return timer_init_schedler(&g_timer_sched, rte_get_main_lcore());
}

每个slave lcore 都要调 timer_lcore_init初始化自己的,然后初始化全局的_timer_sched。

3.timer_lcore_init

static int timer_lcore_init(void *arg)
{
    if (!rte_lcore_is_enabled(rte_lcore_id()))
        return EDPVS_DISABLED;

    return timer_init_schedler(&RTE_PER_LCORE(timer_sched), rte_lcore_id());
}

(免费订阅,永久学习)学习地址: 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值