1228904Sed/*- 2228904Sed * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> 3228904Sed * All rights reserved. 4228904Sed * 5228904Sed * Redistribution and use in source and binary forms, with or without 6228904Sed * modification, are permitted provided that the following conditions 7228904Sed * are met: 8228904Sed * 1. Redistributions of source code must retain the above copyright 9228904Sed * notice, this list of conditions and the following disclaimer. 10228904Sed * 2. Redistributions in binary form must reproduce the above copyright 11228904Sed * notice, this list of conditions and the following disclaimer in the 12228904Sed * documentation and/or other materials provided with the distribution. 13228904Sed * 14228904Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15228904Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16228904Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17228904Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18228904Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19228904Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20228904Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21228904Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22228904Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23228904Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24228904Sed * SUCH DAMAGE. 25228904Sed * 26228904Sed * $FreeBSD$ 27228904Sed */ 28228904Sed 29228904Sed#include <sys/cdefs.h> 30228904Sed__FBSDID("$FreeBSD$"); 31228904Sed 32228904Sed#include <pthread.h> 33228904Sed#include <stdint.h> 34228904Sed#include <stdlib.h> 35228904Sed 36228904Sed#include "threads.h" 37228904Sed 38228904Sedstruct thrd_param { 39228904Sed thrd_start_t func; 40228904Sed void *arg; 41228904Sed}; 42228904Sed 43228904Sedstatic void * 44228904Sedthrd_entry(void *arg) 45228904Sed{ 46228904Sed struct thrd_param tp; 47228904Sed 48228904Sed tp = *(struct thrd_param *)arg; 49228904Sed free(arg); 50228904Sed return ((void *)(intptr_t)tp.func(tp.arg)); 51228904Sed} 52228904Sed 53228904Sedint 54228904Sedthrd_create(thrd_t *thr, thrd_start_t func, void *arg) 55228904Sed{ 56228904Sed struct thrd_param *tp; 57228904Sed 58228904Sed /* 59228904Sed * Work around return type inconsistency. Wrap execution using 60228904Sed * a function conforming to pthread_create()'s start_routine. 61228904Sed */ 62228904Sed tp = malloc(sizeof(*tp)); 63228904Sed if (tp == NULL) 64228904Sed return (thrd_nomem); 65228904Sed tp->func = func; 66228904Sed tp->arg = arg; 67228904Sed if (pthread_create(thr, NULL, thrd_entry, tp) != 0) { 68228904Sed free(tp); 69228904Sed return (thrd_error); 70228904Sed } 71228904Sed return (thrd_success); 72228904Sed} 73228904Sed 74228904Sedthrd_t 75228904Sedthrd_current(void) 76228904Sed{ 77228904Sed 78228904Sed return (pthread_self()); 79228904Sed} 80228904Sed 81228904Sedint 82228904Sedthrd_detach(thrd_t thr) 83228904Sed{ 84228904Sed 85228904Sed if (pthread_detach(thr) != 0) 86228904Sed return (thrd_error); 87228904Sed return (thrd_success); 88228904Sed} 89228904Sed 90228904Sedint 91228904Sedthrd_equal(thrd_t thr0, thrd_t thr1) 92228904Sed{ 93228904Sed 94228904Sed return (pthread_equal(thr0, thr1)); 95228904Sed} 96228904Sed 97228904Sed_Noreturn void 98228904Sedthrd_exit(int res) 99228904Sed{ 100228904Sed 101228904Sed pthread_exit((void *)(intptr_t)res); 102228904Sed} 103228904Sed 104228904Sedint 105228904Sedthrd_join(thrd_t thr, int *res) 106228904Sed{ 107228904Sed void *value_ptr; 108228904Sed 109228904Sed if (pthread_join(thr, &value_ptr) != 0) 110228904Sed return (thrd_error); 111228904Sed *res = (intptr_t)value_ptr; 112228904Sed return (thrd_success); 113228904Sed} 114228904Sed 115228904Sedint 116228904Sedthrd_sleep(const struct timespec *duration, struct timespec *remaining) 117228904Sed{ 118228904Sed 119228904Sed return (nanosleep(duration, remaining)); 120228904Sed} 121228904Sed 122228904Sedvoid 123228904Sedthrd_yield(void) 124228904Sed{ 125228904Sed 126228904Sed pthread_yield(); 127228904Sed} 128