summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/thread.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/src/thread.c b/src/thread.c
index 481dfebeef..15e4ee45e8 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -885,26 +885,27 @@ RTM_EXPORT(rt_thread_control);
#include <lwp_signal.h>
#endif
-static void _thread_set_suspend_state(struct rt_thread *thread, int suspend_flag)
+/* Convert suspend_flag to corresponding thread suspend state value */
+static rt_uint8_t _thread_get_suspend_state(int suspend_flag)
{
- rt_uint8_t stat = RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
-
- RT_ASSERT(thread != RT_NULL);
switch (suspend_flag)
{
case RT_INTERRUPTIBLE:
- stat = RT_THREAD_SUSPEND_INTERRUPTIBLE;
- break;
+ return RT_THREAD_SUSPEND_INTERRUPTIBLE;
case RT_KILLABLE:
- stat = RT_THREAD_SUSPEND_KILLABLE;
- break;
+ return RT_THREAD_SUSPEND_KILLABLE;
case RT_UNINTERRUPTIBLE:
- stat = RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
- break;
default:
- RT_ASSERT(0);
- break;
+ return RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
}
+}
+
+static void _thread_set_suspend_state(struct rt_thread *thread, int suspend_flag)
+{
+ rt_uint8_t stat;
+
+ RT_ASSERT(thread != RT_NULL);
+ stat = _thread_get_suspend_state(suspend_flag);
RT_SCHED_CTX(thread).stat = stat | (RT_SCHED_CTX(thread).stat & ~RT_THREAD_STAT_MASK);
}
@@ -943,20 +944,31 @@ rt_err_t rt_thread_suspend_to_list(rt_thread_t thread, rt_list_t *susp_list, int
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
- LOG_D("thread suspend: %s", thread->parent.name);
+ LOG_D("thread suspend: %s", thread->parent.name);
rt_sched_lock(&slvl);
stat = rt_sched_thread_get_stat(thread);
- if (stat == RT_THREAD_SUSPEND)
+ if (stat & RT_THREAD_SUSPEND_MASK)
{
+ if (RT_SCHED_CTX(thread).sched_flag_ttmr_set == 1)
+ {
+ /* The new suspend operation will halt the tick timer. */
+ LOG_D("Thread [%s]'s timer has been halted.\n", thread->parent.name);
+ rt_sched_thread_timer_stop(thread);
+ }
+ /* Upgrade suspend state if new state is stricter */
+ if (stat < _thread_get_suspend_state(suspend_flag))
+ {
+ _thread_set_suspend_state(thread, suspend_flag);
+ }
rt_sched_unlock(slvl);
- /* Already suspended, just set status to success. */
+ /* Already suspended, just set the status to success. */
return RT_EOK;
}
else if ((stat != RT_THREAD_READY) && (stat != RT_THREAD_RUNNING))
{
- LOG_D("thread suspend: thread disorder, 0x%2x", RT_SCHED_CTX(thread).stat);
+ LOG_W("thread suspend: thread disorder, 0x%02x", RT_SCHED_CTX(thread).stat);
rt_sched_unlock(slvl);
return -RT_ERROR;
}