forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfutex.c
101 lines (81 loc) · 2.04 KB
/
futex.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
* Copyright (c) 2019 Intel corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <kernel_structs.h>
#include <spinlock.h>
#include <kswap.h>
#include <syscall_handler.h>
#include <init.h>
#include <ksched.h>
static struct z_futex_data *k_futex_find_data(struct k_futex *futex)
{
struct z_object *obj;
obj = z_object_find(futex);
if (obj == NULL || obj->type != K_OBJ_FUTEX) {
return NULL;
}
return obj->data.futex_data;
}
int z_impl_k_futex_wake(struct k_futex *futex, bool wake_all)
{
k_spinlock_key_t key;
unsigned int woken = 0U;
struct k_thread *thread;
struct z_futex_data *futex_data;
futex_data = k_futex_find_data(futex);
if (futex_data == NULL) {
return -EINVAL;
}
key = k_spin_lock(&futex_data->lock);
do {
thread = z_unpend_first_thread(&futex_data->wait_q);
if (thread != NULL) {
woken++;
arch_thread_return_value_set(thread, 0);
z_ready_thread(thread);
}
} while (thread && wake_all);
z_reschedule(&futex_data->lock, key);
return woken;
}
static inline int z_vrfy_k_futex_wake(struct k_futex *futex, bool wake_all)
{
if (Z_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) {
return -EACCES;
}
return z_impl_k_futex_wake(futex, wake_all);
}
#include <syscalls/k_futex_wake_mrsh.c>
int z_impl_k_futex_wait(struct k_futex *futex, int expected,
k_timeout_t timeout)
{
int ret;
k_spinlock_key_t key;
struct z_futex_data *futex_data;
futex_data = k_futex_find_data(futex);
if (futex_data == NULL) {
return -EINVAL;
}
if (atomic_get(&futex->val) != (atomic_val_t)expected) {
return -EAGAIN;
}
key = k_spin_lock(&futex_data->lock);
ret = z_pend_curr(&futex_data->lock,
key, &futex_data->wait_q, timeout);
if (ret == -EAGAIN) {
ret = -ETIMEDOUT;
}
return ret;
}
static inline int z_vrfy_k_futex_wait(struct k_futex *futex, int expected,
k_timeout_t timeout)
{
if (Z_SYSCALL_MEMORY_WRITE(futex, sizeof(struct k_futex)) != 0) {
return -EACCES;
}
return z_impl_k_futex_wait(futex, expected, timeout);
}
#include <syscalls/k_futex_wait_mrsh.c>