kernel: stack: fix stack_push spinlock and return
The z_impl_k_stack_push() has a spinlock that is set after stack member access, which could cause race conditions and used multiple return statements. This commit - moves the lock before the CHECKIF - implements goto for flow of lock, reschedule, and unlock - uses ret for single return at the end Signed-off-by: Jennifer Williams <jennifer.m.williams@intel.com>
This commit is contained in:
parent
2ffbad4941
commit
4d33007486
1 changed files with 11 additions and 6 deletions
|
@ -97,14 +97,14 @@ int k_stack_cleanup(struct k_stack *stack)
|
|||
int z_impl_k_stack_push(struct k_stack *stack, stack_data_t data)
|
||||
{
|
||||
struct k_thread *first_pending_thread;
|
||||
k_spinlock_key_t key;
|
||||
int ret = 0;
|
||||
k_spinlock_key_t key = k_spin_lock(&stack->lock);
|
||||
|
||||
CHECKIF(stack->next == stack->top) {
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&stack->lock);
|
||||
|
||||
first_pending_thread = z_unpend_first_thread(&stack->wait_q);
|
||||
|
||||
if (first_pending_thread != NULL) {
|
||||
|
@ -113,13 +113,18 @@ int z_impl_k_stack_push(struct k_stack *stack, stack_data_t data)
|
|||
z_thread_return_value_set_with_data(first_pending_thread,
|
||||
0, (void *)data);
|
||||
z_reschedule(&stack->lock, key);
|
||||
goto end;
|
||||
} else {
|
||||
*(stack->next) = data;
|
||||
stack->next++;
|
||||
k_spin_unlock(&stack->lock, key);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
k_spin_unlock(&stack->lock, key);
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue