1fc6f0665SEd Schouten /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
35e53a4f9SPedro F. Giffuni *
4fc6f0665SEd Schouten * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
5fc6f0665SEd Schouten * All rights reserved.
6fc6f0665SEd Schouten *
7fc6f0665SEd Schouten * Redistribution and use in source and binary forms, with or without
8fc6f0665SEd Schouten * modification, are permitted provided that the following conditions
9fc6f0665SEd Schouten * are met:
10fc6f0665SEd Schouten * 1. Redistributions of source code must retain the above copyright
11fc6f0665SEd Schouten * notice, this list of conditions and the following disclaimer.
12fc6f0665SEd Schouten * 2. Redistributions in binary form must reproduce the above copyright
13fc6f0665SEd Schouten * notice, this list of conditions and the following disclaimer in the
14fc6f0665SEd Schouten * documentation and/or other materials provided with the distribution.
15fc6f0665SEd Schouten *
16fc6f0665SEd Schouten * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17fc6f0665SEd Schouten * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18fc6f0665SEd Schouten * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19fc6f0665SEd Schouten * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20fc6f0665SEd Schouten * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21fc6f0665SEd Schouten * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22fc6f0665SEd Schouten * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23fc6f0665SEd Schouten * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24fc6f0665SEd Schouten * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25fc6f0665SEd Schouten * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26fc6f0665SEd Schouten * SUCH DAMAGE.
27fc6f0665SEd Schouten */
28fc6f0665SEd Schouten
29fc6f0665SEd Schouten #include <sys/cdefs.h>
30fc6f0665SEd Schouten #include <pthread.h>
31fc6f0665SEd Schouten #include <stdint.h>
32fc6f0665SEd Schouten #include <stdlib.h>
33fc6f0665SEd Schouten
34fc6f0665SEd Schouten #include "threads.h"
35fc6f0665SEd Schouten
36fc6f0665SEd Schouten struct thrd_param {
37fc6f0665SEd Schouten thrd_start_t func;
38fc6f0665SEd Schouten void *arg;
39fc6f0665SEd Schouten };
40fc6f0665SEd Schouten
41fc6f0665SEd Schouten static void *
thrd_entry(void * arg)42fc6f0665SEd Schouten thrd_entry(void *arg)
43fc6f0665SEd Schouten {
44fc6f0665SEd Schouten struct thrd_param tp;
45fc6f0665SEd Schouten
46fc6f0665SEd Schouten tp = *(struct thrd_param *)arg;
47fc6f0665SEd Schouten free(arg);
48fc6f0665SEd Schouten return ((void *)(intptr_t)tp.func(tp.arg));
49fc6f0665SEd Schouten }
50fc6f0665SEd Schouten
51fc6f0665SEd Schouten int
thrd_create(thrd_t * thr,thrd_start_t func,void * arg)52fc6f0665SEd Schouten thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
53fc6f0665SEd Schouten {
54fc6f0665SEd Schouten struct thrd_param *tp;
55fc6f0665SEd Schouten
56fc6f0665SEd Schouten /*
57fc6f0665SEd Schouten * Work around return type inconsistency. Wrap execution using
58fc6f0665SEd Schouten * a function conforming to pthread_create()'s start_routine.
59fc6f0665SEd Schouten */
60fc6f0665SEd Schouten tp = malloc(sizeof(*tp));
61fc6f0665SEd Schouten if (tp == NULL)
62fc6f0665SEd Schouten return (thrd_nomem);
63fc6f0665SEd Schouten tp->func = func;
64fc6f0665SEd Schouten tp->arg = arg;
65fc6f0665SEd Schouten if (pthread_create(thr, NULL, thrd_entry, tp) != 0) {
66fc6f0665SEd Schouten free(tp);
67fc6f0665SEd Schouten return (thrd_error);
68fc6f0665SEd Schouten }
69fc6f0665SEd Schouten return (thrd_success);
70fc6f0665SEd Schouten }
71fc6f0665SEd Schouten
72fc6f0665SEd Schouten thrd_t
thrd_current(void)73fc6f0665SEd Schouten thrd_current(void)
74fc6f0665SEd Schouten {
75fc6f0665SEd Schouten
76fc6f0665SEd Schouten return (pthread_self());
77fc6f0665SEd Schouten }
78fc6f0665SEd Schouten
79fc6f0665SEd Schouten int
thrd_detach(thrd_t thr)80fc6f0665SEd Schouten thrd_detach(thrd_t thr)
81fc6f0665SEd Schouten {
82fc6f0665SEd Schouten
83fc6f0665SEd Schouten if (pthread_detach(thr) != 0)
84fc6f0665SEd Schouten return (thrd_error);
85fc6f0665SEd Schouten return (thrd_success);
86fc6f0665SEd Schouten }
87fc6f0665SEd Schouten
88fc6f0665SEd Schouten int
thrd_equal(thrd_t thr0,thrd_t thr1)89fc6f0665SEd Schouten thrd_equal(thrd_t thr0, thrd_t thr1)
90fc6f0665SEd Schouten {
91fc6f0665SEd Schouten
92fc6f0665SEd Schouten return (pthread_equal(thr0, thr1));
93fc6f0665SEd Schouten }
94fc6f0665SEd Schouten
95fc6f0665SEd Schouten _Noreturn void
thrd_exit(int res)96fc6f0665SEd Schouten thrd_exit(int res)
97fc6f0665SEd Schouten {
98fc6f0665SEd Schouten
99fc6f0665SEd Schouten pthread_exit((void *)(intptr_t)res);
100fc6f0665SEd Schouten }
101fc6f0665SEd Schouten
102fc6f0665SEd Schouten int
thrd_join(thrd_t thr,int * res)103fc6f0665SEd Schouten thrd_join(thrd_t thr, int *res)
104fc6f0665SEd Schouten {
105fc6f0665SEd Schouten void *value_ptr;
106fc6f0665SEd Schouten
107fc6f0665SEd Schouten if (pthread_join(thr, &value_ptr) != 0)
108fc6f0665SEd Schouten return (thrd_error);
1093b2cc6d4SKonstantin Belousov if (res != NULL)
110fc6f0665SEd Schouten *res = (intptr_t)value_ptr;
111fc6f0665SEd Schouten return (thrd_success);
112fc6f0665SEd Schouten }
113fc6f0665SEd Schouten
114fc6f0665SEd Schouten int
thrd_sleep(const struct timespec * duration,struct timespec * remaining)115fc6f0665SEd Schouten thrd_sleep(const struct timespec *duration, struct timespec *remaining)
116fc6f0665SEd Schouten {
117fc6f0665SEd Schouten
118fc6f0665SEd Schouten return (nanosleep(duration, remaining));
119fc6f0665SEd Schouten }
120fc6f0665SEd Schouten
121fc6f0665SEd Schouten void
thrd_yield(void)122fc6f0665SEd Schouten thrd_yield(void)
123fc6f0665SEd Schouten {
124fc6f0665SEd Schouten
125fc6f0665SEd Schouten pthread_yield();
126fc6f0665SEd Schouten }
127