blob: 53ce88beb3a08294ba56e91cfc77d58e01b16ec6 [file] [log] [blame]
Anas Nashif06eb4892020-08-23 12:39:09 -04001/*
2 * Copyright (c) 2020 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include <kernel.h>
8#include <kernel_structs.h>
9#include <toolchain.h>
10#include <ksched.h>
11#include <wait_q.h>
Anas Nashif989ebf62020-11-27 11:30:45 -050012#include <syscall_handler.h>
Anas Nashif06eb4892020-08-23 12:39:09 -040013
14static struct k_spinlock lock;
15
16int z_impl_k_condvar_init(struct k_condvar *condvar)
17{
18 z_waitq_init(&condvar->wait_q);
19 z_object_init(condvar);
Torbjörn Leksellb93ff292021-03-26 10:37:05 +010020
21 SYS_PORT_TRACING_OBJ_INIT(k_condvar, condvar, 0);
22
Anas Nashif06eb4892020-08-23 12:39:09 -040023 return 0;
24}
25
Anas Nashif989ebf62020-11-27 11:30:45 -050026#ifdef CONFIG_USERSPACE
27int z_vrfy_k_condvar_init(struct k_condvar *condvar)
28{
29 Z_OOPS(Z_SYSCALL_OBJ_INIT(condvar, K_OBJ_CONDVAR));
30 return z_impl_k_condvar_init(condvar);
31}
32#include <syscalls/k_condvar_init_mrsh.c>
33#endif
34
Anas Nashif06eb4892020-08-23 12:39:09 -040035int z_impl_k_condvar_signal(struct k_condvar *condvar)
36{
37 k_spinlock_key_t key = k_spin_lock(&lock);
Torbjörn Leksellb93ff292021-03-26 10:37:05 +010038
39 SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, signal, condvar);
40
Anas Nashif06eb4892020-08-23 12:39:09 -040041 struct k_thread *thread = z_unpend_first_thread(&condvar->wait_q);
42
43 if (thread != NULL) {
Torbjörn Leksellb93ff292021-03-26 10:37:05 +010044 SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_condvar, signal, condvar, K_FOREVER);
45
Anas Nashif06eb4892020-08-23 12:39:09 -040046 arch_thread_return_value_set(thread, 0);
47 z_ready_thread(thread);
48 z_reschedule(&lock, key);
49 } else {
50 k_spin_unlock(&lock, key);
51 }
Torbjörn Leksellb93ff292021-03-26 10:37:05 +010052
53 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, signal, condvar, 0);
54
Anas Nashif06eb4892020-08-23 12:39:09 -040055 return 0;
56}
57
Anas Nashif989ebf62020-11-27 11:30:45 -050058#ifdef CONFIG_USERSPACE
59int z_vrfy_k_condvar_signal(struct k_condvar *condvar)
60{
61 Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR));
62 return z_impl_k_condvar_signal(condvar);
63}
64#include <syscalls/k_condvar_signal_mrsh.c>
65#endif
66
Anas Nashif06eb4892020-08-23 12:39:09 -040067int z_impl_k_condvar_broadcast(struct k_condvar *condvar)
68{
69 struct k_thread *pending_thread;
70 k_spinlock_key_t key;
71 int woken = 0;
72
73 key = k_spin_lock(&lock);
74
Torbjörn Leksellb93ff292021-03-26 10:37:05 +010075 SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, broadcast, condvar);
76
Anas Nashif06eb4892020-08-23 12:39:09 -040077 /* wake up any threads that are waiting to write */
78 while ((pending_thread = z_unpend_first_thread(&condvar->wait_q)) !=
79 NULL) {
James Harrisc7bb4232021-03-02 13:22:52 -080080 woken++;
Anas Nashif06eb4892020-08-23 12:39:09 -040081 arch_thread_return_value_set(pending_thread, 0);
82 z_ready_thread(pending_thread);
Anas Nashif06eb4892020-08-23 12:39:09 -040083 }
84
Torbjörn Leksellb93ff292021-03-26 10:37:05 +010085 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, broadcast, condvar, woken);
86
Anas Nashif06eb4892020-08-23 12:39:09 -040087 z_reschedule(&lock, key);
88
89 return woken;
90}
Anas Nashif989ebf62020-11-27 11:30:45 -050091#ifdef CONFIG_USERSPACE
92int z_vrfy_k_condvar_broadcast(struct k_condvar *condvar)
93{
94 Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR));
95 return z_impl_k_condvar_broadcast(condvar);
96}
97#include <syscalls/k_condvar_broadcast_mrsh.c>
98#endif
Anas Nashif06eb4892020-08-23 12:39:09 -040099
100int z_impl_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex,
101 k_timeout_t timeout)
102{
103 k_spinlock_key_t key;
104 int ret;
105
Torbjörn Leksellb93ff292021-03-26 10:37:05 +0100106 SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, wait, condvar);
107
Anas Nashif06eb4892020-08-23 12:39:09 -0400108 key = k_spin_lock(&lock);
109 k_mutex_unlock(mutex);
110
111 ret = z_pend_curr(&lock, key, &condvar->wait_q, timeout);
112 k_mutex_lock(mutex, K_FOREVER);
113
Torbjörn Leksellb93ff292021-03-26 10:37:05 +0100114 SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, wait, condvar, ret);
115
Anas Nashif06eb4892020-08-23 12:39:09 -0400116 return ret;
117}
Anas Nashif989ebf62020-11-27 11:30:45 -0500118#ifdef CONFIG_USERSPACE
119int z_vrfy_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex,
120 k_timeout_t timeout)
121{
122 Z_OOPS(Z_SYSCALL_OBJ(condvar, K_OBJ_CONDVAR));
123 Z_OOPS(Z_SYSCALL_OBJ(mutex, K_OBJ_MUTEX));
124 return z_impl_k_condvar_wait(condvar, mutex, timeout);
125}
126#include <syscalls/k_condvar_wait_mrsh.c>
127#endif