From 89cf5886aa19b96b02ebeeeb8f7b07a25318cd7d Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sun, 3 Jan 2021 06:19:14 +0800 Subject: [PATCH 1/5] add rt_mb_urgent() and rt_mb_urgent_wait() --- src/ipc.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/src/ipc.c b/src/ipc.c index 4261f617b0..a3069b1f37 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -37,6 +37,7 @@ * 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 + * 2021-01-03 Meco Man add rt_mb_urgent() and rt_mb_urgent_wait() */ #include @@ -1654,6 +1655,169 @@ 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 the mailbox is full, + * current thread will be suspended until timeout. + * + * @param mb the mailbox object + * @param value the mail + * @param timeout the waiting time + * + * @return the error code + */ +rt_err_t rt_mb_urgent_wait(rt_mailbox_t mb, + rt_ubase_t value, + rt_int32_t timeout) +{ + struct rt_thread *thread; + register rt_ubase_t temp; + rt_uint32_t tick_delta; + + /* parameter check */ + RT_ASSERT(mb != RT_NULL); + RT_ASSERT(rt_object_get_type(&mb->parent.parent) == RT_Object_Class_MailBox); + + /* initialize delta tick */ + tick_delta = 0; + /* get current thread */ + thread = rt_thread_self(); + + RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mb->parent.parent))); + + /* disable interrupt */ + temp = rt_hw_interrupt_disable(); + + /* for non-blocking call */ + if (mb->entry == mb->size && timeout == 0) + { + rt_hw_interrupt_enable(temp); + + return -RT_EFULL; + } + + /* mailbox is full */ + while (mb->entry == mb->size) + { + /* reset error number in thread */ + thread->error = RT_EOK; + + /* no waiting, return timeout */ + if (timeout == 0) + { + /* enable interrupt */ + rt_hw_interrupt_enable(temp); + + return -RT_EFULL; + } + + RT_DEBUG_IN_THREAD_CONTEXT; + /* suspend current thread */ + rt_ipc_list_suspend(&(mb->suspend_sender_thread), + thread, + mb->parent.parent.flag); + + /* has waiting time, start thread timer */ + if (timeout > 0) + { + /* get the start tick of timer */ + tick_delta = rt_tick_get(); + + RT_DEBUG_LOG(RT_DEBUG_IPC, ("mb_send_wait: start timer of thread:%s\n", + thread->name)); + + /* reset the timeout of thread timer and start it */ + rt_timer_control(&(thread->thread_timer), + RT_TIMER_CTRL_SET_TIME, + &timeout); + rt_timer_start(&(thread->thread_timer)); + } + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); + + /* re-schedule */ + rt_schedule(); + + /* resume from suspend state */ + if (thread->error != RT_EOK) + { + /* return error */ + return thread->error; + } + + /* disable interrupt */ + temp = rt_hw_interrupt_disable(); + + /* if it's not waiting forever and then re-calculate timeout tick */ + if (timeout > 0) + { + tick_delta = rt_tick_get() - tick_delta; + timeout -= tick_delta; + if (timeout < 0) + timeout = 0; + } + } + + /* 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; + + if(mb->entry < RT_MB_ENTRY_MAX) + { + /* increase message entry */ + mb->entry ++; + } + else + { + rt_hw_interrupt_enable(temp); /* enable interrupt */ + return -RT_EFULL; /* value overflowed */ + } + + /* 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_wait); + +/** + * 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, if you want blocking send, use rt_mb_urgent_wait instead. + * + * @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) +{ + return rt_mb_urgent_wait(mb, value, 0); +} +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. From 661f54d1e0ea6d7b3c05d43d493f660f58570cb2 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sun, 3 Jan 2021 23:28:15 +0800 Subject: [PATCH 2/5] update --- src/ipc.c | 106 +++--------------------------------------------------- 1 file changed, 5 insertions(+), 101 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index a3069b1f37..d1c4474f14 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -37,7 +37,7 @@ * 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 - * 2021-01-03 Meco Man add rt_mb_urgent() and rt_mb_urgent_wait() + * 2021-01-03 Meco Man add rt_mb_urgent() */ #include @@ -1656,108 +1656,28 @@ 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 the mailbox is full, - * current thread will be suspended until timeout. + * 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, if you want blocking send, use rt_mb_urgent_wait instead. * * @param mb the mailbox object * @param value the mail - * @param timeout the waiting time * * @return the error code */ -rt_err_t rt_mb_urgent_wait(rt_mailbox_t mb, - rt_ubase_t value, - rt_int32_t timeout) +rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) { - struct rt_thread *thread; register rt_ubase_t temp; - rt_uint32_t tick_delta; /* parameter check */ RT_ASSERT(mb != RT_NULL); RT_ASSERT(rt_object_get_type(&mb->parent.parent) == RT_Object_Class_MailBox); - /* initialize delta tick */ - tick_delta = 0; - /* get current thread */ - thread = rt_thread_self(); - RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mb->parent.parent))); /* disable interrupt */ temp = rt_hw_interrupt_disable(); - /* for non-blocking call */ - if (mb->entry == mb->size && timeout == 0) - { - rt_hw_interrupt_enable(temp); - - return -RT_EFULL; - } - - /* mailbox is full */ - while (mb->entry == mb->size) - { - /* reset error number in thread */ - thread->error = RT_EOK; - - /* no waiting, return timeout */ - if (timeout == 0) - { - /* enable interrupt */ - rt_hw_interrupt_enable(temp); - - return -RT_EFULL; - } - - RT_DEBUG_IN_THREAD_CONTEXT; - /* suspend current thread */ - rt_ipc_list_suspend(&(mb->suspend_sender_thread), - thread, - mb->parent.parent.flag); - - /* has waiting time, start thread timer */ - if (timeout > 0) - { - /* get the start tick of timer */ - tick_delta = rt_tick_get(); - - RT_DEBUG_LOG(RT_DEBUG_IPC, ("mb_send_wait: start timer of thread:%s\n", - thread->name)); - - /* reset the timeout of thread timer and start it */ - rt_timer_control(&(thread->thread_timer), - RT_TIMER_CTRL_SET_TIME, - &timeout); - rt_timer_start(&(thread->thread_timer)); - } - - /* enable interrupt */ - rt_hw_interrupt_enable(temp); - - /* re-schedule */ - rt_schedule(); - - /* resume from suspend state */ - if (thread->error != RT_EOK) - { - /* return error */ - return thread->error; - } - - /* disable interrupt */ - temp = rt_hw_interrupt_disable(); - - /* if it's not waiting forever and then re-calculate timeout tick */ - if (timeout > 0) - { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; - if (timeout < 0) - timeout = 0; - } - } - /* rewind to the previous position */ if(mb->out_offset > 0) { @@ -1800,22 +1720,6 @@ rt_err_t rt_mb_urgent_wait(rt_mailbox_t mb, return RT_EOK; } -RTM_EXPORT(rt_mb_urgent_wait); - -/** - * 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, if you want blocking send, use rt_mb_urgent_wait instead. - * - * @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) -{ - return rt_mb_urgent_wait(mb, value, 0); -} RTM_EXPORT(rt_mb_urgent); /** From 234f1aec99a4283e29aff1b2212d23d47aec54a7 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Sun, 3 Jan 2021 23:41:07 +0800 Subject: [PATCH 3/5] update --- src/ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc.c b/src/ipc.c index d1c4474f14..d8b9327795 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -1658,7 +1658,7 @@ 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, if you want blocking send, use rt_mb_urgent_wait instead. + * immediately. * * @param mb the mailbox object * @param value the mail From cd6ca24f88eb167486189eae7d742293203d60e5 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Mon, 4 Jan 2021 22:34:50 +0800 Subject: [PATCH 4/5] update --- src/ipc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index d8b9327795..11b7e266f9 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -1534,7 +1534,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; } @@ -1678,8 +1677,14 @@ rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) /* 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) + if (mb->out_offset > 0) { mb->out_offset --; } @@ -1691,7 +1696,7 @@ rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) /* set ptr */ mb->msg_pool[mb->out_offset] = value; - if(mb->entry < RT_MB_ENTRY_MAX) + if (mb->entry < RT_MB_ENTRY_MAX) { /* increase message entry */ mb->entry ++; From 3f9b3f57ea7f166f19b7d49d071c01874506814d Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Tue, 5 Jan 2021 09:20:53 +0800 Subject: [PATCH 5/5] update --- src/ipc.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index 11b7e266f9..be2baee9b5 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -1696,16 +1696,8 @@ rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) /* set ptr */ mb->msg_pool[mb->out_offset] = value; - if (mb->entry < RT_MB_ENTRY_MAX) - { - /* increase message entry */ - mb->entry ++; - } - else - { - rt_hw_interrupt_enable(temp); /* enable interrupt */ - return -RT_EFULL; /* value overflowed */ - } + /* increase message entry */ + mb->entry ++; /* resume suspended thread */ if (!rt_list_isempty(&mb->parent.suspend_thread))