Skip to content

Commit 6f5e625

Browse files
committed
[kernel]fix thread error code to avoid spurious error display in ps
1 parent 0a02fd4 commit 6f5e625

File tree

4 files changed

+83
-34
lines changed

4 files changed

+83
-34
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 (internal sentinel) */
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: 78 additions & 33 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,31 @@ 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+
/* translate wait pending sentinel back to EINTR for callers */
112+
thread->error = -RT_EINTR;
113+
}
114+
return thread->error;
115+
}
90116

91117
/**
92118
* @brief Dequeue a thread from suspended list and set it to ready. The 2 are
@@ -597,8 +623,8 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
597623
/* get current thread */
598624
thread = rt_thread_self();
599625

600-
/* reset thread error number */
601-
thread->error = RT_EINTR;
626+
/* mark wait pending errno */
627+
thread->error = -RT_EWAITPEND;
602628

603629
LOG_D("sem take: suspend thread - %s", thread->parent.name);
604630

@@ -630,9 +656,11 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
630656
/* do schedule */
631657
rt_schedule();
632658

633-
if (thread->error != RT_EOK)
659+
/* normalize any sentinel errno before returning to caller */
660+
ret = _ipc_wait_result(thread);
661+
if (ret != RT_EOK)
634662
{
635-
return thread->error > 0 ? -thread->error : thread->error;
663+
return ret > 0 ? -ret : ret;
636664
}
637665
}
638666
}
@@ -1403,6 +1431,9 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14031431
LOG_D("mutex_take: suspend thread: %s",
14041432
thread->parent.name);
14051433

1434+
/* mark wait pending errno */
1435+
thread->error = -RT_EWAITPEND;
1436+
14061437
/* suspend current thread */
14071438
ret = rt_thread_suspend_to_list(thread, &(mutex->parent.suspend_thread),
14081439
mutex->parent.parent.flag, suspend_flag);
@@ -1452,13 +1483,16 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14521483

14531484
rt_spin_lock(&(mutex->spinlock));
14541485

1486+
/* translate sentinel back to EINTR or timeout */
1487+
ret = _ipc_wait_result(thread);
1488+
14551489
if (mutex->owner == thread)
14561490
{
14571491
/**
14581492
* get mutex successfully
1459-
* Note: assert to avoid an unexpected resume
1493+
* Note: clear any temporary error from interruptible wait
14601494
*/
1461-
RT_ASSERT(thread->error == RT_EOK);
1495+
thread->error = RT_EOK;
14621496
}
14631497
else
14641498
{
@@ -1467,9 +1501,6 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
14671501
rt_bool_t need_update = RT_FALSE;
14681502
RT_ASSERT(mutex->owner != thread);
14691503

1470-
/* get value first before calling to other APIs */
1471-
ret = thread->error;
1472-
14731504
/* unexpected resume */
14741505
if (ret == RT_EOK)
14751506
{
@@ -1673,6 +1704,9 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
16731704
/* cleanup pending object */
16741705
next_thread->pending_object = RT_NULL;
16751706

1707+
/* clear any temporary error from interruptible wait */
1708+
next_thread->error = RT_EOK;
1709+
16761710
/* update mutex priority */
16771711
if (!rt_list_isempty(&(mutex->parent.suspend_thread)))
16781712
{
@@ -2121,8 +2155,6 @@ static rt_err_t _rt_event_recv(rt_event_t event,
21212155
status = -RT_ERROR;
21222156
/* get current thread */
21232157
thread = rt_thread_self();
2124-
/* reset thread error */
2125-
thread->error = -RT_EINTR;
21262158

21272159
RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(event->parent.parent)));
21282160

@@ -2176,6 +2208,9 @@ static rt_err_t _rt_event_recv(rt_event_t event,
21762208
thread->event_set = set;
21772209
thread->event_info = option;
21782210

2211+
/* mark wait pending errno */
2212+
thread->error = -RT_EWAITPEND;
2213+
21792214
/* put thread to suspended thread list */
21802215
ret = rt_thread_suspend_to_list(thread, &(event->parent.suspend_thread),
21812216
event->parent.parent.flag, suspend_flag);
@@ -2201,10 +2236,15 @@ static rt_err_t _rt_event_recv(rt_event_t event,
22012236
/* do a schedule */
22022237
rt_schedule();
22032238

2204-
if (thread->error != RT_EOK)
2239+
/* unwrap sentinel: signal -> -RT_EINTR, timeout already set */
2240+
/* convert sentinel back to EINTR/timeout semantics */
2241+
/* translate sentinel back to EINTR or timeout */
2242+
/* normalize sentinel before reporting to caller */
2243+
ret = _ipc_wait_result(thread);
2244+
if (ret != RT_EOK)
22052245
{
22062246
/* return error */
2207-
return thread->error;
2247+
return ret;
22082248
}
22092249

22102250
/* received an event, disable interrupt to protect */
@@ -2600,9 +2640,6 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26002640
/* mailbox is full */
26012641
while (mb->entry == mb->size)
26022642
{
2603-
/* reset error number in thread */
2604-
thread->error = -RT_EINTR;
2605-
26062643
/* no waiting, return timeout */
26072644
if (timeout == 0)
26082645
{
@@ -2611,6 +2648,9 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26112648
return -RT_EFULL;
26122649
}
26132650

2651+
/* mark wait pending errno */
2652+
thread->error = -RT_EWAITPEND;
2653+
26142654
/* suspend current thread */
26152655
ret = rt_thread_suspend_to_list(thread, &(mb->suspend_sender_thread),
26162656
mb->parent.parent.flag, suspend_flag);
@@ -2643,10 +2683,12 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
26432683
rt_schedule();
26442684

26452685
/* resume from suspend state */
2646-
if (thread->error != RT_EOK)
2686+
/* normalize sentinel before continuing with mailbox recv */
2687+
ret = _ipc_wait_result(thread);
2688+
if (ret != RT_EOK)
26472689
{
26482690
/* return error */
2649-
return thread->error;
2691+
return ret;
26502692
}
26512693

26522694
level = rt_spin_lock_irqsave(&(mb->spinlock));
@@ -2880,9 +2922,6 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
28802922
/* mailbox is empty */
28812923
while (mb->entry == 0)
28822924
{
2883-
/* reset error number in thread */
2884-
thread->error = -RT_EINTR;
2885-
28862925
/* no waiting, return timeout */
28872926
if (timeout == 0)
28882927
{
@@ -2893,6 +2932,9 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
28932932
return -RT_ETIMEOUT;
28942933
}
28952934

2935+
/* mark wait pending errno */
2936+
thread->error = -RT_EWAITPEND;
2937+
28962938
/* suspend current thread */
28972939
ret = rt_thread_suspend_to_list(thread, &(mb->parent.suspend_thread),
28982940
mb->parent.parent.flag, suspend_flag);
@@ -2925,10 +2967,11 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
29252967
rt_schedule();
29262968

29272969
/* resume from suspend state */
2928-
if (thread->error != RT_EOK)
2970+
ret = _ipc_wait_result(thread);
2971+
if (ret != RT_EOK)
29292972
{
29302973
/* return error */
2931-
return thread->error;
2974+
return ret;
29322975
}
29332976
level = rt_spin_lock_irqsave(&(mb->spinlock));
29342977

@@ -3428,9 +3471,6 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34283471
/* message queue is full */
34293472
while ((msg = (struct rt_mq_message *)mq->msg_queue_free) == RT_NULL)
34303473
{
3431-
/* reset error number in thread */
3432-
thread->error = -RT_EINTR;
3433-
34343474
/* no waiting, return timeout */
34353475
if (timeout == 0)
34363476
{
@@ -3439,6 +3479,9 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34393479
return -RT_EFULL;
34403480
}
34413481

3482+
/* mark wait pending errno */
3483+
thread->error = -RT_EWAITPEND;
3484+
34423485
/* suspend current thread */
34433486
ret = rt_thread_suspend_to_list(thread, &(mq->suspend_sender_thread),
34443487
mq->parent.parent.flag, suspend_flag);
@@ -3471,10 +3514,11 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
34713514
rt_schedule();
34723515

34733516
/* resume from suspend state */
3474-
if (thread->error != RT_EOK)
3517+
ret = _ipc_wait_result(thread);
3518+
if (ret != RT_EOK)
34753519
{
34763520
/* return error */
3477-
return thread->error;
3521+
return ret;
34783522
}
34793523
level = rt_spin_lock_irqsave(&(mq->spinlock));
34803524

@@ -3805,9 +3849,6 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38053849
/* message queue is empty */
38063850
while (mq->entry == 0)
38073851
{
3808-
/* reset error number in thread */
3809-
thread->error = -RT_EINTR;
3810-
38113852
/* no waiting, return timeout */
38123853
if (timeout == 0)
38133854
{
@@ -3819,6 +3860,9 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38193860
return -RT_ETIMEOUT;
38203861
}
38213862

3863+
/* mark wait pending errno */
3864+
thread->error = -RT_EWAITPEND;
3865+
38223866
/* suspend current thread */
38233867
ret = rt_thread_suspend_to_list(thread, &(mq->parent.suspend_thread),
38243868
mq->parent.parent.flag, suspend_flag);
@@ -3851,10 +3895,11 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
38513895
rt_schedule();
38523896

38533897
/* recv message */
3854-
if (thread->error != RT_EOK)
3898+
ret = _ipc_wait_result(thread);
3899+
if (ret != RT_EOK)
38553900
{
38563901
/* return error */
3857-
return thread->error;
3902+
return ret;
38583903
}
38593904

38603905
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)