Linux kernel: kthread & wait_event_interruptible 사용법

2021. 12. 31. 13:12Linux

    목차
반응형

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);

 

 

반응형