diff options
author | ed <ed@FreeBSD.org> | 2011-12-26 21:51:53 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2011-12-26 21:51:53 +0000 |
commit | 6f5f2f5fd7ad53b95e3fef6977942edeb70fc1e4 (patch) | |
tree | 9aa9d3ead883cd53debbe3b797be106429bd9ba6 /lib | |
parent | 2667624c1ccce1ce899c2609514f67efede6e038 (diff) | |
download | FreeBSD-src-6f5f2f5fd7ad53b95e3fef6977942edeb70fc1e4.zip FreeBSD-src-6f5f2f5fd7ad53b95e3fef6977942edeb70fc1e4.tar.gz |
Add libstdthreads.
This library implements the C11 threads interface on top of the pthreads
library. As discussed on the lists, the preferred way to implement
this, is as a separate library.
It is unlikely that these functions will be used a lot in the future. It
would have been easier if the C11 working group standardized (a subset
of) pthreads and clock_nanosleep(). Having it as a separate library
allows the embedded people to omit it from their system.
Discussed on: arch@, threads@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/libstdthreads/Makefile | 41 | ||||
-rw-r--r-- | lib/libstdthreads/Symbol.map | 31 | ||||
-rw-r--r-- | lib/libstdthreads/call_once.c | 44 | ||||
-rw-r--r-- | lib/libstdthreads/cnd.c | 98 | ||||
-rw-r--r-- | lib/libstdthreads/mtx.c | 116 | ||||
-rw-r--r-- | lib/libstdthreads/thrd.c | 127 | ||||
-rw-r--r-- | lib/libstdthreads/thrd_create.3 | 260 | ||||
-rw-r--r-- | lib/libstdthreads/threads.h | 106 | ||||
-rw-r--r-- | lib/libstdthreads/tss.c | 69 |
10 files changed, 893 insertions, 0 deletions
diff --git a/lib/Makefile b/lib/Makefile index ad647ec..d01fa47 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -101,6 +101,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ ${_libsmdb} \ ${_libsmutil} \ libstand \ + libstdthreads \ ${_libtelnet} \ ${_libthr} \ libthread_db \ diff --git a/lib/libstdthreads/Makefile b/lib/libstdthreads/Makefile new file mode 100644 index 0000000..544eeb0 --- /dev/null +++ b/lib/libstdthreads/Makefile @@ -0,0 +1,41 @@ +# $FreeBSD$ + +LIB= stdthreads +SHLIB_MAJOR= 0 + +INCS= threads.h +SRCS= threads.h call_once.c cnd.c mtx.c thrd.c tss.c + +MAN= thrd_create.3 +MLINKS= thrd_create.3 call_once.3 \ + thrd_create.3 cnd_broadcast.3 \ + thrd_create.3 cnd_destroy.3 \ + thrd_create.3 cnd_init.3 \ + thrd_create.3 cnd_signal.3 \ + thrd_create.3 cnd_timedwait.3 \ + thrd_create.3 cnd_wait.3 \ + thrd_create.3 mtx_destroy.3 \ + thrd_create.3 mtx_init.3 \ + thrd_create.3 mtx_lock.3 \ + thrd_create.3 mtx_timedlock.3 \ + thrd_create.3 mtx_trylock.3 \ + thrd_create.3 mtx_unlock.3 \ + thrd_create.3 thrd_current.3 \ + thrd_create.3 thrd_detach.3 \ + thrd_create.3 thrd_equal.3 \ + thrd_create.3 thrd_exit.3 \ + thrd_create.3 thrd_join.3 \ + thrd_create.3 thrd_sleep.3 \ + thrd_create.3 thrd_yield.3 \ + thrd_create.3 tss_create.3 \ + thrd_create.3 tss_delete.3 \ + thrd_create.3 tss_get.3 \ + thrd_create.3 tss_set.3 + +DPADD= ${LIBPTHREAD} +LDADD= -lpthread + +VERSION_DEF= ${.CURDIR}/../libc/Versions.def +SYMBOL_MAPS= ${.CURDIR}/Symbol.map + +.include <bsd.lib.mk> diff --git a/lib/libstdthreads/Symbol.map b/lib/libstdthreads/Symbol.map new file mode 100644 index 0000000..0fe6eac --- /dev/null +++ b/lib/libstdthreads/Symbol.map @@ -0,0 +1,31 @@ +/* + * $FreeBSD$ + */ + +FBSD_1.3 { + call_once; + cnd_broadcast; + cnd_destroy; + cnd_init; + cnd_signal; + cnd_timedwait; + cnd_wait; + mtx_destroy; + mtx_init; + mtx_lock; + mtx_timedlock; + mtx_trylock; + mtx_unlock; + thrd_create; + thrd_current; + thrd_detach; + thrd_equal; + thrd_exit; + thrd_join; + thrd_sleep; + thrd_yield; + tss_create; + tss_delete; + tss_get; + tss_set; +}; diff --git a/lib/libstdthreads/call_once.c b/lib/libstdthreads/call_once.c new file mode 100644 index 0000000..70ce8de --- /dev/null +++ b/lib/libstdthreads/call_once.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <pthread.h> + +#include "threads.h" + +void +call_once(once_flag *flag, void (*func)(void)) +{ + + (void)pthread_once((pthread_once_t *)flag, func); +} + +_Static_assert(sizeof(once_flag) == sizeof(pthread_once_t), + "once_flag must be of the same size as pthread_once_t"); diff --git a/lib/libstdthreads/cnd.c b/lib/libstdthreads/cnd.c new file mode 100644 index 0000000..145960d --- /dev/null +++ b/lib/libstdthreads/cnd.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <errno.h> +#include <pthread.h> + +#include "threads.h" + +int +cnd_broadcast(cnd_t *cond) +{ + + if (pthread_cond_broadcast(cond) != 0) + return (thrd_error); + return (thrd_success); +} + +void +cnd_destroy(cnd_t *cond) +{ + + (void)pthread_cond_destroy(cond); +} + +int +cnd_init(cnd_t *cond) +{ + + switch (pthread_cond_init(cond, NULL)) { + case 0: + return (thrd_success); + case ENOMEM: + return (thrd_nomem); + default: + return (thrd_error); + } +} + +int +cnd_signal(cnd_t *cond) +{ + + if (pthread_cond_signal(cond) != 0) + return (thrd_error); + return (thrd_success); +} + +int +cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mtx, + const struct timespec *restrict ts) +{ + + switch (pthread_cond_timedwait(cond, mtx, ts)) { + case 0: + return (thrd_success); + case ETIMEDOUT: + return (thrd_timedout); + default: + return (thrd_error); + } +} + +int +cnd_wait(cnd_t *cond, mtx_t *mtx) +{ + + if (pthread_cond_wait(cond, mtx) != 0) + return (thrd_error); + return (thrd_success); +} diff --git a/lib/libstdthreads/mtx.c b/lib/libstdthreads/mtx.c new file mode 100644 index 0000000..6c9166d --- /dev/null +++ b/lib/libstdthreads/mtx.c @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <errno.h> +#include <pthread.h> + +#include "threads.h" + +void +mtx_destroy(mtx_t *mtx) +{ + + (void)pthread_mutex_destroy(mtx); +} + +int +mtx_init(mtx_t *mtx, int type) +{ + pthread_mutexattr_t attr; + int mt; + + switch (type) { + case mtx_plain: + case mtx_timed: + mt = PTHREAD_MUTEX_NORMAL; + break; + case mtx_plain | mtx_recursive: + case mtx_timed | mtx_recursive: + mt = PTHREAD_MUTEX_RECURSIVE; + break; + default: + return (thrd_error); + } + + if (pthread_mutexattr_init(&attr) != 0) + return (thrd_error); + if (pthread_mutexattr_settype(&attr, mt) != 0) + return (thrd_error); + if (pthread_mutex_init(mtx, &attr) != 0) + return (thrd_error); + return (thrd_success); +} + +int +mtx_lock(mtx_t *mtx) +{ + + if (pthread_mutex_lock(mtx) != 0) + return (thrd_error); + return (thrd_success); +} + +int +mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts) +{ + + switch (pthread_mutex_timedlock(mtx, ts)) { + case 0: + return (thrd_success); + case ETIMEDOUT: + return (thrd_timedout); + default: + return (thrd_error); + } +} + +int +mtx_trylock(mtx_t *mtx) +{ + + switch (pthread_mutex_lock(mtx)) { + case 0: + return (thrd_success); + case EBUSY: + return (thrd_busy); + default: + return (thrd_error); + } +} + +int +mtx_unlock(mtx_t *mtx) +{ + + if (pthread_mutex_unlock(mtx) != 0) + return (thrd_error); + return (thrd_success); +} diff --git a/lib/libstdthreads/thrd.c b/lib/libstdthreads/thrd.c new file mode 100644 index 0000000..f0ce55a --- /dev/null +++ b/lib/libstdthreads/thrd.c @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <pthread.h> +#include <stdint.h> +#include <stdlib.h> + +#include "threads.h" + +struct thrd_param { + thrd_start_t func; + void *arg; +}; + +static void * +thrd_entry(void *arg) +{ + struct thrd_param tp; + + tp = *(struct thrd_param *)arg; + free(arg); + return ((void *)(intptr_t)tp.func(tp.arg)); +} + +int +thrd_create(thrd_t *thr, thrd_start_t func, void *arg) +{ + struct thrd_param *tp; + + /* + * Work around return type inconsistency. Wrap execution using + * a function conforming to pthread_create()'s start_routine. + */ + tp = malloc(sizeof(*tp)); + if (tp == NULL) + return (thrd_nomem); + tp->func = func; + tp->arg = arg; + if (pthread_create(thr, NULL, thrd_entry, tp) != 0) { + free(tp); + return (thrd_error); + } + return (thrd_success); +} + +thrd_t +thrd_current(void) +{ + + return (pthread_self()); +} + +int +thrd_detach(thrd_t thr) +{ + + if (pthread_detach(thr) != 0) + return (thrd_error); + return (thrd_success); +} + +int +thrd_equal(thrd_t thr0, thrd_t thr1) +{ + + return (pthread_equal(thr0, thr1)); +} + +_Noreturn void +thrd_exit(int res) +{ + + pthread_exit((void *)(intptr_t)res); +} + +int +thrd_join(thrd_t thr, int *res) +{ + void *value_ptr; + + if (pthread_join(thr, &value_ptr) != 0) + return (thrd_error); + *res = (intptr_t)value_ptr; + return (thrd_success); +} + +int +thrd_sleep(const struct timespec *duration, struct timespec *remaining) +{ + + return (nanosleep(duration, remaining)); +} + +void +thrd_yield(void) +{ + + pthread_yield(); +} diff --git a/lib/libstdthreads/thrd_create.3 b/lib/libstdthreads/thrd_create.3 new file mode 100644 index 0000000..ede0d7f --- /dev/null +++ b/lib/libstdthreads/thrd_create.3 @@ -0,0 +1,260 @@ +.\" Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 26, 2011 +.Dt THRD_CREATE 3 +.Os +.Sh NAME +.Nm call_once , +.Nm cnd_broadcast , +.Nm cnd_destroy , +.Nm cnd_init , +.Nm cnd_signal , +.Nm cnd_timedwait , +.Nm cnd_wait , +.Nm mtx_destroy , +.Nm mtx_init , +.Nm mtx_lock , +.Nm mtx_timedlock , +.Nm mtx_trylock , +.Nm mtx_unlock , +.Nm thrd_create , +.Nm thrd_current , +.Nm thrd_detach , +.Nm thrd_equal , +.Nm thrd_exit , +.Nm thrd_join , +.Nm thrd_sleep , +.Nm thrd_yield , +.Nm tss_create , +.Nm tss_delete , +.Nm tss_get , +.Nm tss_set +.Nd C11 threads interface +.Sh LIBRARY +.Lb libstdthreads +.Sh SYNOPSIS +.In threads.h +.Ft void +.Fn call_once "once_flag *flag" "void (*func)(void)" +.Ft int +.Fn cnd_broadcast "cnd_t *cond" +.Ft void +.Fn cnd_destroy "cnd_t *cond" +.Ft int +.Fn cnd_init "cnd_t *cond" +.Ft int +.Fn cnd_signal "cnd_t *cond" +.Ft int +.Fn cnd_timedwait "cnd_t * restrict cond" "mtx_t * restrict mtx" "const struct timespec * restrict ts" +.Ft int +.Fn cnd_wait "cnd_t *cond" "mtx_t *mtx" +.Ft void +.Fn mtx_destroy "mtx_t *mtx" +.Ft int +.Fn mtx_init "mtx_t *mtx" "int type" +.Ft int +.Fn mtx_lock "mtx_t *mtx" +.Ft int +.Fn mtx_timedlock "mtx_t * restrict mtx" "const struct timespec * restrict ts" +.Ft int +.Fn mtx_trylock "mtx_t *mtx" +.Ft int +.Fn mtx_unlock "mtx_t *mtx" +.Ft int +.Fn thrd_create "thrd_t *thr" "int (*func)(void *)" "void *arg" +.Ft thrd_t +.Fn thrd_current "void" +.Ft int +.Fn thrd_detach "thrd_t thr" +.Ft int +.Fn thrd_equal "thrd_t thr0" "thrd_t thr1" +.Ft _Noreturn void +.Fn thrd_exit "int res" +.Ft int +.Fn thrd_join "thrd_t thr" "int *res" +.Ft int +.Fn thrd_sleep "const struct timespec *duration" "struct timespec *remaining" +.Ft void +.Fn thrd_yield "void" +.Ft int +.Fn tss_create "tss_t *key" "void (*dtor)(void *)" +.Ft void +.Fn tss_delete "tss_t key" +.Ft void * +.Fn tss_get "tss_t key" +.Ft int +.Fn tss_set "tss_t key" "void *val" +.Sh DESCRIPTION +As of +.St -isoC-11 , +the C standard includes an API for writing multithreaded applications. +Since POSIX.1 already includes a threading API that is used by virtually +any multithreaded application, the interface provided by the C standard +can be considered superfluous. +.Pp +In this implementation, the threading interface is therefore implemented +as a light-weight layer on top of existing interfaces. +The functions to which these routines are mapped, are listed in the +following table. +Please refer to the documentation of the POSIX equivalent functions for +more information. +.Bl -column ".Fn mtx_timedlock" ".Xr pthread_mutex_timedlock 3" -offset indent +.It Em Function Ta Em POSIX equivalent +.It Fn call_once Ta Xr pthread_once 3 +.It Fn cnd_broadcast Ta Xr pthread_cond_broadcast 3 +.It Fn cnd_destroy Ta Xr pthread_cond_destroy 3 +.It Fn cnd_init Ta Xr pthread_cond_init 3 +.It Fn cnd_signal Ta Xr pthread_cond_signal 3 +.It Fn cnd_timedwait Ta Xr pthread_cond_timedwait 3 +.It Fn cnd_wait Ta Xr pthread_cond_wait 3 +.It Fn mtx_destroy Ta Xr pthread_mutex_destroy 3 +.It Fn mtx_init Ta Xr pthread_mutex_init 3 +.It Fn mtx_lock Ta Xr pthread_mutex_lock 3 +.It Fn mtx_timedlock Ta Xr pthread_mutex_timedlock 3 +.It Fn mtx_trylock Ta Xr pthread_mutex_trylock 3 +.It Fn mtx_unlock Ta Xr pthread_mutex_unlock 3 +.It Fn thrd_create Ta Xr pthread_create 3 +.It Fn thrd_current Ta Xr pthread_self 3 +.It Fn thrd_detach Ta Xr pthread_detach 3 +.It Fn thrd_equal Ta Xr pthread_equal 3 +.It Fn thrd_exit Ta Xr pthread_exit 3 +.It Fn thrd_join Ta Xr pthread_join 3 +.It Fn thrd_sleep Ta Xr nanosleep 2 +.It Fn thrd_yield Ta Xr pthread_yield 3 +.It Fn tss_create Ta Xr pthread_key_create 3 +.It Fn tss_delete Ta Xr pthread_key_delete 3 +.It Fn tss_get Ta Xr pthread_getspecific 3 +.It Fn tss_set Ta Xr pthread_setspecific 3 +.El +.Sh DIFFERENCES WITH POSIX EQUIVALENTS +The +.Fn thrd_exit +function returns an integer value to the thread calling +.Fn thrd_join , +whereas the +.Fn pthread_exit +function uses a pointer. +.Pp +The mutex created by +.Fn mtx_init +can be of +.Fa type +.Dv mtx_plain +or +.Dv mtx_timed +to distinguish between a mutex that supports +.Fn mtx_timedlock . +This type can be +.Em or'd +with +.Dv mtx_recursive +to create a mutex that allows recursive acquisition. +These properties are normally set using +.Fn pthread_mutex_init Ns 's +.Fa attr +parameter. +.Sh RETURN VALUES +If successful, the +.Fn cnd_broadcast , +.Fn cnd_init , +.Fn cnd_signal , +.Fn cnd_timedwait , +.Fn cnd_wait , +.Fn mtx_init , +.Fn mtx_lock , +.Fn mtx_timedlock , +.Fn mtx_trylock , +.Fn mtx_unlock , +.Fn thrd_create , +.Fn thrd_detach , +.Fn thrd_equal , +.Fn thrd_join , +.Fn thrd_sleep , +.Fn tss_create +and +.Fn tss_set +functions return +.Dv thrd_success . +Otherwise an error code will be returned to indicate the error. +.Pp +The +.Fn thrd_current +function returns the thread ID of the calling thread. +.Pp +The +.Fn tss_get +function returns the thread-specific data value associated with the +given +.Fa key . +If no thread-specific data value is associated with +.Fa key , +then the value NULL is returned. +.Sh ERRORS +The +.Fn cnd_init +and +.Fn thrd_create +functions will fail if: +.Bl -tag -width thrd_timedout +.It Dv thrd_nomem +The system has insufficient memory. +.El +.Pp +The +.Fn cnd_timedwait +and +.Fn mtx_timedlock +functions will fail if: +.Bl -tag -width thrd_timedout +.It Dv thrd_timedout +The system time has reached or exceeded the time specified in +.Fa ts +before the operation could be completed. +.El +.Pp +The +.Fn mtx_trylock +function will fail if: +.Bl -tag -width thrd_timedout +.It Dv thrd_busy +The mutex is already locked. +.El +.Pp +In all other cases, these functions may fail by returning general error +code +.Dv thrd_error . +.Sh SEE ALSO +.Xr nanosleep 2 , +.Xr pthread 3 +.Sh STANDARDS +These functions are expected to conform to +.St -isoC-11 . +.Sh HISTORY +These functions appeared in +.Fx 10.0 . +.Sh AUTHORS +.An Ed Schouten Aq ed@FreeBSD.org diff --git a/lib/libstdthreads/threads.h b/lib/libstdthreads/threads.h new file mode 100644 index 0000000..aba9ca1 --- /dev/null +++ b/lib/libstdthreads/threads.h @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _THREADS_H_ +#define _THREADS_H_ + +#include <time.h> + +/* + * The C11 threads interface. + * + * This interface is implemented as a light-weight wrapper around + * <pthread.h>. To prevent namespace pollution, the once_flag object, + * its corresponding ONCE_FLAG_INIT and TSS_DTOR_ITERATIONS have been + * copied from this header file. They must be kept in sync. + */ + +typedef struct pthread_cond *cnd_t; +typedef struct pthread_mutex *mtx_t; +typedef struct pthread *thrd_t; +typedef int tss_t; + +typedef struct { + int __state; + mtx_t __mutex; +} once_flag; + +typedef void (*tss_dtor_t)(void *); +typedef int (*thrd_start_t)(void *); + +enum { + mtx_plain = 0x1, + mtx_recursive = 0x2, + mtx_timed = 0x4 +}; + +enum { + thrd_busy = 1, + thrd_error = 2, + thrd_nomem = 3, + thrd_success = 4, + thrd_timedout = 5 +}; + +#if !defined(__cplusplus) || __cplusplus < 201103L +#define thread_local _Thread_local +#endif +#define ONCE_FLAG_INIT { 0, NULL } +#define TSS_DTOR_ITERATIONS 4 + +__BEGIN_DECLS +void call_once(once_flag *, void (*)(void)); +int cnd_broadcast(cnd_t *); +void cnd_destroy(cnd_t *); +int cnd_init(cnd_t *); +int cnd_signal(cnd_t *); +int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict, + const struct timespec *__restrict); +int cnd_wait(cnd_t *, mtx_t *); +void mtx_destroy(mtx_t *); +int mtx_init(mtx_t *, int); +int mtx_lock(mtx_t *); +int mtx_timedlock(mtx_t *__restrict, const struct timespec *__restrict); +int mtx_trylock(mtx_t *); +int mtx_unlock(mtx_t *); +int thrd_create(thrd_t *, thrd_start_t, void *); +thrd_t thrd_current(void); +int thrd_detach(thrd_t); +int thrd_equal(thrd_t, thrd_t); +_Noreturn void + thrd_exit(int); +int thrd_join(thrd_t, int *); +int thrd_sleep(const struct timespec *, struct timespec *); +void thrd_yield(void); +int tss_create(tss_t *, tss_dtor_t); +void tss_delete(tss_t); +void * tss_get(tss_t); +int tss_set(tss_t, void *); +__END_DECLS + +#endif /* !_THREADS_H_ */ diff --git a/lib/libstdthreads/tss.c b/lib/libstdthreads/tss.c new file mode 100644 index 0000000..ef78b4b --- /dev/null +++ b/lib/libstdthreads/tss.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <pthread.h> + +#include "threads.h" + +int +tss_create(tss_t *key, tss_dtor_t dtor) +{ + + if (pthread_key_create(key, dtor) != 0) + return (thrd_error); + return (thrd_success); +} + +void +tss_delete(tss_t key) +{ + + (void)pthread_key_delete(key); +} + +void * +tss_get(tss_t key) +{ + + return (pthread_getspecific(key)); +} + +int +tss_set(tss_t key, void *val) +{ + + if (pthread_setspecific(key, val) != 0) + return (thrd_error); + return (thrd_success); +} + +_Static_assert(TSS_DTOR_ITERATIONS == PTHREAD_DESTRUCTOR_ITERATIONS, + "TSS_DTOR_ITERATIONS must be identical to PTHREAD_DESTRUCTOR_ITERATIONS"); |