=============================== 博客点滴积累,部分话语和知识点来源于网络,感谢网络资源的提供者======
start_kernel()
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
kernel_init()
do_basic_setup()
init_workqueues();hotcpu_notifier(workqueue_cpu_callback, 0);//注册到内核通知链keventd_wq = create_workqueue("events");//每个cpu都会创建工作队列events线程
#define __create_workqueue(name, singlethread, freezeable)\
__create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL)
err = create_workqueue_thread(cwq, singlethread_cpu);
start_workqueue_thread(cwq, -1);
worker_thread()
run_workqueue()
struct work_struct *work = list_entry(cwq->worklist.next,struct work_struct, entry);//取链表元素work_func_t f = work->func;f(work);//用户注册的工作函数被调用
2 工作任务结构体
struct work_struct {
atomic_long_t data;
#define WORK_STRUCT_PENDING 0
/* T if work item pending execution */
#define WORK_STRUCT_FLAG_MASK (3UL)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
struct list_head entry;
work_func_t func; //函数指针,工作队列线程回调
};
用户接口schedule_work,将工作任务加入内核工作队列:
int fastcall schedule_work(struct work_struct *work){
return queue_work(keventd_wq, work);
}
schedule_work
queue_work(struct workqueue_struct *wq, struct work_struct *work)
__queue_work(wq_per_cpu(wq, get_cpu()), work);
insert_work(cwq, work, 1); //链表插入
3延迟工作 ,也是通过工作队列 加定时器实现的
struct delayed_work {
struct work_struct work;
struct timer_list timer;
};
int schedule_delayed_work_on(int cpu,
struct delayed_work *dwork, unsigned long delay)
{
return queue_delayed_work_on(cpu, keventd_wq, dwork, delay);}
// 添加一个定时器
int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
struct delayed_work *dwork, unsigned long delay)
{
int ret = 0;
struct timer_list *timer = &dwork->timer;
struct work_struct *work = &dwork->work;
if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
BUG_ON(timer_pending(timer));BUG_ON(!list_empty(&work->entry));
/* This stores cwq for the moment, for the timer_fn */set_wq_data(work, wq_per_cpu(wq, raw_smp_processor_id()));timer->expires = jiffies + delay;timer->data = (unsigned long)dwork;timer->function = delayed_work_timer_fn; // 时间到了调用该函数,将work添加到工作队列
if (unlikely(cpu >= 0))add_timer_on(timer, cpu);elseadd_timer(timer);ret = 1;
}}
return ret;
void delayed_work_timer_fn(unsigned long __data)
{
struct delayed_work *dwork = (struct delayed_work *)__data;}
struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work);
struct workqueue_struct *wq = cwq->wq;
__queue_work(wq_per_cpu(wq, smp_processor_id()), &dwork->work);