Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/klibc/kerrno.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern "C" {
#define RT_EINVAL EINVAL /**< Invalid argument */
#define RT_ENOENT ENOENT /**< No entry */
#define RT_ENOSPC ENOSPC /**< No space left */
#define RT_EWAITPEND EINPROGRESS /**< Wait operation pending */
#define RT_EPERM EPERM /**< Operation not permitted */
#define RT_EFAULT EFAULT /**< Bad address */
#define RT_ENOBUFS ENOBUFS /**< No buffer space is available */
Expand All @@ -59,6 +60,7 @@ extern "C" {
#define RT_ENOBUFS 16 /**< No buffer space is available */
#define RT_ESCHEDISR 17 /**< scheduler failure in isr context */
#define RT_ESCHEDLOCKED 18 /**< scheduler failure in critical region */
#define RT_EWAITPEND 19 /**< Wait operation pending */
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Documentation/文档]: Inconsistent documentation between LIBC and non-LIBC builds / LIBC 和非 LIBC 构建之间的文档不一致

English: The documentation comment for RT_EWAITPEND is inconsistent between the two definitions. Line 36 says "Wait operation pending (internal sentinel)" while line 63 only says "Wait operation pending". Please add "(internal sentinel)" to line 63's comment for consistency, as this is a crucial detail indicating it's not meant to be exposed to users.

中文:RT_EWAITPEND 在两个定义之间的文档注释不一致。第 36 行说"Wait operation pending (internal sentinel)",而第 63 行只说"Wait operation pending"。请在第 63 行的注释中添加"(internal sentinel)"以保持一致性,因为这是一个关键细节,表明它不应向用户公开。

Suggested/建议:

#define RT_EWAITPEND                    19              /**< Wait operation pending (internal sentinel) */
Suggested change
#define RT_EWAITPEND 19 /**< Wait operation pending */
#define RT_EWAITPEND 19 /**< Wait operation pending (internal sentinel) */

Copilot uses AI. Check for mistakes.
#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */

rt_err_t rt_get_errno(void);
Expand Down
112 changes: 75 additions & 37 deletions src/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
* 2022-10-16 Bernard add prioceiling feature in mutex
* 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
* 2025-11-23 Rbb666 fix thread error code to avoid spurious error display in list_thread
*/

#include <rtthread.h>
Expand Down Expand Up @@ -87,6 +88,28 @@ rt_inline rt_err_t _ipc_object_init(struct rt_ipc_object *ipc)
return RT_EOK;
}

/**
* @brief This function normalizes the thread error code after IPC wait operation.
*
* @note This function translates the internal RT_EWAITPEND sentinel value back to RT_EINTR
* for the caller. If the error code is still RT_EWAITPEND after scheduling, it means
* the thread was woken by a signal rather than by successfully acquiring the resource
* or timing out.
*
* @param thread is a pointer to the thread object whose error code needs to be checked.
*
* @return Return the thread's error code. When the return value is RT_EOK, the IPC operation succeeded.
* When the return value is RT_EINTR, the operation was interrupted (interrupted system call).
* When the return value is RT_ETIMEOUT, the operation timed out.
*/
static rt_err_t _ipc_wait_result(rt_thread_t thread)
{
if (thread->error == -RT_EWAITPEND)
{
thread->error = -RT_EINTR;
}
return thread->error;
}

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

/* reset thread error number */
thread->error = RT_EINTR;
/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

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

Expand Down Expand Up @@ -630,9 +653,11 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
/* do schedule */
rt_schedule();

if (thread->error != RT_EOK)
/* normalize wait result after reschedule */
ret = _ipc_wait_result(thread);
if (ret != RT_EOK)
{
return thread->error > 0 ? -thread->error : thread->error;
return ret > 0 ? -ret : ret;
}
}
}
Expand Down Expand Up @@ -1403,6 +1428,9 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
LOG_D("mutex_take: suspend thread: %s",
thread->parent.name);

/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

/* suspend current thread */
ret = rt_thread_suspend_to_list(thread, &(mutex->parent.suspend_thread),
mutex->parent.parent.flag, suspend_flag);
Expand Down Expand Up @@ -1452,13 +1480,16 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend

rt_spin_lock(&(mutex->spinlock));

/* normalize wait result after reschedule */
ret = _ipc_wait_result(thread);

