-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[kernel]fix thread error code to avoid spurious error display in list_thread. #10972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,7 @@ | |
| * 2022-10-16 Bernard add prioceiling feature in mutex | ||
| * 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size | ||
| * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable | ||
| * 2025-11-23 Rbb666 fix thread error code to avoid spurious error display in list_thread | ||
| */ | ||
|
|
||
| #include <rtthread.h> | ||
|
|
@@ -87,6 +88,28 @@ rt_inline rt_err_t _ipc_object_init(struct rt_ipc_object *ipc) | |
| return RT_EOK; | ||
| } | ||
|
|
||
| /** | ||
| * @brief This function normalizes the thread error code after IPC wait operation. | ||
| * | ||
| * @note This function translates the internal RT_EWAITPEND sentinel value back to RT_EINTR | ||
| * for the caller. If the error code is still RT_EWAITPEND after scheduling, it means | ||
| * the thread was woken by a signal rather than by successfully acquiring the resource | ||
| * or timing out. | ||
| * | ||
| * @param thread is a pointer to the thread object whose error code needs to be checked. | ||
| * | ||
| * @return Return the thread's error code. When the return value is RT_EOK, the IPC operation succeeded. | ||
| * When the return value is RT_EINTR, the operation was interrupted (interrupted system call). | ||
| * When the return value is RT_ETIMEOUT, the operation timed out. | ||
| */ | ||
| static rt_err_t _ipc_wait_result(rt_thread_t thread) | ||
| { | ||
| if (thread->error == -RT_EWAITPEND) | ||
| { | ||
| thread->error = -RT_EINTR; | ||
| } | ||
| return thread->error; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Dequeue a thread from suspended list and set it to ready. The 2 are | ||
|
|
@@ -597,8 +620,8 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag) | |
| /* get current thread */ | ||
| thread = rt_thread_self(); | ||
|
|
||
| /* reset thread error number */ | ||
| thread->error = RT_EINTR; | ||
| /* mark wait pending errno */ | ||
| thread->error = -RT_EWAITPEND; | ||
|
|
||
| LOG_D("sem take: suspend thread - %s", thread->parent.name); | ||
|
|
||
|
|
@@ -630,9 +653,11 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag) | |
| /* do schedule */ | ||
| rt_schedule(); | ||
|
|
||
| if (thread->error != RT_EOK) | ||
| /* normalize wait result after reschedule */ | ||
| ret = _ipc_wait_result(thread); | ||
| if (ret != RT_EOK) | ||
| { | ||
| return thread->error > 0 ? -thread->error : thread->error; | ||
| return ret > 0 ? -ret : ret; | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -1403,6 +1428,9 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend | |
| LOG_D("mutex_take: suspend thread: %s", | ||
| thread->parent.name); | ||
|
|
||
| /* mark wait pending errno */ | ||
| thread->error = -RT_EWAITPEND; | ||
|
|
||
| /* suspend current thread */ | ||
| ret = rt_thread_suspend_to_list(thread, &(mutex->parent.suspend_thread), | ||
| mutex->parent.parent.flag, suspend_flag); | ||
|
|
@@ -1452,13 +1480,16 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend | |
|
|
||
| rt_spin_lock(&(mutex->spinlock)); | ||
|
|
||
| /* normalize wait result after reschedule */ | ||
| ret = _ipc_wait_result(thread); | ||
|
|
||
| if (mutex->owner == thread) | ||
| { | ||
| /** | ||
| * get mutex successfully | ||
| * Note: assert to avoid an unexpected resume | ||
| * Note: clear any temporary error from interruptible wait | ||
| */ | ||
| RT_ASSERT(thread->error == RT_EOK); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里应该保留原来的逻辑 |
||
| thread->error = RT_EOK; | ||
| } | ||
| else | ||
| { | ||
|
|
@@ -1467,9 +1498,6 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend | |
| rt_bool_t need_update = RT_FALSE; | ||
| RT_ASSERT(mutex->owner != thread); | ||
|
|
||
| /* get value first before calling to other APIs */ | ||
| ret = thread->error; | ||
|
|
||
| /* unexpected resume */ | ||
| if (ret == RT_EOK) | ||
| { | ||
|
|
@@ -1673,6 +1701,9 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) | |
| /* cleanup pending object */ | ||
| next_thread->pending_object = RT_NULL; | ||
|
|
||
| /* clear any temporary error from interruptible wait */ | ||
| next_thread->error = RT_EOK; | ||
|
|
||
| /* update mutex priority */ | ||
| if (!rt_list_isempty(&(mutex->parent.suspend_thread))) | ||
| { | ||
|
|
@@ -2121,8 +2152,6 @@ static rt_err_t _rt_event_recv(rt_event_t event, | |
| status = -RT_ERROR; | ||
| /* get current thread */ | ||
| thread = rt_thread_self(); | ||
| /* reset thread error */ | ||
| thread->error = -RT_EINTR; | ||
|
|
||
| RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(event->parent.parent))); | ||
|
|
||
|
|
@@ -2176,6 +2205,9 @@ static rt_err_t _rt_event_recv(rt_event_t event, | |
| thread->event_set = set; | ||
| thread->event_info = option; | ||
|
|
||
| /* mark wait pending errno */ | ||
| thread->error = -RT_EWAITPEND; | ||
|
|
||
| /* put thread to suspended thread list */ | ||
| ret = rt_thread_suspend_to_list(thread, &(event->parent.suspend_thread), | ||
| event->parent.parent.flag, suspend_flag); | ||
|
|
@@ -2201,10 +2233,12 @@ static rt_err_t _rt_event_recv(rt_event_t event, | |
| /* do a schedule */ | ||
| rt_schedule(); | ||
|
|
||
| if (thread->error != RT_EOK) | ||
| /* normalize wait result after reschedule */ | ||
| ret = _ipc_wait_result(thread); | ||
| if (ret != RT_EOK) | ||
| { | ||
| /* return error */ | ||
| return thread->error; | ||
| return ret; | ||
| } | ||
|
|
||
| /* received an event, disable interrupt to protect */ | ||
|
|
@@ -2600,9 +2634,6 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, | |
| /* mailbox is full */ | ||
| while (mb->entry == mb->size) | ||
| { | ||
| /* reset error number in thread */ | ||
| thread->error = -RT_EINTR; | ||
|
|
||
| /* no waiting, return timeout */ | ||
| if (timeout == 0) | ||
| { | ||
|
|
@@ -2611,6 +2642,9 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, | |
| return -RT_EFULL; | ||
| } | ||
|
|
||
| /* mark wait pending errno */ | ||
| thread->error = -RT_EWAITPEND; | ||
|
|
||
| /* suspend current thread */ | ||
| ret = rt_thread_suspend_to_list(thread, &(mb->suspend_sender_thread), | ||
| mb->parent.parent.flag, suspend_flag); | ||
|
|
@@ -2642,11 +2676,12 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, | |
| /* re-schedule */ | ||
| rt_schedule(); | ||
|
|
||
| /* resume from suspend state */ | ||
| if (thread->error != RT_EOK) | ||
| /* normalize wait result after reschedule */ | ||
| ret = _ipc_wait_result(thread); | ||
| if (ret != RT_EOK) | ||
| { | ||
| /* return error */ | ||
| return thread->error; | ||
| return ret; | ||
| } | ||
|
|
||
| level = rt_spin_lock_irqsave(&(mb->spinlock)); | ||
|
|
@@ -2880,9 +2915,6 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo | |
| /* mailbox is empty */ | ||
| while (mb->entry == 0) | ||
| { | ||
| /* reset error number in thread */ | ||
| thread->error = -RT_EINTR; | ||
|
|
||
| /* no waiting, return timeout */ | ||
| if (timeout == 0) | ||
| { | ||
|
|
@@ -2893,6 +2925,9 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo | |
| return -RT_ETIMEOUT; | ||
| } | ||
|
|
||
| /* mark wait pending errno */ | ||
| thread->error = -RT_EWAITPEND; | ||
|
|
||
| /* suspend current thread */ | ||
| ret = rt_thread_suspend_to_list(thread, &(mb->parent.suspend_thread), | ||
| mb->parent.parent.flag, suspend_flag); | ||
|
|
@@ -2924,11 +2959,12 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo | |
| /* re-schedule */ | ||
| rt_schedule(); | ||
|
|
||
| /* resume from suspend state */ | ||
| if (thread->error != RT_EOK) | ||
| /* normalize wait result after reschedule */ | ||
| ret = _ipc_wait_result(thread); | ||
| if (ret != RT_EOK) | ||
| { | ||
| /* return error */ | ||
| return thread->error; | ||
| return ret; | ||
| } | ||
| level = rt_spin_lock_irqsave(&(mb->spinlock)); | ||
|
|
||
|
|
@@ -3428,9 +3464,6 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, | |
| /* message queue is full */ | ||
| while ((msg = (struct rt_mq_message *)mq->msg_queue_free) == RT_NULL) | ||
| { | ||
| /* reset error number in thread */ | ||
| thread->error = -RT_EINTR; | ||
|
|
||
| /* no waiting, return timeout */ | ||
| if (timeout == 0) | ||
| { | ||
|
|
@@ -3439,6 +3472,9 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, | |
| return -RT_EFULL; | ||
| } | ||
|
|
||
| /* mark wait pending errno */ | ||
| thread->error = -RT_EWAITPEND; | ||
|
|
||
| /* suspend current thread */ | ||
| ret = rt_thread_suspend_to_list(thread, &(mq->suspend_sender_thread), | ||
| mq->parent.parent.flag, suspend_flag); | ||
|
|
@@ -3470,11 +3506,12 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, | |
| /* re-schedule */ | ||
| rt_schedule(); | ||
|
|
||
| /* resume from suspend state */ | ||
| if (thread->error != RT_EOK) | ||
| /* normalize wait result after reschedule */ | ||
| ret = _ipc_wait_result(thread); | ||
| if (ret != RT_EOK) | ||
| { | ||
| /* return error */ | ||
| return thread->error; | ||
| return ret; | ||
| } | ||
| level = rt_spin_lock_irqsave(&(mq->spinlock)); | ||
|
|
||
|
|
@@ -3805,9 +3842,6 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, | |
| /* message queue is empty */ | ||
| while (mq->entry == 0) | ||
| { | ||
| /* reset error number in thread */ | ||
| thread->error = -RT_EINTR; | ||
|
|
||
| /* no waiting, return timeout */ | ||
| if (timeout == 0) | ||
| { | ||
|
|
@@ -3819,6 +3853,9 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, | |
| return -RT_ETIMEOUT; | ||
| } | ||
|
|
||
| /* mark wait pending errno */ | ||
| thread->error = -RT_EWAITPEND; | ||
|
|
||
| /* suspend current thread */ | ||
| ret = rt_thread_suspend_to_list(thread, &(mq->parent.suspend_thread), | ||
| mq->parent.parent.flag, suspend_flag); | ||
|
|
@@ -3850,11 +3887,12 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, | |
| /* re-schedule */ | ||
| rt_schedule(); | ||
|
|
||
| /* recv message */ | ||
| if (thread->error != RT_EOK) | ||
| /* normalize wait result after reschedule */ | ||
| ret = _ipc_wait_result(thread); | ||
| if (ret != RT_EOK) | ||
| { | ||
| /* return error */ | ||
| return thread->error; | ||
| return ret; | ||
| } | ||
|
|
||
| level = rt_spin_lock_irqsave(&(mq->spinlock)); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,6 +55,7 @@ static struct _errno_str_t rt_errno_strs[] = | |
| {RT_ENOENT , "ENOENT "}, /**< No such file or directory. */ | ||
| {RT_ENOSPC , "ENOSPC "}, /**< No space left on device. */ | ||
| {RT_EPERM , "EPERM "}, /**< Operation not permitted. */ | ||
| {RT_EWAITPEND, "OK "}, /**< Wait pending, internal sentinel for scheduler. */ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 那这个PR貌似意义就不大了hh,这个PR就是修复ps的时候显示错误状态的
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 应该是有一个比较好的状态信息显示。 |
||
| {RT_ETRAP , "ETRAP "}, /**< Trap error. */ | ||
| }; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Documentation/文档]: Inconsistent documentation between LIBC and non-LIBC builds / LIBC 和非 LIBC 构建之间的文档不一致
English: The documentation comment for
RT_EWAITPENDis inconsistent between the two definitions. Line 36 says "Wait operation pending (internal sentinel)" while line 63 only says "Wait operation pending". Please add "(internal sentinel)" to line 63's comment for consistency, as this is a crucial detail indicating it's not meant to be exposed to users.中文:
RT_EWAITPEND在两个定义之间的文档注释不一致。第 36 行说"Wait operation pending (internal sentinel)",而第 63 行只说"Wait operation pending"。请在第 63 行的注释中添加"(internal sentinel)"以保持一致性,因为这是一个关键细节,表明它不应向用户公开。Suggested/建议: