waitqueue.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <stdint.h>
  2. #include <rthw.h>
  3. #include <rtdevice.h>
  4. #include <rtservice.h>
  5. extern struct rt_thread *rt_current_thread;
  6. void rt_wqueue_add(rt_wqueue_t *queue, struct rt_wqueue_node *node)
  7. {
  8. rt_base_t level;
  9. level = rt_hw_interrupt_disable();
  10. rt_list_insert_before(queue, &(node->list));
  11. rt_hw_interrupt_enable(level);
  12. }
  13. void rt_wqueue_remove(struct rt_wqueue_node *node)
  14. {
  15. rt_base_t level;
  16. level = rt_hw_interrupt_disable();
  17. rt_list_remove(&(node->list));
  18. rt_hw_interrupt_enable(level);
  19. }
  20. int __wqueue_default_wake(struct rt_wqueue_node *wait, void *key)
  21. {
  22. return 0;
  23. }
  24. void rt_wqueue_wakeup(rt_wqueue_t *queue, void *key)
  25. {
  26. rt_base_t level;
  27. register int need_schedule = 0;
  28. struct rt_list_node *node;
  29. struct rt_wqueue_node *entry;
  30. if (rt_list_isempty(queue))
  31. return;
  32. level = rt_hw_interrupt_disable();
  33. for (node = queue->next; node != queue; node = node->next)
  34. {
  35. entry = rt_list_entry(node, struct rt_wqueue_node, list);
  36. if (entry->wakeup(entry, key) == 0)
  37. {
  38. rt_thread_resume(entry->polling_thread);
  39. need_schedule = 1;
  40. rt_wqueue_remove(entry);
  41. break;
  42. }
  43. }
  44. rt_hw_interrupt_enable(level);
  45. if (need_schedule)
  46. rt_schedule();
  47. }
  48. int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec)
  49. {
  50. int tick;
  51. rt_thread_t tid = rt_current_thread;
  52. rt_timer_t tmr = &(tid->thread_timer);
  53. struct rt_wqueue_node __wait;
  54. tick = rt_tick_from_millisecond(msec);
  55. if ((condition) || (tick == 0))
  56. return 0;
  57. __wait.polling_thread = rt_thread_self();
  58. __wait.key = 0;
  59. __wait.wakeup = __wqueue_default_wake;
  60. rt_list_init(&__wait.list);
  61. rt_wqueue_add(queue, &__wait);
  62. /* current context checking */
  63. RT_DEBUG_NOT_IN_INTERRUPT;
  64. rt_thread_suspend(tid);
  65. /* start timer */
  66. if (tick != RT_WAITING_FOREVER)
  67. {
  68. rt_timer_control(tmr,
  69. RT_TIMER_CTRL_SET_TIME,
  70. &tick);
  71. rt_timer_start(tmr);
  72. }
  73. rt_schedule();
  74. rt_wqueue_remove(&__wait);
  75. return 0;
  76. }