summaryrefslogtreecommitdiff
path: root/src/scheduler.c
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2019-01-24 09:30:30 +0800
committerBernard Xiong <[email protected]>2019-01-24 09:30:30 +0800
commit69994ca2109da3f2d655ae079872071762e3625a (patch)
tree500b02e91e1e7c36c3682694bf06376372fed126 /src/scheduler.c
parentbef1d55736d589c45fece3f0660473cc34d15029 (diff)
[Kernel] Fix rt_schedule_insert_thread issue
When suspend current thread and then enable interrupt, it's possible resume "the current thread" immediately and insert to ready queue. The rt_schedule_insert_thread should change the status of "current thread" to RUNNING statue.
Diffstat (limited to 'src/scheduler.c')
-rw-r--r--src/scheduler.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/scheduler.c b/src/scheduler.c
index 0ced21105e..37b262d83b 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -351,7 +351,7 @@ void rt_schedule(void)
RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (current_thread, to_thread));
rt_schedule_remove_thread(to_thread);
- to_thread->stat = RT_THREAD_RUNNING;
+ to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
/* switch to new thread */
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
@@ -412,6 +412,7 @@ void rt_schedule(void)
if (rt_thread_ready_priority_group != 0)
{
+ /* need_insert_from_thread: need to insert from_thread to ready queue */
int need_insert_from_thread = 0;
to_thread = _get_highest_priority_thread(&highest_ready_priority);
@@ -443,7 +444,7 @@ void rt_schedule(void)
}
rt_schedule_remove_thread(to_thread);
- to_thread->stat = RT_THREAD_RUNNING;
+ to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
/* switch to new thread */
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
@@ -485,7 +486,7 @@ void rt_schedule(void)
else
{
rt_schedule_remove_thread(rt_current_thread);
- rt_current_thread->stat = RT_THREAD_RUNNING;
+ rt_current_thread->stat = RT_THREAD_RUNNING | (rt_current_thread->stat & ~RT_THREAD_STAT_MASK);
}
}
}
@@ -556,7 +557,7 @@ void rt_scheduler_do_irq_switch(void *context)
RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (current_thread, to_thread));
rt_schedule_remove_thread(to_thread);
- to_thread->stat = RT_THREAD_RUNNING;
+ to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
#ifdef RT_USING_OVERFLOW_CHECK
_rt_scheduler_stack_check(to_thread);
@@ -595,14 +596,16 @@ void rt_schedule_insert_thread(struct rt_thread *thread)
/* disable interrupt */
level = rt_hw_interrupt_disable();
- /* change stat */
- thread->stat = RT_THREAD_READY | (thread->stat & ~RT_THREAD_STAT_MASK);
-
+ /* it should be RUNNING thread */
if (thread->oncpu != RT_CPU_DETACHED)
{
+ thread->stat = RT_THREAD_RUNNING | (thread->stat & ~RT_THREAD_STAT_MASK);
goto __exit;
}
+ /* READY thread, insert to ready queue */
+ thread->stat = RT_THREAD_READY | (thread->stat & ~RT_THREAD_STAT_MASK);
+
cpu_id = rt_hw_cpu_id();
bind_cpu = thread->bind_cpu ;
@@ -655,14 +658,15 @@ void rt_schedule_insert_thread(struct rt_thread *thread)
/* disable interrupt */
temp = rt_hw_interrupt_disable();
- /* change stat */
- thread->stat = RT_THREAD_READY | (thread->stat & ~RT_THREAD_STAT_MASK);
-
+ /* it's current thread, it should be RUNNING thread */
if (thread == rt_current_thread)
{
+ thread->stat = RT_THREAD_RUNNING | (thread->stat & ~RT_THREAD_STAT_MASK);
goto __exit;
}
+ /* READY thread, insert to ready queue */
+ thread->stat = RT_THREAD_READY | (thread->stat & ~RT_THREAD_STAT_MASK);
/* insert thread to ready list */
rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),
&(thread->tlist));