4646 * 2022-10-16 Bernard add prioceiling feature in mutex
4747 * 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size
4848 * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
49+ * 2025-11-23 Rbb666 fix thread error code to avoid spurious error display in list_thread
4950 */
5051
5152#include <rtthread.h>
@@ -87,6 +88,28 @@ rt_inline rt_err_t _ipc_object_init(struct rt_ipc_object *ipc)
8788 return RT_EOK ;
8889}
8990
91+ /**
92+ * @brief This function normalizes the thread error code after IPC wait operation.
93+ *
94+ * @note This function translates the internal RT_EWAITPEND sentinel value back to RT_EINTR
95+ * for the caller. If the error code is still RT_EWAITPEND after scheduling, it means
96+ * the thread was woken by a signal rather than by successfully acquiring the resource
97+ * or timing out.
98+ *
99+ * @param thread is a pointer to the thread object whose error code needs to be checked.
100+ *
101+ * @return Return the thread's error code. When the return value is RT_EOK, the IPC operation succeeded.
102+ * When the return value is RT_EINTR, the operation was interrupted (interrupted system call).
103+ * When the return value is RT_ETIMEOUT, the operation timed out.
104+ */
105+ static rt_err_t _ipc_wait_result (rt_thread_t thread )
106+ {
107+ if (thread -> error == - RT_EWAITPEND )
108+ {
109+ thread -> error = - RT_EINTR ;
110+ }
111+ return thread -> error ;
112+ }
90113
91114/**
92115 * @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)
597620 /* get current thread */
598621 thread = rt_thread_self ();
599622
600- /* reset thread error number */
601- thread -> error = RT_EINTR ;
623+ /* mark wait pending errno */
624+ thread -> error = - RT_EWAITPEND ;
602625
603626 LOG_D ("sem take: suspend thread - %s" , thread -> parent .name );
604627
@@ -630,9 +653,11 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
630653 /* do schedule */
631654 rt_schedule ();
632655
633- if (thread -> error != RT_EOK )
656+ /* normalize wait result after reschedule */
657+ ret = _ipc_wait_result (thread );
658+ if (ret != RT_EOK )
634659 {
635- return thread -> error > 0 ? - thread -> error : thread -> error ;
660+ return ret > 0 ? - ret : ret ;
636661 }
637662 }
638663 }
@@ -1403,6 +1428,9 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14031428 LOG_D ("mutex_take: suspend thread: %s" ,
14041429 thread -> parent .name );
14051430
1431+ /* mark wait pending errno */
1432+ thread -> error = - RT_EWAITPEND ;
1433+
14061434 /* suspend current thread */
14071435 ret = rt_thread_suspend_to_list (thread , & (mutex -> parent .suspend_thread ),
14081436 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
14521480
14531481 rt_spin_lock (& (mutex -> spinlock ));
14541482
1483+ /* normalize wait result after reschedule */
1484+ ret = _ipc_wait_result (thread );
1485+
14551486 if (mutex -> owner == thread )
14561487 {
14571488 /**
14581489 * get mutex successfully
1459- * Note: assert to avoid an unexpected resume
1490+ * Note: clear any temporary error from interruptible wait
14601491 */
1461- RT_ASSERT ( thread -> error == RT_EOK ) ;
1492+ thread -> error = RT_EOK ;
14621493 }
14631494 else
14641495 {
@@ -1467,9 +1498,6 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14671498 rt_bool_t need_update = RT_FALSE ;
14681499 RT_ASSERT (mutex -> owner != thread );
14691500
1470- /* get value first before calling to other APIs */
1471- ret = thread -> error ;
1472-
14731501 /* unexpected resume */
14741502 if (ret == RT_EOK )
14751503 {
@@ -1673,6 +1701,9 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
16731701 /* cleanup pending object */
16741702 next_thread -> pending_object = RT_NULL ;
16751703
1704+ /* clear any temporary error from interruptible wait */
1705+ next_thread -> error = RT_EOK ;
1706+
16761707 /* update mutex priority */
16771708 if (!rt_list_isempty (& (mutex -> parent .suspend_thread )))
16781709 {
@@ -2121,8 +2152,6 @@ static rt_err_t _rt_event_recv(rt_event_t event,
21212152 status = - RT_ERROR ;
21222153 /* get current thread */
21232154 thread = rt_thread_self ();
2124- /* reset thread error */
2125- thread -> error = - RT_EINTR ;
21262155
21272156 RT_OBJECT_HOOK_CALL (rt_object_trytake_hook , (& (event -> parent .parent )));
21282157
@@ -2176,6 +2205,9 @@ static rt_err_t _rt_event_recv(rt_event_t event,
21762205 thread -> event_set = set ;
21772206 thread -> event_info = option ;
21782207
2208+ /* mark wait pending errno */
2209+ thread -> error = - RT_EWAITPEND ;
2210+
21792211 /* put thread to suspended thread list */
21802212 ret = rt_thread_suspend_to_list (thread , & (event -> parent .suspend_thread ),
21812213 event -> parent .parent .flag , suspend_flag );
@@ -2201,10 +2233,12 @@ static rt_err_t _rt_event_recv(rt_event_t event,
22012233 /* do a schedule */
22022234 rt_schedule ();
22032235
2204- if (thread -> error != RT_EOK )
2236+ /* normalize wait result after reschedule */
2237+ ret = _ipc_wait_result (thread );
2238+ if (ret != RT_EOK )
22052239 {
22062240 /* return error */
2207- return thread -> error ;
2241+ return ret ;
22082242 }
22092243
22102244 /* received an event, disable interrupt to protect */
@@ -2600,9 +2634,6 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26002634 /* mailbox is full */
26012635 while (mb -> entry == mb -> size )
26022636 {
2603- /* reset error number in thread */
2604- thread -> error = - RT_EINTR ;
2605-
26062637 /* no waiting, return timeout */
26072638 if (timeout == 0 )
26082639 {
@@ -2611,6 +2642,9 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26112642 return - RT_EFULL ;
26122643 }
26132644
2645+ /* mark wait pending errno */
2646+ thread -> error = - RT_EWAITPEND ;
2647+
26142648 /* suspend current thread */
26152649 ret = rt_thread_suspend_to_list (thread , & (mb -> suspend_sender_thread ),
26162650 mb -> parent .parent .flag , suspend_flag );
@@ -2642,11 +2676,12 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26422676 /* re-schedule */
26432677 rt_schedule ();
26442678
2645- /* resume from suspend state */
2646- if (thread -> error != RT_EOK )
2679+ /* normalize wait result after reschedule */
2680+ ret = _ipc_wait_result (thread );
2681+ if (ret != RT_EOK )
26472682 {
26482683 /* return error */
2649- return thread -> error ;
2684+ return ret ;
26502685 }
26512686
26522687 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
28802915 /* mailbox is empty */
28812916 while (mb -> entry == 0 )
28822917 {
2883- /* reset error number in thread */
2884- thread -> error = - RT_EINTR ;
2885-
28862918 /* no waiting, return timeout */
28872919 if (timeout == 0 )
28882920 {
@@ -2893,6 +2925,9 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
28932925 return - RT_ETIMEOUT ;
28942926 }
28952927
2928+ /* mark wait pending errno */
2929+ thread -> error = - RT_EWAITPEND ;
2930+
28962931 /* suspend current thread */
28972932 ret = rt_thread_suspend_to_list (thread , & (mb -> parent .suspend_thread ),
28982933 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
29242959 /* re-schedule */
29252960 rt_schedule ();
29262961
2927- /* resume from suspend state */
2928- if (thread -> error != RT_EOK )
2962+ /* normalize wait result after reschedule */
2963+ ret = _ipc_wait_result (thread );
2964+ if (ret != RT_EOK )
29292965 {
29302966 /* return error */
2931- return thread -> error ;
2967+ return ret ;
29322968 }
29332969 level = rt_spin_lock_irqsave (& (mb -> spinlock ));
29342970
@@ -3428,9 +3464,6 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34283464 /* message queue is full */
34293465 while ((msg = (struct rt_mq_message * )mq -> msg_queue_free ) == RT_NULL )
34303466 {
3431- /* reset error number in thread */
3432- thread -> error = - RT_EINTR ;
3433-
34343467 /* no waiting, return timeout */
34353468 if (timeout == 0 )
34363469 {
@@ -3439,6 +3472,9 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34393472 return - RT_EFULL ;
34403473 }
34413474
3475+ /* mark wait pending errno */
3476+ thread -> error = - RT_EWAITPEND ;
3477+
34423478 /* suspend current thread */
34433479 ret = rt_thread_suspend_to_list (thread , & (mq -> suspend_sender_thread ),
34443480 mq -> parent .parent .flag , suspend_flag );
@@ -3470,11 +3506,12 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34703506 /* re-schedule */
34713507 rt_schedule ();
34723508
3473- /* resume from suspend state */
3474- if (thread -> error != RT_EOK )
3509+ /* normalize wait result after reschedule */
3510+ ret = _ipc_wait_result (thread );
3511+ if (ret != RT_EOK )
34753512 {
34763513 /* return error */
3477- return thread -> error ;
3514+ return ret ;
34783515 }
34793516 level = rt_spin_lock_irqsave (& (mq -> spinlock ));
34803517
@@ -3805,9 +3842,6 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38053842 /* message queue is empty */
38063843 while (mq -> entry == 0 )
38073844 {
3808- /* reset error number in thread */
3809- thread -> error = - RT_EINTR ;
3810-
38113845 /* no waiting, return timeout */
38123846 if (timeout == 0 )
38133847 {
@@ -3819,6 +3853,9 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38193853 return - RT_ETIMEOUT ;
38203854 }
38213855
3856+ /* mark wait pending errno */
3857+ thread -> error = - RT_EWAITPEND ;
3858+
38223859 /* suspend current thread */
38233860 ret = rt_thread_suspend_to_list (thread , & (mq -> parent .suspend_thread ),
38243861 mq -> parent .parent .flag , suspend_flag );
@@ -3850,11 +3887,12 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38503887 /* re-schedule */
38513888 rt_schedule ();
38523889
3853- /* recv message */
3854- if (thread -> error != RT_EOK )
3890+ /* normalize wait result after reschedule */
3891+ ret = _ipc_wait_result (thread );
3892+ if (ret != RT_EOK )
38553893 {
38563894 /* return error */
3857- return thread -> error ;
3895+ return ret ;
38583896 }
38593897
38603898 level = rt_spin_lock_irqsave (& (mq -> spinlock ));
0 commit comments