Tasklet
[Overview]
Tasklet is a special implementation of Soft Interrupt. Tasklet is usually the optimization mechanism of the lower half of the processing, which has a good balance between performance and ease of use. Compared with softirq, tasklet does not need to consider concurrency issues under SMP, but has better performance than workqueue.
Different types of tasklets can be executed simultaneously on different processors, but tasklets of the same type cannot be executed simultaneously. This avoids concurrency issues.
The ksoftirqd kernel thread has the same responsibilities as the worker thread. It periodically traverses the soft interrupt vector list. if it finds that the soft interrupt vector is suspended (pending), it executes the corresponding processing function,
The implementation of tasklet can also read lkd3. This book is really classic.
[Instance]
static struct input_dev *button_dev;static struct tasklet_structbutton_tasklet;
Global variables are not recommended for actual driver development, because global variables are the main cause of competition.
[Interrupt Processing Program]
static irqreturn_t button_interrupt(intirq, void *p){ tasklet_schedule(&button_tasklet); returnIRQ_RETVAL(IRQ_HANDLED);}
Call the tasklet_schedule function, add button_tasklet to the tasklet_vec (soft interrupt vector) linked list, and trigger Soft Interrupt. In this way, the next call to the do_softirq function will execute button_tasklet. Button_tasklet will be executed in the shortest time.
[Tasklet processing function]
void tasklet_handler(unsigned long data){ /*get pin value <down 0, up 1> */ intval = s3c2410_gpio_getpin(S3C2410_GPG(0)); input_report_key(button_dev,KEY_1, val); input_sync(button_dev);}
Because it is implemented by soft interruptions, tasklet cannot sleep, which means that semaphores and other functions that may be blocked cannot be used in tasklet. However, when tasklet is running, the response is interrupted.
static int __init button_init(void){ interr; if(request_irq(BUTTON_IRQ, button_interrupt, IRQ_TYPE_EDGE_BOTH,DEV_NAME, (void *)button_dev)) { printk(KERN_ERR"cannotallocate irq"); return- EBUSY; } …… tasklet_init(&button_tasklet,tasklet_handler, 0); debug("initialized\n"); return0;}
Initialize tasklet dynamically:
Void tasklet_init (struct tasklet_struct * t, void (* func) (unsigned long), unsigned long data)
T: tasklet_struct struct pointer
FUNC: tasklet processing function pointer
Data: func Parameters
Static initialization tasklet:
# Define declare_tasklet (name, func, data )\
Struct tasklet_struct name = {null, 0, atomic_init (0), func, data}
Reference: http://www.cppblog.com/kgha/archive/2007/02/10/18590.html