本文共 3025 字,大约阅读时间需要 10 分钟。
dpdk中要使用timer 必须分为下面三步第一步:在dpdk中要使用timer,必须初始化RTE timer library其源码分析如下:voidrte_timer_subsystem_init(void){ unsigned lcore_id; /* since priv_timer is static, it's zeroed by default, so only init some * fields. */ for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++) { rte_spinlock_init(&priv_timer[lcore_id].list_lock); priv_timer[lcore_id].prev_lcore = lcore_id; }}可见time子系统初始化是给每一个cpu初始化一个spin lock,并记录当前的cpu id第二步:必须为每个timer的回调函数初始化一个rte_timer结构体voidrte_timer_init(struct rte_timer *tim){ union rte_timer_status status; status.state = RTE_TIMER_STOP; status.owner = RTE_TIMER_NO_OWNER; tim->status.u32 = status.u32;}可以看到只是初始化rte_timer的status 变量第三步:设置timer工作的模式intrte_timer_reset(struct rte_timer *tim, uint64_t ticks, enum rte_timer_type type, unsigned tim_lcore, rte_timer_cb_t fct, void *arg){ #得到当前时间 uint64_t cur_time = rte_get_timer_cycles(); uint64_t period; if (unlikely((tim_lcore != (unsigned)LCORE_ID_ANY) && !(rte_lcore_is_enabled(tim_lcore) || rte_lcore_has_role(tim_lcore, ROLE_SERVICE) == 0))) return -1; #如果type是PERIODICAL,说明是周期timer,这里就要设置timer的周期,否则周期就是零 if (type == PERIODICAL) period = ticks; else period = 0; #获得当前时间和周期后继续设置timer return __rte_timer_reset(tim, cur_time + ticks, period, tim_lcore, fct, arg, 0);}static int__rte_timer_reset(struct rte_timer *tim, uint64_t expire, uint64_t period, unsigned tim_lcore, rte_timer_cb_t fct, void *arg, int local_is_locked){ union rte_timer_status prev_status, status; int ret; #获得当前cpu id unsigned lcore_id = rte_lcore_id(); /* round robin for tim_lcore */ #这里检查timer是否可以建立在其他core上 if (tim_lcore == (unsigned)LCORE_ID_ANY) { if (lcore_id < RTE_MAX_LCORE) { /* EAL thread with valid lcore_id */ tim_lcore = rte_get_next_lcore( priv_timer[lcore_id].prev_lcore, 0, 1); priv_timer[lcore_id].prev_lcore = tim_lcore; } else /* non-EAL thread do not run rte_timer_manage(), * so schedule the timer on the first enabled lcore. */ tim_lcore = rte_get_next_lcore(LCORE_ID_ANY, 0, 1); } /* wait that the timer is in correct status before update, * and mark it as being configured */ #只是timer状态 ret = timer_set_config_state(tim, &prev_status); if (ret < 0) return -1; #用于debug函数,release版本为空函数 __TIMER_STAT_ADD(reset, 1); #如果timer已经在运行状态说明这次是要update状态 if (prev_status.state == RTE_TIMER_RUNNING && lcore_id < RTE_MAX_LCORE) { priv_timer[lcore_id].updated = 1; } /* remove it from list */ #如果timer是pending的,则调用timer_del删除timer if (prev_status.state == RTE_TIMER_PENDING) { timer_del(tim, prev_status, local_is_locked); __TIMER_STAT_ADD(pending, -1); } #设置time的周期,下次到期时间,回调函数,以及参数 tim->period = period; tim->expire = expire; tim->f = fct; tim->arg = arg; #debug函数,打印状态 __TIMER_STAT_ADD(pending, 1); #添加这个timer后,这个timer就开始正常工作了 timer_add(tim, tim_lcore, local_is_locked); /* update state: as we are in CONFIG state, only us can modify * the state so we don't need to use cmpset() here */ rte_wmb(); status.state = RTE_TIMER_PENDING; status.owner = (int16_t)tim_lcore; tim->status.u32 = status.u32; return 0;}
转载地址:http://cnnmi.baihongyu.com/