Subversion Repositories Kolibri OS

Rev

Rev 5056 | Rev 6102 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #ifndef _LINUX_WAIT_H
  2. #define _LINUX_WAIT_H
  3. /*
  4.  * Linux wait queue related types and methods
  5.  */
  6. #include <linux/list.h>
  7. #include <linux/stddef.h>
  8. #include <linux/spinlock.h>
  9. #include <asm/current.h>
  10.  
  11.  
  12.  
  13. #include <syscall.h>
  14.  
  15. typedef struct __wait_queue wait_queue_t;
  16. typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
  17. int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);
  18.  
  19. typedef struct __wait_queue_head wait_queue_head_t;
  20.  
  21. struct __wait_queue
  22. {
  23.     wait_queue_func_t func;
  24.     struct list_head task_list;
  25.     evhandle_t evnt;
  26. };
  27.  
  28. struct __wait_queue_head
  29. {
  30.     spinlock_t lock;
  31.     struct list_head task_list;
  32. };
  33. static inline int waitqueue_active(wait_queue_head_t *q)
  34. {
  35.         return !list_empty(&q->task_list);
  36. }
  37.  
  38. extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
  39. extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
  40. extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
  41.  
  42. static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
  43. {
  44.     list_add(&new->task_list, &head->task_list);
  45. }
  46.  
  47. /*
  48. #define __wait_event(wq, condition)                                     \
  49. do {                                                                    \
  50.         DEFINE_WAIT(__wait);                                            \
  51.                                                                         \
  52.         for (;;) {                                                      \
  53.                 prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
  54.                 if (condition)                                          \
  55.                         break;                                          \
  56.                 schedule();                                             \
  57.         }                                                               \
  58.         finish_wait(&wq, &__wait);                                      \
  59. } while (0)
  60.  
  61. */
  62.  
  63. #define wait_event_timeout(wq, condition, timeout)          \
  64. ({                                                          \
  65.     long __ret = timeout;                                   \
  66. do{                                                         \
  67.     wait_queue_t __wait = {                                 \
  68.         .task_list = LIST_HEAD_INIT(__wait.task_list),      \
  69.         .evnt      = CreateEvent(NULL, MANUAL_DESTROY),     \
  70.     };                                                      \
  71.     unsigned long flags;                                    \
  72.                                                             \
  73.     spin_lock_irqsave(&wq.lock, flags);                     \
  74.     if (list_empty(&__wait.task_list))                      \
  75.         __add_wait_queue(&wq, &__wait);                     \
  76.     spin_unlock_irqrestore(&wq.lock, flags);                \
  77.                                                             \
  78.     for(;;){                                                \
  79.         if (condition)                                      \
  80.             break;                                          \
  81.         WaitEventTimeout(__wait.evnt, timeout);             \
  82.     };                                                      \
  83.     if (!list_empty(&__wait.task_list)) {                   \
  84.         spin_lock_irqsave(&wq.lock, flags);                 \
  85.         list_del_init(&__wait.task_list);                   \
  86.         spin_unlock_irqrestore(&wq.lock, flags);            \
  87.     };                                                      \
  88.     DestroyEvent(__wait.evnt);                              \
  89. } while (0);                                                \
  90.     __ret;                                                  \
  91. })
  92.  
  93. #define wait_event_interruptible_timeout(wq, condition, timeout)    \
  94.         wait_event_timeout(wq, condition, timeout)
  95.  
  96.  
  97. #define wait_event(wq, condition)                           \
  98.     do{                                                     \
  99.     wait_queue_t __wait = {                                 \
  100.         .task_list = LIST_HEAD_INIT(__wait.task_list),      \
  101.         .evnt      = CreateEvent(NULL, MANUAL_DESTROY),     \
  102.     };                                                      \
  103.     unsigned long flags;                                    \
  104.                                                             \
  105.     spin_lock_irqsave(&wq.lock, flags);                     \
  106.     if (list_empty(&__wait.task_list))                      \
  107.         __add_wait_queue(&wq, &__wait);                     \
  108.     spin_unlock_irqrestore(&wq.lock, flags);                \
  109.                                                             \
  110.     for(;;){                                                \
  111.         if (condition)                                      \
  112.             break;                                          \
  113.         WaitEvent(__wait.evnt);                             \
  114.     };                                                      \
  115.     if (!list_empty_careful(&__wait.task_list)) {           \
  116.         spin_lock_irqsave(&wq.lock, flags);                 \
  117.         list_del_init(&__wait.task_list);                   \
  118.         spin_unlock_irqrestore(&wq.lock, flags);            \
  119.     };                                                      \
  120.     DestroyEvent(__wait.evnt);                              \
  121. } while (0)
  122.  
  123. #define wait_event_interruptible(wq, condition)             \
  124. ({                                                          \
  125.     int __ret = 0;                                          \
  126.     if (!(condition))                                       \
  127.         wait_event(wq, condition);                          \
  128.     __ret;                                                  \
  129. })
  130.  
  131.  
  132. static inline
  133. void wake_up_all(wait_queue_head_t *q)
  134. {
  135.     wait_queue_t *curr;
  136.     unsigned long flags;
  137.  
  138.     spin_lock_irqsave(&q->lock, flags);
  139.     list_for_each_entry(curr, &q->task_list, task_list)
  140.     {
  141. //        printf("raise event \n");
  142.  
  143.         kevent_t event;
  144.         event.code = -1;
  145.         RaiseEvent(curr->evnt, 0, &event);
  146.     }
  147.     spin_unlock_irqrestore(&q->lock, flags);
  148. }
  149.  
  150.  
  151. static inline void
  152. init_waitqueue_head(wait_queue_head_t *q)
  153. {
  154.     spin_lock_init(&q->lock);
  155.     INIT_LIST_HEAD(&q->task_list);
  156. };
  157.  
  158.  
  159. //struct completion {
  160. //    unsigned int done;
  161. //    wait_queue_head_t wait;
  162. //};
  163.  
  164. int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
  165.  
  166.  
  167. #define DEFINE_WAIT_FUNC(name, function)                                \
  168.         wait_queue_t name = {                                           \
  169.                 .func           = function,                             \
  170.                 .task_list      = LIST_HEAD_INIT((name).task_list),     \
  171.                 .evnt           = CreateEvent(NULL, MANUAL_DESTROY),    \
  172.         }
  173.  
  174. #define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
  175.  
  176.  
  177. #endif
  178.  
  179.