linux-old/include/linux/tqueue.h
<<
>>
Prefs
   1/*
   2 * tqueue.h --- task queue handling for Linux.
   3 *
   4 * Mostly based on a proposed bottom-half replacement code written by
   5 * Kai Petzke, wpp@marie.physik.tu-berlin.de.
   6 *
   7 * Modified for use in the Linux kernel by Theodore Ts'o,
   8 * tytso@mit.edu.  Any bugs are my fault, not Kai's.
   9 *
  10 * The original comment follows below.
  11 */
  12
  13#ifndef _LINUX_TQUEUE_H
  14#define _LINUX_TQUEUE_H
  15
  16#include <linux/spinlock.h>
  17#include <linux/list.h>
  18#include <asm/bitops.h>
  19#include <asm/system.h>
  20
  21/*
  22 * New proposed "bottom half" handlers:
  23 * (C) 1994 Kai Petzke, wpp@marie.physik.tu-berlin.de
  24 *
  25 * Advantages:
  26 * - Bottom halfs are implemented as a linked list.  You can have as many
  27 *   of them, as you want.
  28 * - No more scanning of a bit field is required upon call of a bottom half.
  29 * - Support for chained bottom half lists.  The run_task_queue() function can be
  30 *   used as a bottom half handler.  This is for example useful for bottom
  31 *   halfs, which want to be delayed until the next clock tick.
  32 *
  33 * Notes:
  34 * - Bottom halfs are called in the reverse order that they were linked into
  35 *   the list.
  36 */
  37
  38struct tq_struct {
  39        struct list_head list;          /* linked list of active bh's */
  40        unsigned long sync;             /* must be initialized to zero */
  41        void (*routine)(void *);        /* function to call */
  42        void *data;                     /* argument to function */
  43};
  44
  45/*
  46 * Emit code to initialise a tq_struct's routine and data pointers
  47 */
  48#define PREPARE_TQUEUE(_tq, _routine, _data)                    \
  49        do {                                                    \
  50                (_tq)->routine = _routine;                      \
  51                (_tq)->data = _data;                            \
  52        } while (0)
  53
  54/*
  55 * Emit code to initialise all of a tq_struct
  56 */
  57#define INIT_TQUEUE(_tq, _routine, _data)                       \
  58        do {                                                    \
  59                INIT_LIST_HEAD(&(_tq)->list);                   \
  60                (_tq)->sync = 0;                                \
  61                PREPARE_TQUEUE((_tq), (_routine), (_data));     \
  62        } while (0)
  63
  64typedef struct list_head task_queue;
  65
  66#define DECLARE_TASK_QUEUE(q)   LIST_HEAD(q)
  67#define TQ_ACTIVE(q)            (!list_empty(&q))
  68
  69extern task_queue tq_timer, tq_immediate, tq_disk;
  70
  71/*
  72 * To implement your own list of active bottom halfs, use the following
  73 * two definitions:
  74 *
  75 * DECLARE_TASK_QUEUE(my_tqueue);
  76 * struct tq_struct my_task = {
  77 *      routine: (void (*)(void *)) my_routine,
  78 *      data: &my_data
  79 * };
  80 *
  81 * To activate a bottom half on a list, use:
  82 *
  83 *      queue_task(&my_task, &my_tqueue);
  84 *
  85 * To later run the queued tasks use
  86 *
  87 *      run_task_queue(&my_tqueue);
  88 *
  89 * This allows you to do deferred processing.  For example, you could
  90 * have a task queue called tq_timer, which is executed within the timer
  91 * interrupt.
  92 */
  93
  94extern spinlock_t tqueue_lock;
  95
  96/*
  97 * Queue a task on a tq.  Return non-zero if it was successfully
  98 * added.
  99 */
 100static inline int queue_task(struct tq_struct *bh_pointer, task_queue *bh_list)
 101{
 102        int ret = 0;
 103        if (!test_and_set_bit(0,&bh_pointer->sync)) {
 104                unsigned long flags;
 105                spin_lock_irqsave(&tqueue_lock, flags);
 106                list_add_tail(&bh_pointer->list, bh_list);
 107                spin_unlock_irqrestore(&tqueue_lock, flags);
 108                ret = 1;
 109        }
 110        return ret;
 111}
 112
 113/*
 114 * Call all "bottom halfs" on a given list.
 115 */
 116
 117extern void __run_task_queue(task_queue *list);
 118
 119static inline void run_task_queue(task_queue *list)
 120{
 121        if (TQ_ACTIVE(*list))
 122                __run_task_queue(list);
 123}
 124
 125#endif /* _LINUX_TQUEUE_H */
 126
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.