声明:此文档只做学习交流使用,请勿用作其他商业用途
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;