tqueue.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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