From linux/interrupt.h:
/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high frequency threaded job scheduling. For almost all the purposes tasklets are more than enough. F.e. all serial device BHs et al. should be converted to tasklets, not to softirqs. */
The tasklet priority of a tasklet scheduled with schedule_hi_tasklet is above the network subsystem, so if you over due it you actually can cripple your network performance..., schedule_tasklet has a priority just below the network subsystem so a network overload can delay your tasklet substantially.
With the kernel functions tasklet_disable and tasklet_enable the execution of a tasklet can be suspended. If a tasklet was scheduled and is disable before it was executed it will be executed when tasklet_enabled is called. For the full set of kernel functions available for tasklets check linux/interrupt.h, note though that you must check if these are safe to be called from rt-context, for this paper checks were done against linux 2.4.4.
To ensure synchronization of tasklet scheduling when disabling tasklets within rt-context with tasklet_disable one must install a cleanup handler to re-enable the tasklet on termination of the thread so that a scheduled tasklets can be executed and the tasklet structure can be removed on module exit.
...
void
tasklet_cleanup(void *arg)
{
tasklet_enable(&test_tasklet);
rtl_printf("cleanup handler\n");
}
void *
start_routine(void *arg)
{
...
pthread_cleanup_push(
tasklet_cleanup,
0);
while (1) {
pthread_wait_np ();
...
if(i==20){
tasklet_disable(&test_tasklet);
rtl_printf("killed tasklet\n");
}
tasklet_hi_schedule(
&test_tasklet);
i++;
}
pthread_cleanup_pop(0);
return 0;
}
This somewhat artificial code shows the basic setup - a cleanup handler to re-enable the tasklet is installed and within the main loop of the rt-thread tasklet_disable is called to disable the test_tasklet, the cleanup handler is executed on termination of the while(1) loop and re-enables tasklets.