blob: c52f90d655df4a6cb30143130118f2acfd675571 [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
7#include <kernel.h>
8#include <kernel_structs.h>
9#include <spinlock.h>
10#include <kswap.h>
11#include <syscall_handler.h>
12#include <init.h>
13#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;
30 unsigned int woken = 0;
31 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);
43 if (thread) {
44 z_ready_thread(thread);
Andrew Boie4f77c2a2019-11-07 12:43:29 -080045 arch_thread_return_value_set(thread, 0);
Wentong Wu5611e922019-06-20 23:51:27 +080046 woken++;
47 }
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
77 key = k_spin_lock(&futex_data->lock);
78
79 if (atomic_get(&futex->val) != (atomic_val_t)expected) {
80 k_spin_unlock(&futex_data->lock, key);
81 return -EAGAIN;
82 }
83
84 ret = z_pend_curr(&futex_data->lock,
85 key, &futex_data->wait_q, timeout);
86 if (ret == -EAGAIN) {
87 ret = -ETIMEDOUT;
88 }
89
90 return ret;
91}
92
Andy Ross643701a2019-08-13 12:58:38 -070093static inline int z_vrfy_k_futex_wait(struct k_futex *futex, int expected,
Andy Ross78327382020-03-05 15:18:14 -080094 k_timeout_t timeout)
Wentong Wu5611e922019-06-20 23:51:27 +080095{
96 if (Z_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) {
97 return -EACCES;
98 }
99
Andy Ross65649742019-08-06 13:34:31 -0700100 return z_impl_k_futex_wait(futex, expected, timeout);
Wentong Wu5611e922019-06-20 23:51:27 +0800101}
Andy Ross65649742019-08-06 13:34:31 -0700102#include <syscalls/k_futex_wait_mrsh.c>