声明:此文档只做学习交流使用,请勿用作其他商业用途
author:朝阳_tony转载请注明出处:http://blog.csdn.net/linzhaolove
此文中源码可以去http://dpdk.org/dev 网页中下载;更多官方文档请访问http://dpdk.org
uint64_t cur_time = rte_get_hpet_cycles();
在rte_timer_reset中首先会调用rte_get_hpet_cycles()获取当前hpet模块的cycles数,而定时器的时钟精准度也是依赖hpet模块;我在其他的博文中已经讲过hpet模块;
if (type == PERIODICAL)
period = ticks;
else
period = 0;
过类型判断你当前设置的周期性的定时器,还是单次运行定时器;
/* wait that the timer is in correct status before update,
* and mark it as beeing configured */
ret = timer_set_config_state(tim, &prev_status);
首先要设置当前定时器的状态为 配置状态;
tim->period = period;
tim->expire = expire;
tim->f = fct;
tim->arg = arg;
然后配置其 周期,期望值,回调函数,以及给回调函数传递的参数;
timer_add(tim, tim_lcore, local_is_locked);
将定时器插入到对应的lcore 的pending列表中,
status.state = RTE_TIMER_PENDING;
status.owner = (int16_t)tim_lcore;
tim->status.u32 = status.u32;
/* optimize for the case where per-cpu list is empty */
if (LIST_EMPTY(&priv_timer[lcore_id].pending))
return;
在rte_timer_manage()中,先判断pending列表是否为空,如果是空,就要及时返回;
/* browse ordered list, add expired timers in 'expired' list */
rte_spinlock_lock(&priv_timer[lcore_id].list_lock);
LIST_FOREACH_SAFE(tim, tim2, &priv_timer[lcore_id].pending, next) {
if ((int64_t)(cur_time - tim->expire) < 0)
break;
LIST_REMOVE(tim, next);
LIST_INSERT_HEAD(&priv_timer[lcore_id].expired, tim, next);
}
这添加了自旋锁防止误操作;
/* for each timer of 'expired' list, check state and execute callback */
while ((tim = LIST_FIRST(&priv_timer[lcore_id].expired)) != NULL) {
ret = timer_set_running_state(tim);
/* remove from expired list, and add it in done list */
LIST_REMOVE(tim, next);
LIST_INSERT_HEAD(&priv_timer[lcore_id].done, tim, next);
将其从expired 期满列表,移动到done完成列表;
/* execute callback function with list unlocked */
tim->f(tim, tim->arg);
执行定时器调用回调函数;
/* remove from done list and mark timer as stopped */
LIST_REMOVE(tim, next);
__TIMER_STAT_ADD(pending, -1);
status.state = RTE_TIMER_STOP;
status.owner = RTE_TIMER_NO_OWNER;
/* keep it in done list and mark timer as pending */
status.state = RTE_TIMER_PENDING;
status.owner = (int16_t)lcore_id;