以下函数用于将定时任务结构体timer插入到链表中,list成员表示链表结点,该链表是双向循环链表,container_of是获取成员所在结构体的首地址,list_is_empty()判断链表是否为空,如果为空则返回1,否则返回0,list_add_to_behind函数将新节点插入到当前结点的next位置(后插)
想问下红圈的部分是不是有问题呀?
第一个问题是,我理解是链表结点应该是按照expire_jiffies值从小到大排列,但是这里插入却将结点插入到了后面,造成了前大后小的情况;
第二个问题是,感觉如果timer_list_head链表中所有结点的expire_jiffies值都比timer的小,那是不是while就进入了无限循环?因为双向循环链表的结尾指向了头结点
void add_timer(struct timer_list * timer)
{
struct timer_list * tmp = container_of(list_next(&timer_list_head.list),struct timer_list,list);
if(list_is_empty(&timer_list_head.list))
{
}
else
{
while(tmp->expire_jiffies < timer->expire_jiffies)
tmp = container_of(list_next(&tmp->list),struct timer_list,list);
}
list_add_to_behind(&tmp->list,&timer->list);
}
相关函数结构体定义如下:
struct timer_list
{
struct List list;
unsigned long expire_jiffies; //期望执行时间(延迟)
void (* func)(void * data); //处理方法
void *data; //参数
};
#define container_of(ptr,type,member) \
({ \
typeof(((type *)0)->member) * p = (ptr); \
(type *)((unsigned long)p - (unsigned long)&(((type *)0)->member)); \
})
inline struct List * list_next(struct List * entry)
{
if(entry->next != NULL)
return entry->next;
else
return NULL;
}
inline long list_is_empty(struct List * entry)
{
if(entry == entry->next && entry->prev == entry)
return 1;
else
return 0;
}
inline void list_add_to_behind(struct List * entry,struct List * new) ////add to entry behind
{
new->next = entry->next;
new->prev = entry;
new->next->prev = new;
entry->next = new;
}