| 177 | } |
| 178 | |
| 179 | rt_err_t rt_prio_queue_pop(struct rt_prio_queue *que, |
| 180 | void *data, |
| 181 | rt_int32_t timeout) |
| 182 | { |
| 183 | rt_base_t level; |
| 184 | struct rt_prio_queue_item *item; |
| 185 | |
| 186 | RT_ASSERT(que); |
| 187 | RT_ASSERT(data); |
| 188 | |
| 189 | level = rt_hw_interrupt_disable(); |
| 190 | for (item = _do_pop(que); |
| 191 | item == RT_NULL; |
| 192 | item = _do_pop(que)) |
| 193 | { |
| 194 | rt_thread_t thread; |
| 195 | |
| 196 | if (timeout == 0) |
| 197 | { |
| 198 | rt_hw_interrupt_enable(level); |
| 199 | return -RT_ETIMEOUT; |
| 200 | } |
| 201 | |
| 202 | RT_DEBUG_NOT_IN_INTERRUPT; |
| 203 | |
| 204 | thread = rt_thread_self(); |
| 205 | thread->error = RT_EOK; |
| 206 | rt_thread_suspend(thread); |
| 207 | |
| 208 | rt_list_insert_before(&(que->suspended_pop_list), &RT_THREAD_LIST_NODE(thread)); |
| 209 | |
| 210 | if (timeout > 0) |
| 211 | { |
| 212 | rt_tick_t timeout_tick = timeout; |
| 213 | rt_timer_control(&(thread->thread_timer), |
| 214 | RT_TIMER_CTRL_SET_TIME, |
| 215 | &timeout_tick); |
| 216 | rt_timer_start(&(thread->thread_timer)); |
| 217 | } |
| 218 | |
| 219 | rt_hw_interrupt_enable(level); |
| 220 | |
| 221 | rt_schedule(); |
| 222 | |
| 223 | /* thread is waked up */ |
| 224 | if (thread->error != RT_EOK) |
| 225 | return thread->error; |
| 226 | level = rt_hw_interrupt_disable(); |
| 227 | } |
| 228 | |
| 229 | rt_hw_interrupt_enable(level); |
| 230 | |
| 231 | rt_memcpy(data, item+1, que->item_sz); |
| 232 | rt_mp_free(item); |
| 233 | |
| 234 | return RT_EOK; |
| 235 | } |
| 236 |
no test coverage detected