* @brief This function will send a message to the messagequeue object. If * there is a thread suspended on the messagequeue, the thread will be * resumed. * * @note When using this function to send a message, if the messagequeue is * fully used, the current thread will wait for a timeout. If reaching * the timeout and there is still no space ava
| 3379 | * context. |
| 3380 | */ |
| 3381 | static rt_err_t _rt_mq_send_wait(rt_mq_t mq, |
| 3382 | const void *buffer, |
| 3383 | rt_size_t size, |
| 3384 | rt_int32_t prio, |
| 3385 | rt_int32_t timeout, |
| 3386 | int suspend_flag) |
| 3387 | { |
| 3388 | rt_base_t level; |
| 3389 | struct rt_mq_message *msg; |
| 3390 | rt_uint32_t tick_delta; |
| 3391 | struct rt_thread *thread; |
| 3392 | rt_err_t ret; |
| 3393 | |
| 3394 | RT_UNUSED(prio); |
| 3395 | |
| 3396 | /* parameter check */ |
| 3397 | RT_ASSERT(mq != RT_NULL); |
| 3398 | RT_ASSERT(rt_object_get_type(&mq->parent.parent) == RT_Object_Class_MessageQueue); |
| 3399 | RT_ASSERT(buffer != RT_NULL); |
| 3400 | RT_ASSERT(size != 0); |
| 3401 | |
| 3402 | /* current context checking */ |
| 3403 | RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); |
| 3404 | |
| 3405 | /* greater than one message size */ |
| 3406 | if (size > mq->msg_size) |
| 3407 | return -RT_ERROR; |
| 3408 | |
| 3409 | /* initialize delta tick */ |
| 3410 | tick_delta = 0; |
| 3411 | /* get current thread */ |
| 3412 | thread = rt_thread_self(); |
| 3413 | |
| 3414 | RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mq->parent.parent))); |
| 3415 | |
| 3416 | level = rt_spin_lock_irqsave(&(mq->spinlock)); |
| 3417 | |
| 3418 | /* get a free list, there must be an empty item */ |
| 3419 | msg = (struct rt_mq_message *)mq->msg_queue_free; |
| 3420 | /* for non-blocking call */ |
| 3421 | if (msg == RT_NULL && timeout == 0) |
| 3422 | { |
| 3423 | rt_spin_unlock_irqrestore(&(mq->spinlock), level); |
| 3424 | |
| 3425 | return -RT_EFULL; |
| 3426 | } |
| 3427 | |
| 3428 | /* message queue is full */ |
| 3429 | while ((msg = (struct rt_mq_message *)mq->msg_queue_free) == RT_NULL) |
| 3430 | { |
| 3431 | /* reset error number in thread */ |
| 3432 | thread->error = -RT_EINTR; |
| 3433 | |
| 3434 | /* no waiting, return timeout */ |
| 3435 | if (timeout == 0) |
| 3436 | { |
| 3437 | rt_spin_unlock_irqrestore(&(mq->spinlock), level); |
| 3438 |
no test coverage detected