Skip to content

Commit 32aeba5

Browse files
committed
[kernel]fix thread error code to avoid spurious error display in list_thread.
1 parent 0a02fd4 commit 32aeba5

File tree

4 files changed

+82
-38
lines changed

4 files changed

+82
-38
lines changed

include/klibc/kerrno.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern "C" {
3333
#define RT_EINVAL EINVAL /**< Invalid argument */
3434
#define RT_ENOENT ENOENT /**< No entry */
3535
#define RT_ENOSPC ENOSPC /**< No space left */
36+
#define RT_EWAITPEND EINPROGRESS /**< Wait operation pending */
3637
#define RT_EPERM EPERM /**< Operation not permitted */
3738
#define RT_EFAULT EFAULT /**< Bad address */
3839
#define RT_ENOBUFS ENOBUFS /**< No buffer space is available */
@@ -59,6 +60,7 @@ extern "C" {
5960
#define RT_ENOBUFS 16 /**< No buffer space is available */
6061
#define RT_ESCHEDISR 17 /**< scheduler failure in isr context */
6162
#define RT_ESCHEDLOCKED 18 /**< scheduler failure in critical region */
63+
#define RT_EWAITPEND 19 /**< Wait operation pending */
6264
#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */
6365

6466
rt_err_t rt_get_errno(void);

src/ipc.c

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
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));

src/klibc/kerrno.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static struct _errno_str_t rt_errno_strs[] =
5555
{RT_ENOENT , "ENOENT "}, /**< No such file or directory. */
5656
{RT_ENOSPC , "ENOSPC "}, /**< No space left on device. */
5757
{RT_EPERM , "EPERM "}, /**< Operation not permitted. */
58+
{RT_EWAITPEND, "OK "}, /**< Wait pending, internal sentinel for scheduler. */
5859
{RT_ETRAP , "ETRAP "}, /**< Trap error. */
5960
};
6061

src/thread.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,8 @@ static rt_err_t _thread_sleep(rt_tick_t tick)
673673
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
674674
rt_timer_start(&(thread->thread_timer));
675675

676-
thread->error = -RT_EINTR;
676+
/* mark wait pending errno */
677+
thread->error = -RT_EWAITPEND;
677678

678679
/* notify a pending rescheduling */
679680
rt_schedule();

0 commit comments

Comments
 (0)