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的使用

未完待續。。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM