The concept of 1,tasklet
Tasklet is a soft interrupt implementation of a lower half of the mechanism, tasklet by the two class soft interrupt representatives, HI_SOFTIRQ and TASKLET_SOFTIRQ, the difference is the HI_SOFTIRQ type of soft interrupt prior to tasklet_ Soft interrupts of the SOFTIRQ type are performed first.
Tasklet is represented by the tasklet_struct structure, and each structure represents a single tasklet, defined in Interrupt.h.
[CPP]View Plaincopy
- 420 struct Tasklet_struct
- 421 {
- 422 struct tasklet_struct *next;
- 423 unsigned long state; The value of the//state member is evaluated between 0,tasklet_state_sched and Tasklet_state_run, and tasklet_state_sched indicates that the Tasklet has been dispatched and is ready to be put into operation.
- 424 atomic_t Count; //tasklet Reference count, if it is not 0 then Tasklet is forbidden,
- 425 Void (*func) (unsigned long);
- 426 unsigned Long data;
- 427};
Tasklet is dispatched by the Tasklet_schedule () function,
[CPP]View Plaincopy
- <span style="font-weight:bold; Font-family:arial, Helvetica, Sans-serif; Background-color:rgb (255, 255, 255); " >2,tasklet mechanism </span>
1) Declare your tasklet.
Statically created:
You can create tasklet statically using one of the two macros defined in <linux/interrupt.h>, Declare_tasklet, or declare_tasklet_disabled. The former sets the reference counter of the created Tasklet to 0 and the Tasklet is active. The other one sets the introduction counter to 1, so the tasklet is in a forbidden state. You can also use Tasklet_init () to dynamically create a tasklet.
[CPP]View Plaincopy
- 429 #define DECLARE_TASKLET (name, func, data) \
- 430 struct Tasklet_struct name = {NULL, 0, atomic_init (0), func, data}
Dynamic creation:
[CPP]View Plaincopy
- struct msdc_host{
- struct tasklet_struct card_tasklet;
- };
- struct Msdc_host *host;
- Tasklet_init (&host->card_tasklet,msdc_tasklet_card,unsigned long arg); Msdc_tasklet_card is the Tasklet processing function
- Tasklet_hi_schedule (&host->card_tasklet);
- 470 void Tasklet_init (struct tasklet_struct *t,
- 471 Void (*func) (unsigned long), unsigned Long data)
- 472 {
- 473 T->next = NULL;
- 474 t->state = 0;
- 475 Atomic_set (&t->count, 0);
- 476 T->func = func;
- 477 t->data = data;
- 478}
2) Write your own Tasklet handler
The Tasklet handler must conform to the specified function type: void Tasklet_handler (unsigned long data). Because it is implemented by soft interrupts, tasklet cannot sleep. This means that you cannot use semaphores or any other blocking functions in Tasklet. If your tasklet and other tasklet or soft interrupts share the data, you must make appropriate lock protection.
3) Dispatch your own Tasklet
Dispatched by calling the Tasklet_schedule () function. After Tasklet is dispatched, it will only run once if an identical tasklet is dispatched before it has yet to be run. And if it starts running, the new tasklet will be re-dispatched and run again. As an optimization measure, a tasklet is always executed on the processor that dispatches it-this is the cache that wants to make better use of the processor. You can call the Tasklet_disable () function to suppress a specified tasklet, or you can invoke the Tasklet_enable () function to activate a tasklet. You can also call the Tasklet_kill () function to remove a tasklet from the Suspended queue.
3,ksoftirqd
Each processor has one such thread, all the thread names are called Ksoftirqd/n,n corresponding to the processor number, these threads are running at the lowest priority (Nice value is 19), so the advantage is that they and other important think Rob the resources, on the idle system, this program also performed well.
4, the difference between work queue and Tasklet ~
The work queue runs in the context of the process and can be interrupted if you need to sleep on the lower half of the interrupt, then you should use the work queue mechanism.
[Linux kernel] interrupts the lower half--tasklet