kernel/sched: Fix SMP scheduling

Recent changes post-scheduler-rewrite broke scheduling on SMP:

The "preempt_ok" feature added to isolate preemption points wasn't
honored in SMP mode.  Fix this by adding a "swap_ok" field to the CPU
record (not the thread) which is set at the same time out of
update_cache().

The "queued" flag wasn't being maintained correctly when swapping away
from _current (it was added back to the queue, but the flag wasn't
set).

Abstract out a "should_preempt()" predicate so SMP and uniprocessor
paths share the same logic, which is distressingly subtle.

There were two places where _Swap() was predicated on
_get_next_ready_thread() != _current.  That's no longer a benign
optimization in SMP, where the former function REMOVES the next thread
from the queue.  Just call _Swap() directly in SMP, which has a
unified C implementation that does this test already.  Don't change
other architectures in case it exposes bugs with _Swap() switching
back to the same thread (it should work, I just don't want to break
anything).

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2018-05-30 11:23:02 -07:00 committed by Anas Nashif
commit eace1df539
3 changed files with 112 additions and 31 deletions

View file

@ -96,7 +96,12 @@ struct _cpu {
/* one assigned idle thread per CPU */
struct k_thread *idle_thread;
int id;
u8_t id;
#ifdef CONFIG_SMP
/* True when _current is allowed to context switch */
u8_t swap_ok;
#endif
};
typedef struct _cpu _cpu_t;