wait.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _LINUX_WAIT_H
  2. #define _LINUX_WAIT_H
  3. #define WNOHANG 0x00000001
  4. #define WUNTRACED 0x00000002
  5. #define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads in this group */
  6. #define __WALL 0x40000000 /* Wait on all children, regardless of type */
  7. #define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */
  8. #ifdef __KERNEL__
  9. #include <linux/kernel.h>
  10. #include <linux/list.h>
  11. #include <linux/stddef.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/config.h>
  14. #include <asm/page.h>
  15. #include <asm/processor.h>
  16. /*
  17.  * Debug control.  Slow but useful.
  18.  */
  19. #if defined(CONFIG_DEBUG_WAITQ)
  20. #define WAITQUEUE_DEBUG 1
  21. #else
  22. #define WAITQUEUE_DEBUG 0
  23. #endif
  24. struct __wait_queue {
  25. unsigned int flags;
  26. #define WQ_FLAG_EXCLUSIVE 0x01
  27. struct task_struct * task;
  28. struct list_head task_list;
  29. #if WAITQUEUE_DEBUG
  30. long __magic;
  31. long __waker;
  32. #endif
  33. };
  34. typedef struct __wait_queue wait_queue_t;
  35. /*
  36.  * 'dual' spinlock architecture. Can be switched between spinlock_t and
  37.  * rwlock_t locks via changing this define. Since waitqueues are quite
  38.  * decoupled in the new architecture, lightweight 'simple' spinlocks give
  39.  * us slightly better latencies and smaller waitqueue structure size.
  40.  */
  41. #define USE_RW_WAIT_QUEUE_SPINLOCK 0
  42. #if USE_RW_WAIT_QUEUE_SPINLOCK
  43. # define wq_lock_t rwlock_t
  44. # define WAITQUEUE_RW_LOCK_UNLOCKED RW_LOCK_UNLOCKED
  45. # define wq_read_lock read_lock
  46. # define wq_read_lock_irqsave read_lock_irqsave
  47. # define wq_read_unlock_irqrestore read_unlock_irqrestore
  48. # define wq_read_unlock read_unlock
  49. # define wq_write_lock_irq write_lock_irq
  50. # define wq_write_lock_irqsave write_lock_irqsave
  51. # define wq_write_unlock_irqrestore write_unlock_irqrestore
  52. # define wq_write_unlock write_unlock
  53. #else
  54. # define wq_lock_t spinlock_t
  55. # define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
  56. # define wq_read_lock spin_lock
  57. # define wq_read_lock_irqsave spin_lock_irqsave
  58. # define wq_read_unlock spin_unlock
  59. # define wq_read_unlock_irqrestore spin_unlock_irqrestore
  60. # define wq_write_lock_irq spin_lock_irq
  61. # define wq_write_lock_irqsave spin_lock_irqsave
  62. # define wq_write_unlock_irqrestore spin_unlock_irqrestore
  63. # define wq_write_unlock spin_unlock
  64. #endif
  65. struct __wait_queue_head {
  66. wq_lock_t lock;
  67. struct list_head task_list;
  68. #if WAITQUEUE_DEBUG
  69. long __magic;
  70. long __creator;
  71. #endif
  72. };
  73. typedef struct __wait_queue_head wait_queue_head_t;
  74. /*
  75.  * Debugging macros.  We eschew `do { } while (0)' because gcc can generate
  76.  * spurious .aligns.
  77.  */
  78. #if WAITQUEUE_DEBUG
  79. #define WQ_BUG() BUG()
  80. #define CHECK_MAGIC(x)
  81. do {
  82. if ((x) != (long)&(x)) {
  83. printk("bad magic %lx (should be %lx), ",
  84. (long)x, (long)&(x));
  85. WQ_BUG();
  86. }
  87. } while (0)
  88. #define CHECK_MAGIC_WQHEAD(x)
  89. do {
  90. if ((x)->__magic != (long)&((x)->__magic)) {
  91. printk("bad magic %lx (should be %lx, creator %lx), ",
  92. (x)->__magic, (long)&((x)->__magic), (x)->__creator);
  93. WQ_BUG();
  94. }
  95. } while (0)
  96. #define WQ_CHECK_LIST_HEAD(list) 
  97. do {
  98. if (!(list)->next || !(list)->prev)
  99. WQ_BUG();
  100. } while(0)
  101. #define WQ_NOTE_WAKER(tsk)
  102. do {
  103. (tsk)->__waker = (long)__builtin_return_address(0);
  104. } while (0)
  105. #else
  106. #define WQ_BUG()
  107. #define CHECK_MAGIC(x)
  108. #define CHECK_MAGIC_WQHEAD(x)
  109. #define WQ_CHECK_LIST_HEAD(list)
  110. #define WQ_NOTE_WAKER(tsk)
  111. #endif
  112. /*
  113.  * Macros for declaration and initialisaton of the datatypes
  114.  */
  115. #if WAITQUEUE_DEBUG
  116. # define __WAITQUEUE_DEBUG_INIT(name) (long)&(name).__magic, 0
  117. # define __WAITQUEUE_HEAD_DEBUG_INIT(name) (long)&(name).__magic, (long)&(name).__magic
  118. #else
  119. # define __WAITQUEUE_DEBUG_INIT(name)
  120. # define __WAITQUEUE_HEAD_DEBUG_INIT(name)
  121. #endif
  122. #define __WAITQUEUE_INITIALIZER(name, tsk) {
  123. task: tsk,
  124. task_list: { NULL, NULL },
  125.  __WAITQUEUE_DEBUG_INIT(name)}
  126. #define DECLARE_WAITQUEUE(name, tsk)
  127. wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
  128. #define __WAIT_QUEUE_HEAD_INITIALIZER(name) {
  129. lock: WAITQUEUE_RW_LOCK_UNLOCKED,
  130. task_list: { &(name).task_list, &(name).task_list },
  131. __WAITQUEUE_HEAD_DEBUG_INIT(name)}
  132. #define DECLARE_WAIT_QUEUE_HEAD(name) 
  133. wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
  134. static inline void init_waitqueue_head(wait_queue_head_t *q)
  135. {
  136. #if WAITQUEUE_DEBUG
  137. if (!q)
  138. WQ_BUG();
  139. #endif
  140. q->lock = WAITQUEUE_RW_LOCK_UNLOCKED;
  141. INIT_LIST_HEAD(&q->task_list);
  142. #if WAITQUEUE_DEBUG
  143. q->__magic = (long)&q->__magic;
  144. q->__creator = (long)current_text_addr();
  145. #endif
  146. }
  147. static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
  148. {
  149. #if WAITQUEUE_DEBUG
  150. if (!q || !p)
  151. WQ_BUG();
  152. #endif
  153. q->flags = 0;
  154. q->task = p;
  155. #if WAITQUEUE_DEBUG
  156. q->__magic = (long)&q->__magic;
  157. #endif
  158. }
  159. static inline int waitqueue_active(wait_queue_head_t *q)
  160. {
  161. #if WAITQUEUE_DEBUG
  162. if (!q)
  163. WQ_BUG();
  164. CHECK_MAGIC_WQHEAD(q);
  165. #endif
  166. return !list_empty(&q->task_list);
  167. }
  168. static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
  169. {
  170. #if WAITQUEUE_DEBUG
  171. if (!head || !new)
  172. WQ_BUG();
  173. CHECK_MAGIC_WQHEAD(head);
  174. CHECK_MAGIC(new->__magic);
  175. if (!head->task_list.next || !head->task_list.prev)
  176. WQ_BUG();
  177. #endif
  178. list_add(&new->task_list, &head->task_list);
  179. }
  180. /*
  181.  * Used for wake-one threads:
  182.  */
  183. static inline void __add_wait_queue_tail(wait_queue_head_t *head,
  184. wait_queue_t *new)
  185. {
  186. #if WAITQUEUE_DEBUG
  187. if (!head || !new)
  188. WQ_BUG();
  189. CHECK_MAGIC_WQHEAD(head);
  190. CHECK_MAGIC(new->__magic);
  191. if (!head->task_list.next || !head->task_list.prev)
  192. WQ_BUG();
  193. #endif
  194. list_add_tail(&new->task_list, &head->task_list);
  195. }
  196. static inline void __remove_wait_queue(wait_queue_head_t *head,
  197. wait_queue_t *old)
  198. {
  199. #if WAITQUEUE_DEBUG
  200. if (!old)
  201. WQ_BUG();
  202. CHECK_MAGIC(old->__magic);
  203. #endif
  204. list_del(&old->task_list);
  205. }
  206. #endif /* __KERNEL__ */
  207. #endif