93dc7e7438
Spinlocks taken in ISRs were storing the _current thread pointer of the interrupted thread as the owner, which was never strictly correct but was benign as the thread would never run until the lock was released. But now k_thread_abort(_current) in an ISR has been fixed to eliminate all references to the (now aborted) thread struct, and _current points to a dummy thread. Handle that edge case in the validation framework. Signed-off-by: Andy Ross <andyross@google.com>
48 lines
961 B
C
48 lines
961 B
C
/*
|
|
* Copyright (c) 2018,2024 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include <kernel_internal.h>
|
|
#include <zephyr/spinlock.h>
|
|
|
|
bool z_spin_lock_valid(struct k_spinlock *l)
|
|
{
|
|
uintptr_t thread_cpu = l->thread_cpu;
|
|
|
|
if (thread_cpu != 0U) {
|
|
if ((thread_cpu & 3U) == _current_cpu->id) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool z_spin_unlock_valid(struct k_spinlock *l)
|
|
{
|
|
uintptr_t tcpu = l->thread_cpu;
|
|
|
|
l->thread_cpu = 0;
|
|
|
|
if (arch_is_in_isr() && _current->base.thread_state & _THREAD_DUMMY) {
|
|
/* Edge case where an ISR aborted _current */
|
|
return true;
|
|
}
|
|
if (tcpu != (_current_cpu->id | (uintptr_t)_current)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void z_spin_lock_set_owner(struct k_spinlock *l)
|
|
{
|
|
l->thread_cpu = _current_cpu->id | (uintptr_t)_current;
|
|
}
|
|
|
|
#ifdef CONFIG_KERNEL_COHERENCE
|
|
bool z_spin_lock_mem_coherent(struct k_spinlock *l)
|
|
{
|
|
return arch_mem_coherent((void *)l);
|
|
}
|
|
#endif /* CONFIG_KERNEL_COHERENCE */
|