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