Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Dec 2011 21:51:53 +0000 (UTC)
From:      Ed Schouten <ed@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r228904 - in head: contrib/groff/tmac lib lib/libstdthreads
Message-ID:  <201112262151.pBQLprF2023340@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ed
Date: Mon Dec 26 21:51:53 2011
New Revision: 228904
URL: http://svn.freebsd.org/changeset/base/228904

Log:
  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@

Added:
  head/lib/libstdthreads/
  head/lib/libstdthreads/Makefile   (contents, props changed)
  head/lib/libstdthreads/Symbol.map   (contents, props changed)
  head/lib/libstdthreads/call_once.c   (contents, props changed)
  head/lib/libstdthreads/cnd.c   (contents, props changed)
  head/lib/libstdthreads/mtx.c   (contents, props changed)
  head/lib/libstdthreads/thrd.c   (contents, props changed)
  head/lib/libstdthreads/thrd_create.3   (contents, props changed)
  head/lib/libstdthreads/threads.h   (contents, props changed)
  head/lib/libstdthreads/tss.c   (contents, props changed)
Modified:
  head/contrib/groff/tmac/doc-syms
  head/contrib/groff/tmac/groff_mdoc.man
  head/lib/Makefile

Modified: head/contrib/groff/tmac/doc-syms
==============================================================================
--- head/contrib/groff/tmac/doc-syms	Mon Dec 26 19:41:46 2011	(r228903)
+++ head/contrib/groff/tmac/doc-syms	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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)

Modified: head/contrib/groff/tmac/groff_mdoc.man
==============================================================================
--- head/contrib/groff/tmac/groff_mdoc.man	Mon Dec 26 19:41:46 2011	(r228903)
+++ head/contrib/groff/tmac/groff_mdoc.man	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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

Modified: head/lib/Makefile
==============================================================================
--- head/lib/Makefile	Mon Dec 26 19:41:46 2011	(r228903)
+++ head/lib/Makefile	Mon Dec 26 21:51:53 2011	(r228904)
@@ -101,6 +101,7 @@ SUBDIR=	${SUBDIR_ORDERED} \
 	${_libsmdb} \
 	${_libsmutil} \
 	libstand \
+	libstdthreads \
 	${_libtelnet} \
 	${_libthr} \
 	libthread_db \

Added: head/lib/libstdthreads/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/Makefile	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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>

Added: head/lib/libstdthreads/Symbol.map
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/Symbol.map	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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;
+};

Added: head/lib/libstdthreads/call_once.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/call_once.c	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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");

Added: head/lib/libstdthreads/cnd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/cnd.c	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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);
+}

Added: head/lib/libstdthreads/mtx.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/mtx.c	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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);
+}

Added: head/lib/libstdthreads/thrd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/thrd.c	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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();
+}

Added: head/lib/libstdthreads/thrd_create.3
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/thrd_create.3	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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

Added: head/lib/libstdthreads/threads.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/threads.h	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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_ */

Added: head/lib/libstdthreads/tss.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libstdthreads/tss.c	Mon Dec 26 21:51:53 2011	(r228904)
@@ -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");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112262151.pBQLprF2023340>