4.1.1.1.3. Tasklet Handling Example
static void tasklet_action (struct softirq_action *a)
{
  struct tasklet_struct *list;

  // Get the entire tasklet queue
  local_irq_disable ();
    list = __get_cpu_var (tasklet_vec).head;
    __get_cpu_var (tasklet_vec).head = NULL;
    __get_cpu_var (tasklet_vec).tail = &__get_cpu_var (tasklet_vec).head;
  local_irq_enable ();

  // Go through the queue tasklet by tasklet
  while (list) {
    struct tasklet_struct *t = list;

    list = list->next;

    // Necessary synchronization with other processors
    if (tasklet_trylock (t)) {
      if (!atomic_read (&t->count)) {
        if (!test_and_clear_bit (TASKLET_STATE_SCHED, &t->state))
          BUG ();
        t->func (t->data);
        tasklet_unlock (t);
        continue;
      }
      tasklet_unlock (t);
    }

    // Put the executed tasklets back into queue
    local_irq_disable();
      t->next = NULL;
      *__get_cpu_var(tasklet_vec).tail = t;
      __get_cpu_var(tasklet_vec).tail = &(t->next);
      __raise_softirq_irqoff(TASKLET_SOFTIRQ);
    local_irq_enable();
  }
}