1 /*
2  * Copyright (c) 2023, Meta
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <threads.h>
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/posix/pthread.h>
12 #include <zephyr/posix/sched.h>
13 #include <zephyr/sys/clock.h>
14 
15 struct thrd_trampoline_arg {
16 	thrd_start_t func;
17 	void *arg;
18 };
19 
thrd_create(thrd_t * thr,thrd_start_t func,void * arg)20 int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
21 {
22 	typedef void *(*pthread_func_t)(void *arg);
23 
24 	pthread_func_t pfunc = (pthread_func_t)func;
25 
26 	switch (pthread_create(thr, NULL, pfunc, arg)) {
27 	case 0:
28 		return thrd_success;
29 	case EAGAIN:
30 		return thrd_nomem;
31 	default:
32 		return thrd_error;
33 	}
34 }
35 
thrd_equal(thrd_t lhs,thrd_t rhs)36 int thrd_equal(thrd_t lhs, thrd_t rhs)
37 {
38 	return pthread_equal(lhs, rhs);
39 }
40 
thrd_current(void)41 thrd_t thrd_current(void)
42 {
43 	return pthread_self();
44 }
45 
thrd_sleep(const struct timespec * duration,struct timespec * remaining)46 int thrd_sleep(const struct timespec *duration, struct timespec *remaining)
47 {
48 	if (sys_clock_nanosleep(SYS_CLOCK_REALTIME, 0, duration, remaining) != 0) {
49 		return thrd_error;
50 	}
51 
52 	return thrd_success;
53 }
54 
thrd_yield(void)55 void thrd_yield(void)
56 {
57 	(void)sched_yield();
58 }
59 
thrd_exit(int res)60 FUNC_NORETURN void thrd_exit(int res)
61 {
62 	pthread_exit(INT_TO_POINTER(res));
63 
64 	CODE_UNREACHABLE;
65 }
66 
thrd_detach(thrd_t thr)67 int thrd_detach(thrd_t thr)
68 {
69 	switch (pthread_detach(thr)) {
70 	case 0:
71 		return thrd_success;
72 	default:
73 		return thrd_error;
74 	}
75 }
76 
thrd_join(thrd_t thr,int * res)77 int thrd_join(thrd_t thr, int *res)
78 {
79 	void *ret;
80 
81 	switch (pthread_join(thr, &ret)) {
82 	case 0:
83 		if (res != NULL) {
84 			*res = POINTER_TO_INT(ret);
85 		}
86 		return thrd_success;
87 	default:
88 		return thrd_error;
89 	}
90 }
91