* @brief This function will write data to the data queue. If the data queue is full, * the thread will suspend for the specified amount of time. * * @param queue is a pointer to the data queue object. * . * @param data_ptr is the buffer pointer of the data to be written. * * @param size is the size in bytes of the data to be written. * * @param timeout is the wait
| 90 | * When the return value is -RT_ETIMEOUT, it means the specified time out. |
| 91 | */ |
| 92 | rt_err_t rt_data_queue_push(struct rt_data_queue *queue, |
| 93 | const void *data_ptr, |
| 94 | rt_size_t data_size, |
| 95 | rt_int32_t timeout) |
| 96 | { |
| 97 | rt_base_t level; |
| 98 | rt_thread_t thread; |
| 99 | rt_err_t result; |
| 100 | |
| 101 | RT_ASSERT(queue != RT_NULL); |
| 102 | RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); |
| 103 | |
| 104 | /* current context checking */ |
| 105 | RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); |
| 106 | |
| 107 | result = RT_EOK; |
| 108 | thread = rt_thread_self(); |
| 109 | |
| 110 | level = rt_spin_lock_irqsave(&(queue->spinlock)); |
| 111 | while (queue->is_full) |
| 112 | { |
| 113 | /* queue is full */ |
| 114 | if (timeout == 0) |
| 115 | { |
| 116 | result = -RT_ETIMEOUT; |
| 117 | |
| 118 | goto __exit; |
| 119 | } |
| 120 | |
| 121 | /* reset thread error number */ |
| 122 | thread->error = RT_EOK; |
| 123 | |
| 124 | /* suspend thread on the push list */ |
| 125 | result = rt_thread_suspend_to_list(thread, &queue->suspended_push_list, |
| 126 | RT_IPC_FLAG_FIFO, RT_UNINTERRUPTIBLE); |
| 127 | if (result == RT_EOK) |
| 128 | { |
| 129 | /* start timer */ |
| 130 | if (timeout > 0) |
| 131 | { |
| 132 | rt_tick_t timeout_tick = timeout; |
| 133 | /* reset the timeout of thread timer and start it */ |
| 134 | rt_timer_control(&(thread->thread_timer), |
| 135 | RT_TIMER_CTRL_SET_TIME, |
| 136 | &timeout_tick); |
| 137 | rt_timer_start(&(thread->thread_timer)); |
| 138 | } |
| 139 | |
| 140 | /* enable interrupt */ |
| 141 | rt_spin_unlock_irqrestore(&(queue->spinlock), level); |
| 142 | |
| 143 | /* do schedule */ |
| 144 | rt_schedule(); |
| 145 | |
| 146 | /* thread is waked up */ |
| 147 | level = rt_spin_lock_irqsave(&(queue->spinlock)); |
| 148 | |
| 149 | /* error may be modified by waker, so take the lock before accessing it */ |
no test coverage detected