tasklets using (tasklet_struct) to start the functions of deferred action.
Tasklets (tasklet_struct) as workqueues are used for performing of deferred actions. Tasklet (tasklet_struct) can run in softirq interrupt, so if there is a section BUG_ON(in_interrupt()) in the code, the use of tasklet (tasklet_struct) is impossible there.
An example of the use of tasklet (tasklet_struct) with the static declaration and parameter passing in function tasklet (as parameter is the line transfered):
/* * stat_tasklet.c - пример использвания такслета * со статическим объявлением */ #include <linux/module.h> #include <linux/workqueue.h> #include <linux/interrupt.h> #define DRIVER_AUTHOR "noname author" #define DRIVER_DESC "static tasklet" char tmpVar[] = "hello tasklet"; /* функция, которую требуется вызвать в отложенном режиме */ static void my_tasklet_function(unsigned long data){ printk("call tasklet function\n"); printk ("tasklet data: %s\n",(char *)data); } /* объявляется тасклет * первый аргумент - имя тасклета * второй аргумент - имя функции которую нужно отложенно выполнить * третий аргумент - переменная которая передаётся в функцию */ DECLARE_TASKLET (tst_tasklet, my_tasklet_function, (unsigned long) &tmpVar); /* функция, которая вызывается при загрузке модуля */ static int __init init_stat_tasklet(void){ printk(KERN_ALERT "Hello, static tasklet\n"); /* помещение тасклета в очередь на выполнение */ tasklet_schedule(&tst_tasklet ); return 0; } static void __exit cleanup_stat_tasklet(void){ printk(KERN_ALERT "Goodbye, static tasklet\n"); } module_init(init_stat_tasklet); module_exit(cleanup_stat_tasklet); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC);
Tasklets can be called out using dynamic declaration as in the case of workqueues.
An example of the use of tasklet (tasklet_struct) with the dynamic declaration and parameter passing in function tasklet (as parameter is the numeral char transfered):
/* * dynam_tasklet.c - пример использвания такслета * с динамическим объявлением */ #include <linux/module.h> #include <linux/workqueue.h> #include <linux/interrupt.h> #include <linux/slab.h> #define DRIVER_AUTHOR "noname author" #define DRIVER_DESC "dynamic tasklet" char tmpVar=55; /* функция, которую требуется вызвать в отложенном режиме */ static void my_tasklet_function(unsigned long data){ printk("call tasklet function\n"); printk ("tasklet data: %d\n",*(char *)data); } //DECLARE_TASKLET (tst_tasklet, my_tasklet_function, (unsigned long) &tmpVar); /* функция, которая вызывается при загрузке модуля */ static int __init init_dynam_tasklet(void){ printk(KERN_ALERT "Hello, dynamic tasklet\n"); /* объявление указателя на тасклет */ struct tasklet_struct *tst_tasklet; /* выделение памяти под структуру */ tst_tasklet = kmalloc( sizeof(struct tasklet_struct), GFP_KERNEL ); /* объявляется тасклет * первый аргумент - имя тасклета * второй аргумент - имя функции которую нужно отложенно выполнить * третий аргумент - переменная которая передаётся в функцию */ tasklet_init (tst_tasklet, my_tasklet_function, &tmpVar); /* помещение тасклета в очередь на выполнение */ tasklet_schedule(tst_tasklet); return 0; } static void __exit cleanup_dynam_tasklet(void){ printk(KERN_ALERT "Goodbye, dynamic tasklet\n"); } module_init(init_dynam_tasklet); module_exit(cleanup_dynam_tasklet); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC);