Skip to content

Commit 76325bf

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

File tree

4 files changed

+80
-38
lines changed

4 files changed

+80
-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: 75 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 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));

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)