* @brief This function will wait for a completion, if the completion is unavailable, the thread shall wait for * the completion up to a specified time. * * @param completion is a pointer to a completion object. * * @param timeout is a timeout period (unit: OS ticks). If the completion is unavailable, the thread will wait for * the completion done up to the amount of tim
| 63 | * @warning This function can ONLY be called in the thread context. It MUST NOT be called in interrupt context. |
| 64 | */ |
| 65 | rt_err_t rt_completion_wait_flags(struct rt_completion *completion, |
| 66 | rt_int32_t timeout, int suspend_flag) |
| 67 | { |
| 68 | rt_err_t result; |
| 69 | rt_base_t level; |
| 70 | rt_thread_t thread; |
| 71 | RT_ASSERT(completion != RT_NULL); |
| 72 | |
| 73 | /* current context checking */ |
| 74 | RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); |
| 75 | |
| 76 | result = RT_EOK; |
| 77 | thread = rt_thread_self(); |
| 78 | |
| 79 | level = rt_spin_lock_irqsave(&_completion_lock); |
| 80 | |
| 81 | __try_again: |
| 82 | if (RT_COMPLETION_FLAG(completion) != RT_COMPLETED) |
| 83 | { |
| 84 | /* only one thread can suspend on complete */ |
| 85 | RT_ASSERT(RT_COMPLETION_THREAD(completion) == RT_NULL); |
| 86 | |
| 87 | if (timeout == 0) |
| 88 | { |
| 89 | result = -RT_ETIMEOUT; |
| 90 | goto __exit; |
| 91 | } |
| 92 | else |
| 93 | { |
| 94 | /* reset thread error number */ |
| 95 | thread->error = RT_EOK; |
| 96 | |
| 97 | /* suspend thread */ |
| 98 | result = rt_thread_suspend_with_flag(thread, suspend_flag); |
| 99 | if (result == RT_EOK) |
| 100 | { |
| 101 | /* add to suspended thread */ |
| 102 | rt_base_t waiting_stat = RT_COMPLETION_NEW_STAT(thread, RT_UNCOMPLETED); |
| 103 | completion->susp_thread_n_flag = waiting_stat; |
| 104 | |
| 105 | /* current context checking */ |
| 106 | RT_DEBUG_NOT_IN_INTERRUPT; |
| 107 | |
| 108 | /* start timer */ |
| 109 | if (timeout > 0) |
| 110 | { |
| 111 | rt_tick_t timeout_tick = timeout; |
| 112 | /* reset the timeout of thread timer and start it */ |
| 113 | rt_timer_control(&(thread->thread_timer), |
| 114 | RT_TIMER_CTRL_SET_TIME, |
| 115 | &timeout_tick); |
| 116 | rt_timer_start(&(thread->thread_timer)); |
| 117 | } |
| 118 | /* enable interrupt */ |
| 119 | rt_spin_unlock_irqrestore(&_completion_lock, level); |
| 120 | |
| 121 | /* do schedule */ |
| 122 | rt_schedule(); |
no test coverage detected