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 ps
4950 */
5051
5152#include <rtthread.h>
@@ -87,6 +88,30 @@ 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 interrupted by an interrupted system call rather than successfully
97+ * acquiring the resource 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+ * @see _ipc_mark_thread_waiting()
106+ */
107+ static rt_err_t _ipc_wait_result (rt_thread_t thread )
108+ {
109+ if (thread -> error == - RT_EWAITPEND )
110+ {
111+ thread -> error = - RT_EINTR ;
112+ }
113+ return thread -> error ;
114+ }
90115
91116/**
92117 * @brief Dequeue a thread from suspended list and set it to ready. The 2 are
@@ -597,8 +622,8 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
597622 /* get current thread */
598623 thread = rt_thread_self ();
599624
600- /* reset thread error number */
601- thread -> error = RT_EINTR ;
625+ /* mark wait pending errno */
626+ thread -> error = - RT_EWAITPEND ;
602627
603628 LOG_D ("sem take: suspend thread - %s" , thread -> parent .name );
604629
@@ -630,9 +655,11 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
630655 /* do schedule */
631656 rt_schedule ();
632657
633- if (thread -> error != RT_EOK )
658+ /* normalize wait result after reschedule */
659+ ret = _ipc_wait_result (thread );
660+ if (ret != RT_EOK )
634661 {
635- return thread -> error > 0 ? - thread -> error : thread -> error ;
662+ return ret > 0 ? - ret : ret ;
636663 }
637664 }
638665 }
@@ -1403,6 +1430,9 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14031430 LOG_D ("mutex_take: suspend thread: %s" ,
14041431 thread -> parent .name );
14051432
1433+ /* mark wait pending errno */
1434+ thread -> error = - RT_EWAITPEND ;
1435+
14061436 /* suspend current thread */
14071437 ret = rt_thread_suspend_to_list (thread , & (mutex -> parent .suspend_thread ),
14081438 mutex -> parent .parent .flag , suspend_flag );
@@ -1452,13 +1482,16 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14521482
14531483 rt_spin_lock (& (mutex -> spinlock ));
14541484
1485+ /* normalize wait result after reschedule */
1486+ ret = _ipc_wait_result (thread );
1487+
14551488 if (mutex -> owner == thread )
14561489 {
14571490 /**
14581491 * get mutex successfully
1459- * Note: assert to avoid an unexpected resume
1492+ * Note: clear any temporary error from interruptible wait
14601493 */
1461- RT_ASSERT ( thread -> error == RT_EOK ) ;
1494+ thread -> error = RT_EOK ;
14621495 }
14631496 else
14641497 {
@@ -1467,9 +1500,6 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14671500 rt_bool_t need_update = RT_FALSE ;
14681501 RT_ASSERT (mutex -> owner != thread );
14691502
1470- /* get value first before calling to other APIs */
1471- ret = thread -> error ;
1472-
14731503 /* unexpected resume */
14741504 if (ret == RT_EOK )
14751505 {
@@ -1673,6 +1703,9 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
16731703 /* cleanup pending object */
16741704 next_thread -> pending_object = RT_NULL ;
16751705
1706+ /* clear any temporary error from interruptible wait */
1707+ next_thread -> error = RT_EOK ;
1708+
16761709 /* update mutex priority */
16771710 if (!rt_list_isempty (& (mutex -> parent .suspend_thread )))
16781711 {
@@ -2121,8 +2154,6 @@ static rt_err_t _rt_event_recv(rt_event_t event,
21212154 status = - RT_ERROR ;
21222155 /* get current thread */
21232156 thread = rt_thread_self ();
2124- /* reset thread error */
2125- thread -> error = - RT_EINTR ;
21262157
21272158 RT_OBJECT_HOOK_CALL (rt_object_trytake_hook , (& (event -> parent .parent )));
21282159
@@ -2176,6 +2207,9 @@ static rt_err_t _rt_event_recv(rt_event_t event,
21762207 thread -> event_set = set ;
21772208 thread -> event_info = option ;
21782209
2210+ /* mark wait pending errno */
2211+ thread -> error = - RT_EWAITPEND ;
2212+
21792213 /* put thread to suspended thread list */
21802214 ret = rt_thread_suspend_to_list (thread , & (event -> parent .suspend_thread ),
21812215 event -> parent .parent .flag , suspend_flag );
@@ -2201,10 +2235,12 @@ static rt_err_t _rt_event_recv(rt_event_t event,
22012235 /* do a schedule */
22022236 rt_schedule ();
22032237
2204- if (thread -> error != RT_EOK )
2238+ /* normalize wait result after reschedule */
2239+ ret = _ipc_wait_result (thread );
2240+ if (ret != RT_EOK )
22052241 {
22062242 /* return error */
2207- return thread -> error ;
2243+ return ret ;
22082244 }
22092245
22102246 /* received an event, disable interrupt to protect */
@@ -2600,9 +2636,6 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26002636 /* mailbox is full */
26012637 while (mb -> entry == mb -> size )
26022638 {
2603- /* reset error number in thread */
2604- thread -> error = - RT_EINTR ;
2605-
26062639 /* no waiting, return timeout */
26072640 if (timeout == 0 )
26082641 {
@@ -2611,6 +2644,9 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26112644 return - RT_EFULL ;
26122645 }
26132646
2647+ /* mark wait pending errno */
2648+ thread -> error = - RT_EWAITPEND ;
2649+
26142650 /* suspend current thread */
26152651 ret = rt_thread_suspend_to_list (thread , & (mb -> suspend_sender_thread ),
26162652 mb -> parent .parent .flag , suspend_flag );
@@ -2642,11 +2678,12 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26422678 /* re-schedule */
26432679 rt_schedule ();
26442680
2645- /* resume from suspend state */
2646- if (thread -> error != RT_EOK )
2681+ /* normalize wait result after reschedule */
2682+ ret = _ipc_wait_result (thread );
2683+ if (ret != RT_EOK )
26472684 {
26482685 /* return error */
2649- return thread -> error ;
2686+ return ret ;
26502687 }
26512688
26522689 level = rt_spin_lock_irqsave (& (mb -> spinlock ));
@@ -2880,9 +2917,6 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
28802917 /* mailbox is empty */
28812918 while (mb -> entry == 0 )
28822919 {
2883- /* reset error number in thread */
2884- thread -> error = - RT_EINTR ;
2885-
28862920 /* no waiting, return timeout */
28872921 if (timeout == 0 )
28882922 {
@@ -2893,6 +2927,9 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
28932927 return - RT_ETIMEOUT ;
28942928 }
28952929
2930+ /* mark wait pending errno */
2931+ thread -> error = - RT_EWAITPEND ;
2932+
28962933 /* suspend current thread */
28972934 ret = rt_thread_suspend_to_list (thread , & (mb -> parent .suspend_thread ),
28982935 mb -> parent .parent .flag , suspend_flag );
@@ -2924,11 +2961,12 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
29242961 /* re-schedule */
29252962 rt_schedule ();
29262963
2927- /* resume from suspend state */
2928- if (thread -> error != RT_EOK )
2964+ /* normalize wait result after reschedule */
2965+ ret = _ipc_wait_result (thread );
2966+ if (ret != RT_EOK )
29292967 {
29302968 /* return error */
2931- return thread -> error ;
2969+ return ret ;
29322970 }
29332971 level = rt_spin_lock_irqsave (& (mb -> spinlock ));
29342972
@@ -3428,9 +3466,6 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34283466 /* message queue is full */
34293467 while ((msg = (struct rt_mq_message * )mq -> msg_queue_free ) == RT_NULL )
34303468 {
3431- /* reset error number in thread */
3432- thread -> error = - RT_EINTR ;
3433-
34343469 /* no waiting, return timeout */
34353470 if (timeout == 0 )
34363471 {
@@ -3439,6 +3474,9 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34393474 return - RT_EFULL ;
34403475 }
34413476
3477+ /* mark wait pending errno */
3478+ thread -> error = - RT_EWAITPEND ;
3479+
34423480 /* suspend current thread */
34433481 ret = rt_thread_suspend_to_list (thread , & (mq -> suspend_sender_thread ),
34443482 mq -> parent .parent .flag , suspend_flag );
@@ -3470,11 +3508,12 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34703508 /* re-schedule */
34713509 rt_schedule ();
34723510
3473- /* resume from suspend state */
3474- if (thread -> error != RT_EOK )
3511+ /* normalize wait result after reschedule */
3512+ ret = _ipc_wait_result (thread );
3513+ if (ret != RT_EOK )
34753514 {
34763515 /* return error */
3477- return thread -> error ;
3516+ return ret ;
34783517 }
34793518 level = rt_spin_lock_irqsave (& (mq -> spinlock ));
34803519
@@ -3805,9 +3844,6 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38053844 /* message queue is empty */
38063845 while (mq -> entry == 0 )
38073846 {
3808- /* reset error number in thread */
3809- thread -> error = - RT_EINTR ;
3810-
38113847 /* no waiting, return timeout */
38123848 if (timeout == 0 )
38133849 {
@@ -3819,6 +3855,9 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38193855 return - RT_ETIMEOUT ;
38203856 }
38213857
3858+ /* mark wait pending errno */
3859+ thread -> error = - RT_EWAITPEND ;
3860+
38223861 /* suspend current thread */
38233862 ret = rt_thread_suspend_to_list (thread , & (mq -> parent .suspend_thread ),
38243863 mq -> parent .parent .flag , suspend_flag );
@@ -3850,11 +3889,12 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38503889 /* re-schedule */
38513890 rt_schedule ();
38523891
3853- /* recv message */
3854- if (thread -> error != RT_EOK )
3892+ /* normalize wait result after reschedule */
3893+ ret = _ipc_wait_result (thread );
3894+ if (ret != RT_EOK )
38553895 {
38563896 /* return error */
3857- return thread -> error ;
3897+ return ret ;
38583898 }
38593899
38603900 level = rt_spin_lock_irqsave (& (mq -> spinlock ));
0 commit comments