worker线程的创建与使用

一、worker线程的创建

1. 创建流程

//调用这个接口创建内核工作线程,eg: crypto_engine.c中的创建方法:
kthread_create_worker(0, "%s", engine->name); //在CPU0上创建一个work线程
    kthread_create_worker(unsigned int flags, const char namefmt[], ...)
    //或kthread_create_worker_on_cpu(int cpu, unsigned int flags, const char namefmt[], ...)
        __kthread_create_worker(int cpu, unsigned int flags, const char namefmt[], va_list args)
            __kthread_create_on_node(kthread_worker_fn, worker, node, namefmt, args)

 

__kthread_create_worker():

/* 若是参数cpu大于等于0就创建特定于某个CPU的工作线程,若是不想创建特定于CPU的工作线程,就将CPU域赋值为-1 */
static struct kthread_worker * __kthread_create_worker(int cpu, unsigned int flags, const char namefmt[], va_list args)
{
    struct kthread_worker *worker;
    struct task_struct *task;
    int node = -1;

    worker = kzalloc(sizeof(*worker), GFP_KERNEL);
    if (!worker)
        return ERR_PTR(-ENOMEM);

    kthread_init_worker(worker);

    if (cpu >= 0)
        node = cpu_to_node(cpu);

    task = __kthread_create_on_node(kthread_worker_fn, worker,
                        node, namefmt, args);
    if (IS_ERR(task))
        goto fail_task;

    if (cpu >= 0)
        kthread_bind(task, cpu);

    worker->flags = flags;
    worker->task = task;
    wake_up_process(task);
    return worker;

fail_task:
    kfree(worker);
    return ERR_CAST(task);
}

 

kthread_worker_fn 循环监听是否有工作需要处理: 

int kthread_worker_fn(void *worker_ptr)
{
    struct kthread_worker *worker = worker_ptr;
    struct kthread_work *work;

    /*
     * FIXME: Update the check and remove the assignment when all kthread
     * worker users are created using kthread_create_worker*() functions.
     */
    WARN_ON(worker->task && worker->task != current);
    worker->task = current;

    if (worker->flags & KTW_FREEZABLE)
        set_freezable();

repeat:
    /* 设置进程的状态,不被调度 */
    set_current_state(TASK_INTERRUPTIBLE);    /* mb paired w/ kthread_stop */

    if (kthread_should_stop()) {
        __set_current_state(TASK_RUNNING);
        spin_lock_irq(&worker->lock);
        worker->task = NULL;
        spin_unlock_irq(&worker->lock);
        return 0;
    }

    work = NULL;
    spin_lock_irq(&worker->lock);
    if (!list_empty(&worker->work_list)) {
        /* 从work_list中取出一个工作 */
        work = list_first_entry(&worker->work_list, struct kthread_work, node);
        list_del_init(&work->node);
    }
    worker->current_work = work;
    spin_unlock_irq(&worker->lock);

    if (work) {
        __set_current_state(TASK_RUNNING);
        /* 执行这个工作上func() */
        work->func(work);
    } else if (!freezing(current))
        schedule();

    try_to_freeze();
    cond_resched();

    /* 又跳到repeat位置,进行循环执行 */
    goto repeat;
}

 

二、worker的使用

未完待续。。。。。

 

posted on 2019-06-05 22:03  Hello-World3  阅读(3180)  评论(0编辑  收藏  举报

导航