123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /*
- * Copyright (c) 2020 Intel Corporation.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <kernel.h>
- #include <kernel_structs.h>
- #include <toolchain.h>
- #include <ksched.h>
- #include <wait_q.h>
- #include <syscall_handler.h>
- static struct k_spinlock lock;
- int z_impl_k_condvar_init(struct k_condvar *condvar)
- {
- z_waitq_init(&condvar->wait_q);
- z_object_init(condvar);
- SYS_PORT_TRACING_OBJ_INIT(k_condvar, condvar, 0);
- return 0;
- }
- #ifdef CONFIG_USERSPACE
- int z_vrfy_k_condvar_init(struct k_condvar *condvar)
- {
- Z_OOPS(Z_SYSCALL_OBJ_INIT(condvar, K_OBJ_CONDVAR));
- return z_impl_k_condvar_init(condvar);
- }
- #include <syscalls/k_condvar_init_mrsh.c>
- #endif
- int z_impl_k_condvar_signal(struct k_condvar *condvar)
- {
- k_spinlock_key_t key = k_spin_lock(&lock);
- SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, signal, condvar);
- struct k_thread *thread = z_unpend_first_thread(&condvar->wait_q);
- if (thread != NULL) {
- SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_condvar, signal, condvar, K_FOREVER);
- arch_thread_return_value_set(thread, 0);
- z_ready_thread(thread);
- z_reschedule(&lock, key);
- } else {
- k_spin_unlock(&lock, key);
- }
- SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, signal, condvar, 0);
- return 0;
- }
- #ifdef CONFIG_USERSPACE
- int z_vrfy_k_condvar_signal(struct k_condvar *condvar)
- {
- Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR));
- return z_impl_k_condvar_signal(condvar);
- }
- #include <syscalls/k_condvar_signal_mrsh.c>
- #endif
- int z_impl_k_condvar_broadcast(struct k_condvar *condvar)
- {
- struct k_thread *pending_thread;
- k_spinlock_key_t key;
- int woken = 0;
- key = k_spin_lock(&lock);
- SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, broadcast, condvar);
- /* wake up any threads that are waiting to write */
- while ((pending_thread = z_unpend_first_thread(&condvar->wait_q)) !=
- NULL) {
- woken++;
- arch_thread_return_value_set(pending_thread, 0);
- z_ready_thread(pending_thread);
- }
- SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, broadcast, condvar, woken);
- z_reschedule(&lock, key);
- return woken;
- }
- #ifdef CONFIG_USERSPACE
- int z_vrfy_k_condvar_broadcast(struct k_condvar *condvar)
- {
- Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR));
- return z_impl_k_condvar_broadcast(condvar);
- }
- #include <syscalls/k_condvar_broadcast_mrsh.c>
- #endif
- int z_impl_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex,
- k_timeout_t timeout)
- {
- k_spinlock_key_t key;
- int ret;
- SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, wait, condvar);
- key = k_spin_lock(&lock);
- k_mutex_unlock(mutex);
- ret = z_pend_curr(&lock, key, &condvar->wait_q, timeout);
- k_mutex_lock(mutex, K_FOREVER);
- SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, wait, condvar, ret);
- return ret;
- }
- #ifdef CONFIG_USERSPACE
- int z_vrfy_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex,
- k_timeout_t timeout)
- {
- Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR));
- Z_OOPS(Z_SYSCALL_OBJ(mutex, K_OBJ_MUTEX));
- return z_impl_k_condvar_wait(condvar, mutex, timeout);
- }
- #include <syscalls/k_condvar_wait_mrsh.c>
- #endif
|