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@
This commit is contained in:
parent
2667624c1c
commit
6f5f2f5fd7
@ -814,6 +814,7 @@
|
||||
.ds doc-str-Lb-librt \*[Px] \*[doc-str-Lb]Real-time Library (librt, \-lrt)
|
||||
.ds doc-str-Lb-libsdp Bluetooth Service Discovery Protocol User Library (libsdp, \-lsdp)
|
||||
.ds doc-str-Lb-libssp Buffer Overflow Protection Library (libssp, \-lssp)
|
||||
.ds doc-str-Lb-libstdthreads C11 Threads Library (libstdthreads, \-lstdthreads)
|
||||
.ds doc-str-Lb-libSystem System Library (libSystem, \-lSystem)
|
||||
.ds doc-str-Lb-libtermcap Termcap Access Library (libtermcap, \-ltermcap)
|
||||
.ds doc-str-Lb-libterminfo Terminal Information Library (libterminfo, \-lterminfo)
|
||||
|
@ -1797,6 +1797,8 @@ and their results are:
|
||||
.Lb libsdp
|
||||
.It Li libssp
|
||||
.Lb libssp
|
||||
.It Li libstdthreads
|
||||
.Lb libstdthreads
|
||||
.It Li libSystem
|
||||
.Lb libSystem
|
||||
.It Li libtermcap
|
||||
|
@ -101,6 +101,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
|
||||
${_libsmdb} \
|
||||
${_libsmutil} \
|
||||
libstand \
|
||||
libstdthreads \
|
||||
${_libtelnet} \
|
||||
${_libthr} \
|
||||
libthread_db \
|
||||
|
41
lib/libstdthreads/Makefile
Normal file
41
lib/libstdthreads/Makefile
Normal file
@ -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>
|
31
lib/libstdthreads/Symbol.map
Normal file
31
lib/libstdthreads/Symbol.map
Normal file
@ -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;
|
||||
};
|
44
lib/libstdthreads/call_once.c
Normal file
44
lib/libstdthreads/call_once.c
Normal file
@ -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");
|
98
lib/libstdthreads/cnd.c
Normal file
98
lib/libstdthreads/cnd.c
Normal file
@ -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);
|
||||
}
|
116
lib/libstdthreads/mtx.c
Normal file
116
lib/libstdthreads/mtx.c
Normal file
@ -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);
|
||||
}
|
127
lib/libstdthreads/thrd.c
Normal file
127
lib/libstdthreads/thrd.c
Normal file
@ -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();
|
||||
}
|
260
lib/libstdthreads/thrd_create.3
Normal file
260
lib/libstdthreads/thrd_create.3
Normal file
@ -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
|
106
lib/libstdthreads/threads.h
Normal file
106
lib/libstdthreads/threads.h
Normal file
@ -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_ */
|
69
lib/libstdthreads/tss.c
Normal file
69
lib/libstdthreads/tss.c
Normal file
@ -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");
|
Loading…
Reference in New Issue
Block a user