kernel/sched: Make z_ready_thread() safe vs. already-running threads
This is part of the scheduler API, and was always just a synchronized wrapper around the internal ready_thread() function. But where the internal users seem to be careful not to call it on threads that are not known to be already queued or running, the general users in the IPC code seem to be less strict. Add a simple test to detect the case where a thread is already running. Right now this just loops over the array of CPUs, so is O(N) in the CPU count even though N is never more than four for us currently. But this is possible without modifying data structures. A more scalable way to do this if we ever need to run on very parallel systems would be to use another state bit for RUNNING, or to keep a backpointer in the thread struct to the CPU it's running on, etc... Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
6b84ab3830
commit
05c468f594
1 changed files with 22 additions and 1 deletions
|
@ -455,6 +455,25 @@ static void update_cache(int preempt_ok)
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool thread_active_elsewhere(struct k_thread *thread)
|
||||
{
|
||||
/* True if the thread is currently running on another CPU.
|
||||
* There are more scalable designs to answer this question in
|
||||
* constant time, but this is fine for now.
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
int currcpu = _current_cpu->id;
|
||||
|
||||
for (int i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
|
||||
if ((i != currcpu) &&
|
||||
(_kernel.cpus[i].current == thread)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ready_thread(struct k_thread *thread)
|
||||
{
|
||||
#ifdef CONFIG_KERNEL_COHERENCE
|
||||
|
@ -477,7 +496,9 @@ static void ready_thread(struct k_thread *thread)
|
|||
void z_ready_thread(struct k_thread *thread)
|
||||
{
|
||||
LOCKED(&sched_spinlock) {
|
||||
ready_thread(thread);
|
||||
if (!thread_active_elsewhere(thread)) {
|
||||
ready_thread(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue