blob: 40362045eabfa7bbae77e5f6fe44bececc856fc0 [file] [log] [blame]
Wentong Wu5611e922019-06-20 23:51:27 +08001/*
2 * Copyright (c) 2019 Intel corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
Gerard Marull-Paretascffefc82022-05-06 11:04:23 +02007#include <zephyr/kernel.h>
8#include <zephyr/kernel_structs.h>
9#include <zephyr/spinlock.h>
Wentong Wu5611e922019-06-20 23:51:27 +080010#include <kswap.h>
Gerard Marull-Paretascffefc82022-05-06 11:04:23 +020011#include <zephyr/syscall_handler.h>
12#include <zephyr/init.h>
Wentong Wu5611e922019-06-20 23:51:27 +080013#include <ksched.h>
14
15static struct z_futex_data *k_futex_find_data(struct k_futex *futex)
16{
Andrew Boie2dc2ecf2020-03-11 07:13:07 -070017 struct z_object *obj;
Wentong Wu5611e922019-06-20 23:51:27 +080018
19 obj = z_object_find(futex);
20 if (obj == NULL || obj->type != K_OBJ_FUTEX) {
21 return NULL;
22 }
23
Andrew Boief2734ab2020-03-11 06:37:42 -070024 return obj->data.futex_data;
Wentong Wu5611e922019-06-20 23:51:27 +080025}
26
Wentong Wu5611e922019-06-20 23:51:27 +080027int z_impl_k_futex_wake(struct k_futex *futex, bool wake_all)
28{
29 k_spinlock_key_t key;
Flavio Ceolinf6f951c2021-04-02 23:06:00 -070030 unsigned int woken = 0U;
Wentong Wu5611e922019-06-20 23:51:27 +080031 struct k_thread *thread;
32 struct z_futex_data *futex_data;
33
34 futex_data = k_futex_find_data(futex);
35 if (futex_data == NULL) {
36 return -EINVAL;
37 }
38
39 key = k_spin_lock(&futex_data->lock);
40
41 do {
42 thread = z_unpend_first_thread(&futex_data->wait_q);
Anas Nashif3f4f3f62021-03-29 17:13:47 -040043 if (thread != NULL) {
Wentong Wu5611e922019-06-20 23:51:27 +080044 woken++;
James Harrisc7bb4232021-03-02 13:22:52 -080045 arch_thread_return_value_set(thread, 0);
46 z_ready_thread(thread);
Wentong Wu5611e922019-06-20 23:51:27 +080047 }
48 } while (thread && wake_all);
49
50 z_reschedule(&futex_data->lock, key);
51
52 return woken;
53}
54
Andy Ross65649742019-08-06 13:34:31 -070055static inline int z_vrfy_k_futex_wake(struct k_futex *futex, bool wake_all)
Wentong Wu5611e922019-06-20 23:51:27 +080056{
57 if (Z_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) {
58 return -EACCES;
59 }
60
Andy Ross65649742019-08-06 13:34:31 -070061 return z_impl_k_futex_wake(futex, wake_all);
Wentong Wu5611e922019-06-20 23:51:27 +080062}
Andy Ross65649742019-08-06 13:34:31 -070063#include <syscalls/k_futex_wake_mrsh.c>
Wentong Wu5611e922019-06-20 23:51:27 +080064
Andy Ross78327382020-03-05 15:18:14 -080065int z_impl_k_futex_wait(struct k_futex *futex, int expected,
66 k_timeout_t timeout)
Wentong Wu5611e922019-06-20 23:51:27 +080067{
68 int ret;
69 k_spinlock_key_t key;
70 struct z_futex_data *futex_data;
71
72 futex_data = k_futex_find_data(futex);
73 if (futex_data == NULL) {
74 return -EINVAL;
75 }
76
Wentong Wu5611e922019-06-20 23:51:27 +080077 if (atomic_get(&futex->val) != (atomic_val_t)expected) {
Wentong Wu5611e922019-06-20 23:51:27 +080078 return -EAGAIN;
79 }
80
Flavio Ceolinf2e323f2021-07-08 17:13:29 -070081 key = k_spin_lock(&futex_data->lock);
82
Wentong Wu5611e922019-06-20 23:51:27 +080083 ret = z_pend_curr(&futex_data->lock,
84 key, &futex_data->wait_q, timeout);
85 if (ret == -EAGAIN) {
86 ret = -ETIMEDOUT;
87 }
88
89 return ret;
90}
91
Andy Ross643701a2019-08-13 12:58:38 -070092static inline int z_vrfy_k_futex_wait(struct k_futex *futex, int expected,
Andy Ross78327382020-03-05 15:18:14 -080093 k_timeout_t timeout)
Wentong Wu5611e922019-06-20 23:51:27 +080094{
95 if (Z_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) {
96 return -EACCES;
97 }
98
Andy Ross65649742019-08-06 13:34:31 -070099 return z_impl_k_futex_wait(futex, expected, timeout);
Wentong Wu5611e922019-06-20 23:51:27 +0800100}
Andy Ross65649742019-08-06 13:34:31 -0700101#include <syscalls/k_futex_wait_mrsh.c>