#include linux/init.h> #include linux/module.h> #include linux/moduleparam.h> #include linux/time.h> #include linux/timer.h> #include linux/workqueue.h> #include asm/atomic.h> MODULE_AUTHOR("lcw"); MODULE_LICENSE("GPL"); struct timer_data { struct timer_list timer; struct workqueue_struct *work_queue; unsigned long prev_jiffies; unsigned int loops; };
struct timer_data test_data; struct timer_data test_data1; static void do_work(void *); static DECLARE_WORK(test_work, do_work, NULL); static DECLARE_WORK(test_work1, do_work, NULL); static struct workqueue_struct *test_workqueue; atomic_t wq_run_times; unsigned int failed_cnt = 0;
void test_timer_fn(unsigned long arg) { struct timer_data *data = (struct timer_data *)arg;
unsigned long j = jiffies; data->timer.expires += 2 * HZ; data->prev_jiffies = j; add_timer(&data->timer);
if (queue_work(test_workqueue, &test_work) == 0) { printk("Timer (0) add work queue failed\n"); (*(&failed_cnt))++; } data->loops++; printk("timer-0 loops: %u\n", data->loops); }
void test_timer_fn1(unsigned long arg) { struct timer_data *data = (struct timer_data *)arg; unsigned long j = jiffies; data->timer.expires += 3 * HZ; data->prev_jiffies = j; add_timer(&data->timer); //if (queue_work(test_workqueue, &test_work) == 0) { if (queue_work(test_workqueue, &test_work1) == 0) { printk("Timer (1) add work queue failed\n"); (*(&failed_cnt))++; } data->loops++; printk("timer-1 loops: %u\n", data->loops); }
void do_work(void *arg) { atomic_inc(&wq_run_times); printk("====work queue run times: %u====\n", atomic_read(&wq_run_times)); printk("====failed count: %u====\n", *(&failed_cnt)); }
int wq_init(void) { unsigned long j = jiffies; printk("jiffies: %lu\n", jiffies); atomic_set(&wq_run_times, 0);
init_timer(&test_data.timer); test_data.loops = 0; test_data.prev_jiffies = j; test_data.timer.function = test_timer_fn; test_data.timer.data = (unsigned long)(&test_data); test_data.timer.expires = j + 2 * HZ; add_timer(&test_data.timer);
init_timer(&test_data1.timer); test_data1.loops = 0; test_data1.prev_jiffies = j; test_data1.timer.function = test_timer_fn1; test_data1.timer.data = (unsigned long)(&test_data1); test_data1.timer.expires = j + 3 * HZ; add_timer(&test_data1.timer);
test_workqueue = create_singlethread_workqueue("test-wq"); printk("test-wq init success\n"); printk("jiffies: %lu\n", jiffies); return 0; }
void wq_exit(void) { del_timer(&test_data.timer); del_timer(&test_data1.timer); destroy_workqueue(test_workqueue); printk("wq exit success\n"); }
module_init(wq_init); module_exit(wq_exit) |