if (mutex->owner == thread)
{
/**
* get mutex successfully
* Note: assert to avoid an unexpected resume
* Note: clear any temporary error from interruptible wait
*/
RT_ASSERT(thread->error == RT_EOK);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里应该保留原来的逻辑

thread->error = RT_EOK;
}
else
{
Expand All @@ -1467,9 +1498,6 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
rt_bool_t need_update = RT_FALSE;
RT_ASSERT(mutex->owner != thread);

/* get value first before calling to other APIs */
ret = thread->error;

/* unexpected resume */
if (ret == RT_EOK)
{
Expand Down Expand Up @@ -1673,6 +1701,9 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
/* cleanup pending object */
next_thread->pending_object = RT_NULL;

/* clear any temporary error from interruptible wait */
next_thread->error = RT_EOK;

/* update mutex priority */
if (!rt_list_isempty(&(mutex->parent.suspend_thread)))
{
Expand Down Expand Up @@ -2121,8 +2152,6 @@ static rt_err_t _rt_event_recv(rt_event_t event,
status = -RT_ERROR;
/* get current thread */
thread = rt_thread_self();
/* reset thread error */
thread->error = -RT_EINTR;

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

Expand Down Expand Up @@ -2176,6 +2205,9 @@ static rt_err_t _rt_event_recv(rt_event_t event,
thread->event_set = set;
thread->event_info = option;

/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

/* put thread to suspended thread list */
ret = rt_thread_suspend_to_list(thread, &(event->parent.suspend_thread),
event->parent.parent.flag, suspend_flag);
Expand All @@ -2201,10 +2233,12 @@ static rt_err_t _rt_event_recv(rt_event_t event,
/* do a schedule */
rt_schedule();

if (thread->error != RT_EOK)
/* normalize wait result after reschedule */
ret = _ipc_wait_result(thread);
if (ret != RT_EOK)
{
/* return error */
return thread->error;
return ret;
}

/* received an event, disable interrupt to protect */
Expand Down Expand Up @@ -2600,9 +2634,6 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
/* mailbox is full */
while (mb->entry == mb->size)
{
/* reset error number in thread */
thread->error = -RT_EINTR;

/* no waiting, return timeout */
if (timeout == 0)
{
Expand All @@ -2611,6 +2642,9 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
return -RT_EFULL;
}

/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

/* suspend current thread */
ret = rt_thread_suspend_to_list(thread, &(mb->suspend_sender_thread),
mb->parent.parent.flag, suspend_flag);
Expand Down Expand Up @@ -2642,11 +2676,12 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
/* re-schedule */
rt_schedule();

/* resume from suspend state */
if (thread->error != RT_EOK)
/* normalize wait result after reschedule */
ret = _ipc_wait_result(thread);
if (ret != RT_EOK)
{
/* return error */
return thread->error;
return ret;
}

level = rt_spin_lock_irqsave(&(mb->spinlock));
Expand Down Expand Up @@ -2880,9 +2915,6 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
/* mailbox is empty */
while (mb->entry == 0)
{
/* reset error number in thread */
thread->error = -RT_EINTR;

/* no waiting, return timeout */
if (timeout == 0)
{
Expand All @@ -2893,6 +2925,9 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
return -RT_ETIMEOUT;
}

/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

/* suspend current thread */
ret = rt_thread_suspend_to_list(thread, &(mb->parent.suspend_thread),
mb->parent.parent.flag, suspend_flag);
Expand Down Expand Up @@ -2924,11 +2959,12 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
/* re-schedule */
rt_schedule();

/* resume from suspend state */
if (thread->error != RT_EOK)
/* normalize wait result after reschedule */
ret = _ipc_wait_result(thread);
if (ret != RT_EOK)
{
/* return error */
return thread->error;
return ret;
}
level = rt_spin_lock_irqsave(&(mb->spinlock));

Expand Down Expand Up @@ -3428,9 +3464,6 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
/* message queue is full */
while ((msg = (struct rt_mq_message *)mq->msg_queue_free) == RT_NULL)
{
/* reset error number in thread */
thread->error = -RT_EINTR;

/* no waiting, return timeout */
if (timeout == 0)
{
Expand All @@ -3439,6 +3472,9 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
return -RT_EFULL;
}

/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

/* suspend current thread */
ret = rt_thread_suspend_to_list(thread, &(mq->suspend_sender_thread),
mq->parent.parent.flag, suspend_flag);
Expand Down Expand Up @@ -3470,11 +3506,12 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
/* re-schedule */
rt_schedule();

/* resume from suspend state */
if (thread->error != RT_EOK)
/* normalize wait result after reschedule */
ret = _ipc_wait_result(thread);
if (ret != RT_EOK)
{
/* return error */
return thread->error;
return ret;
}
level = rt_spin_lock_irqsave(&(mq->spinlock));

Expand Down Expand Up @@ -3805,9 +3842,6 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
/* message queue is empty */
while (mq->entry == 0)
{
/* reset error number in thread */
thread->error = -RT_EINTR;

/* no waiting, return timeout */
if (timeout == 0)
{
Expand All @@ -3819,6 +3853,9 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
return -RT_ETIMEOUT;
}

/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

/* suspend current thread */
ret = rt_thread_suspend_to_list(thread, &(mq->parent.suspend_thread),
mq->parent.parent.flag, suspend_flag);
Expand Down Expand Up @@ -3850,11 +3887,12 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
/* re-schedule */
rt_schedule();

/* recv message */
if (thread->error != RT_EOK)
/* normalize wait result after reschedule */
ret = _ipc_wait_result(thread);
if (ret != RT_EOK)
{
/* return error */
return thread->error;
return ret;
}

level = rt_spin_lock_irqsave(&(mq->spinlock));
Expand Down
1 change: 1 addition & 0 deletions src/klibc/kerrno.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static struct _errno_str_t rt_errno_strs[] =
{RT_ENOENT , "ENOENT "}, /**< No such file or directory. */
{RT_ENOSPC , "ENOSPC "}, /**< No space left on device. */
{RT_EPERM , "EPERM "}, /**< Operation not permitted. */
{RT_EWAITPEND, "OK "}, /**< Wait pending, internal sentinel for scheduler. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 这个显示成"ok"是不是不大好,显示成"WAITPEND".这样准确的?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

那这个PR貌似意义就不大了hh,这个PR就是修复ps的时候显示错误状态的

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

应该是有一个比较好的状态信息显示。

{RT_ETRAP , "ETRAP "}, /**< Trap error. */
};

Expand Down
3 changes: 2 additions & 1 deletion src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,8 @@ static rt_err_t _thread_sleep(rt_tick_t tick)
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
rt_timer_start(&(thread->thread_timer));

thread->error = -RT_EINTR;
/* mark wait pending errno */
thread->error = -RT_EWAITPEND;

/* notify a pending rescheduling */
rt_schedule();
Expand Down