diff options
| author | tmmdh <[email protected]> | 2021-01-20 18:45:20 +0800 |
|---|---|---|
| committer | tmmdh <[email protected]> | 2021-01-20 18:45:20 +0800 |
| commit | 9db4d446382426d215ffe79f60920c98a8b1be53 (patch) | |
| tree | a3bd61199194d5f8251bf7ee889e22baedf5dc31 /src/ipc.c | |
| parent | 55c0a9f27900d19556d52110be6397f3ee15a6c3 (diff) | |
| parent | afd575105d2fdd29fb003fb49c6e4f5446f824ce (diff) | |
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
Diffstat (limited to 'src/ipc.c')
| -rwxr-xr-x | src/ipc.c | 80 |
1 files changed, 76 insertions, 4 deletions
@@ -37,7 +37,8 @@ * 2020-07-29 Meco Man fix thread->event_set/event_info when received an * event without pending * 2020-10-11 Meco Man add value overflow-check code - * 2020-10-25 hupu fix priority inversion bug of mutex + * 2021-01-03 Meco Man add rt_mb_urgent() + * 2021-01-20 hupu fix priority inversion bug of mutex */ #include <rtthread.h> @@ -1576,7 +1577,6 @@ rt_err_t rt_mb_send_wait(rt_mailbox_t mb, if (mb->entry == mb->size && timeout == 0) { rt_hw_interrupt_enable(temp); - return -RT_EFULL; } @@ -1698,6 +1698,71 @@ rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value) RTM_EXPORT(rt_mb_send); /** + * This function will send an urgent mail to mailbox object, if there are threads + * suspended on mailbox object, it will be waked up. This function will return + * immediately. + * + * @param mb the mailbox object + * @param value the mail + * + * @return the error code + */ +rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) +{ + register rt_ubase_t temp; + + /* parameter check */ + RT_ASSERT(mb != RT_NULL); + RT_ASSERT(rt_object_get_type(&mb->parent.parent) == RT_Object_Class_MailBox); + + RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mb->parent.parent))); + + /* disable interrupt */ + temp = rt_hw_interrupt_disable(); + + if (mb->entry == mb->size) + { + rt_hw_interrupt_enable(temp); + return -RT_EFULL; + } + + /* rewind to the previous position */ + if (mb->out_offset > 0) + { + mb->out_offset --; + } + else + { + mb->out_offset = mb->size - 1; + } + + /* set ptr */ + mb->msg_pool[mb->out_offset] = value; + + /* increase message entry */ + mb->entry ++; + + /* resume suspended thread */ + if (!rt_list_isempty(&mb->parent.suspend_thread)) + { + rt_ipc_list_resume(&(mb->parent.suspend_thread)); + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); + + rt_schedule(); + + return RT_EOK; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); + + return RT_EOK; +} +RTM_EXPORT(rt_mb_urgent); + +/** * This function will receive a mail from mailbox object, if there is no mail * in mailbox object, the thread shall wait for a specified time. * @@ -1807,8 +1872,12 @@ rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout) ++ mb->out_offset; if (mb->out_offset >= mb->size) mb->out_offset = 0; + /* decrease message entry */ - mb->entry --; + if(mb->entry > 0) + { + mb->entry --; + } /* resume suspended thread */ if (!rt_list_isempty(&(mb->suspend_sender_thread))) @@ -2482,7 +2551,10 @@ rt_err_t rt_mq_recv(rt_mq_t mq, mq->msg_queue_tail = RT_NULL; /* decrease message entry */ - mq->entry --; + if(mq->entry > 0) + { + mq->entry --; + } /* enable interrupt */ rt_hw_interrupt_enable(temp); |
