Linux

Linux kernel: kthread & wait_event_interruptible 사용법

Roien 2015. 7. 4.
반응형

Kernel thread에서event wait 사용 법

 

1. Dependencies

#include <linux/kthread.h>

#include <linux/time.h>

#include <linux/timer.h>

 

2. Declaring variables

static DECLARE_WAIT_QUEUE_HEAD(hub_wait_queue);

 

static struct {

    unsigned int evt_thread_stt;

    unsigned int evt_wait_cond;

    struct task_struct *evt_kthread;

 

    spinlock_t evt_thread_lock;

} hub_wait_queue_ctx;

 

3. Condition check used by kthread

bool _hub_work_evt_check_cond()

{

    spin_lock(&hub_wait_queue_ctx.evt_thread_lock);

    bool ret = hub_wait_queue_ctx.evt_wait_cond;

    spin_unlock(&hub_wait_queue_ctx.evt_thread_lock);

    return ret;

}

 

4. kthread entry

int _hub_work_evt_thread_entry(void *param)

{

int ret;

int timeout = 5000;

unsigned long remain_timeout = 1;

 

// 1. Without timeout

ret =

wait_event_interruptible(hub_wait_queue, _hub_work_evt_check_cond());

if (ret != 0) {

    printk(KERN_WARNING "ERR: wait_event_interruptible\r\n");

}

 

// 2. With timeout

remain_timeout = wait_event_interruptible_timeout(hub_wait_queue,

   _hub_work_evt_check_cond(),

   msecs_to_jiffies(timeout));

 

if (remain_timeout <= 0) {

    printk(KERN_WARNING “ time out...\r\n");

    continue;

}

 

spin_lock(&hub_wait_queue_ctx.evt_thread_lock);

hub_wait_queue_ctx.evt_wait_cond = false;

spin_unlock(&hub_wait_queue_ctx.evt_thread_lock);

}

 

5. ISR

unsigned long irqflags;

    spin_lock_irqsave(&hub_wait_queue_ctx.evt_thread_lock, irqflags);

    hub_wait_queue_ctx.evt_wait_cond = true;

    spin_unlock_irqrestore(&hub_wait_queue_ctx.evt_thread_lock, irqflags);

   

    wake_up_interruptible(&hub_wait_queue);

 

6. init

spin_lock_init(&hub_wait_queue_ctx.evt_thread_lock);

    hub_wait_queue_ctx.evt_wait_cond = false;

   

    hub_wait_queue_ctx.evt_thread_stt = 1;

    hub_wait_queue_ctx.evt_kthread =

kthread_run(_hub_work_evt_thread_entry, NULL, "Evt_kthread");

    if (IS_ERR(hub_wait_queue_ctx.evt_kthread)) {

        pr_err("ERR: errno:%p\n", hub_wait_queue_ctx.evt_kthread);

        return NULL;

    }

 

7. deinit

hub_wait_queue_ctx.evt_thread_stt = 0;

    kthread_stop(hub_wait_queue_ctx.evt_kthread);

 


반응형

댓글