summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libpthread/include/pthread.h17
-rw-r--r--lib/libpthread/man/Makefile.inc9
-rw-r--r--lib/libpthread/man/pthread_barrier_init.3101
-rw-r--r--lib/libpthread/man/pthread_barrier_wait.357
-rw-r--r--lib/libpthread/man/pthread_barrierattr_getpshared.385
-rw-r--r--lib/libpthread/man/pthread_barrierattr_init.377
-rw-r--r--lib/librthread/Makefile4
-rw-r--r--lib/librthread/rthread.h14
-rw-r--r--lib/librthread/rthread_barrier.c145
-rw-r--r--lib/librthread/rthread_barrier_attr.c76
10 files changed, 581 insertions, 4 deletions
diff --git a/lib/libpthread/include/pthread.h b/lib/libpthread/include/pthread.h
index 0a3cde4f753..0dccc5e91f6 100644
--- a/lib/libpthread/include/pthread.h
+++ b/lib/libpthread/include/pthread.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread.h,v 1.32 2012/02/23 04:43:06 guenther Exp $ */
+/* $OpenBSD: pthread.h,v 1.33 2012/04/11 10:18:46 pirofti Exp $ */
/*
* Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
@@ -103,6 +103,11 @@
#define PTHREAD_CANCELED ((void *) 1)
/*
+ * Barrier flags
+ */
+#define PTHREAD_BARRIER_SERIAL_THREAD -1
+
+/*
* Forward structure definitions.
*
* These are mostly opaque to the user.
@@ -134,6 +139,8 @@ typedef volatile int pthread_key_t;
typedef struct pthread_once pthread_once_t;
typedef struct pthread_rwlock *pthread_rwlock_t;
typedef struct pthread_rwlockattr *pthread_rwlockattr_t;
+typedef struct pthread_barrier *pthread_barrier_t;
+typedef struct pthread_barrierattr *pthread_barrierattr_t;
/*
* Additional type definitions:
@@ -307,6 +314,14 @@ int pthread_setschedparam(pthread_t, int,
const struct sched_param *);
int pthread_getconcurrency(void);
int pthread_setconcurrency(int);
+int pthread_barrier_init(pthread_barrier_t *,
+ pthread_barrierattr_t *, unsigned int);
+int pthread_barrier_destroy(pthread_barrier_t *);
+int pthread_barrier_wait(pthread_barrier_t *);
+int pthread_barrierattr_init(pthread_barrierattr_t *);
+int pthread_barrierattr_destroy(pthread_barrierattr_t *);
+int pthread_barrierattr_getpshared(pthread_barrierattr_t *, int *);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
__END_DECLS
#endif /* _PTHREAD_H_ */
diff --git a/lib/libpthread/man/Makefile.inc b/lib/libpthread/man/Makefile.inc
index 0ed97110373..de389a96d93 100644
--- a/lib/libpthread/man/Makefile.inc
+++ b/lib/libpthread/man/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.31 2012/03/22 19:44:53 kurt Exp $
+# $OpenBSD: Makefile.inc,v 1.32 2012/04/11 10:18:46 pirofti Exp $
# $FreeBSD: Makefile.inc,v 1.6 1999/08/28 00:03:02 peter Exp $
# POSIX thread man files
@@ -13,6 +13,10 @@ MAN+= \
pthread_attr_setstacksize.3 \
pthread_attr_setguardsize.3 \
pthread_attr_setdetachstate.3 \
+ pthread_barrier_init.3 \
+ pthread_barrier_wait.3 \
+ pthread_barrierattr_init.3 \
+ pthread_barrierattr_getpshared.3 \
pthread_cleanup_pop.3 \
pthread_cleanup_push.3 \
pthread_condattr_init.3 \
@@ -85,6 +89,9 @@ MLINKS+=flockfile.3 funlockfile.3 \
pthread_attr_setstacksize.3 pthread_attr_getstacksize.3 \
pthread_attr_setguardsize.3 pthread_attr_getguardsize.3 \
pthread_attr_setdetachstate.3 pthread_attr_getdetachstate.3 \
+ pthread_barrier_init.3 pthread_barrier_destroy.3 \
+ pthread_barrierattr_init.3 pthread_barrierattr_destroy.3 \
+ pthread_barrierattr_getpshared.3 pthread_barrierattr_setpshared.3 \
pthread_condattr_init.3 pthread_condattr_destroy.3 \
pthread_condattr_init.3 pthread_condattr_setclock.3 \
pthread_condattr_init.3 pthread_condattr_getclock.3 \
diff --git a/lib/libpthread/man/pthread_barrier_init.3 b/lib/libpthread/man/pthread_barrier_init.3
new file mode 100644
index 00000000000..0f2162ac4da
--- /dev/null
+++ b/lib/libpthread/man/pthread_barrier_init.3
@@ -0,0 +1,101 @@
+.\" $OpenBSD: pthread_barrier_init.3,v 1.1 2012/04/11 10:18:46 pirofti Exp $
+.\"
+.\" Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\"
+.Dd $Mdocdate: April 11 2012 $
+.Dt PTHREAD_BARRIER_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_barrier_init ,
+.Nm pthread_barrier_destroy
+.Nd initialize and destroy a barrier object
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_barrier_init "pthread_barrier_t *barrier" "pthread_barrierattr_t *attr" "unsigned int count"
+.Ft int
+.Fn pthread_barrier_destroy "pthread_barrier_t *barrier"
+.Sh DESCRIPTION
+The
+.Fn pthread_barrier_init
+function creates a new barrier object, with attributes specified with
+.Fa attr
+and with a threshold specified with
+.Fa count .
+If
+.Fa attr
+is
+.Dv NULL
+the default attributes are used. The
+.Fa count
+argument is later used by the
+.Fn pthread_barrier_wait
+function to check if the required number of threads reached the barrier.
+.Pp
+The
+.Fn pthread_barrier_destroy
+function frees the resources allocated for
+.Fa barrier .
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_barrier_init
+and
+.Fn pthread_barrier_destroy
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_barrier_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa barrier
+or
+.Fa attr
+is invalid.
+.It Bq Er ENOMEM
+The process cannot allocate enough memory to create another barrier object.
+.It Bq Er ENOTSUP
+The attributes specified by
+.Fa attr
+are not supported by the current implementation.
+.El
+.Pp
+.Fn pthread_barrier_destroy
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa barrier
+is invalid.
+.It Bq Er EBUSY
+There are still threads waiting on the barrier.
+.El
+.Sh SEE ALSO
+.Xr pthread_barrier_wait 3 ,
+.Xr pthread_barrierattr_init 3 ,
+.Xr pthread_barrierattr_getpshared 3
+.Sh STANDARDS
+.Fn pthread_barrier_init
+and
+.Fn pthread_barrier_destroy
+conform to
+.St -p1003.1-2008 .
+.Sh BUGS
+Currently only private barriers are supported and the pshared attribute is
+always set that way.
+Any attempts to change that value will trigger
+.Er ENOTSUP .
diff --git a/lib/libpthread/man/pthread_barrier_wait.3 b/lib/libpthread/man/pthread_barrier_wait.3
new file mode 100644
index 00000000000..e2f66137876
--- /dev/null
+++ b/lib/libpthread/man/pthread_barrier_wait.3
@@ -0,0 +1,57 @@
+.\" $OpenBSD: pthread_barrier_wait.3,v 1.1 2012/04/11 10:18:46 pirofti Exp $
+.\"
+.\" Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\"
+.Dd $Mdocdate: April 11 2012 $
+.Dt PTHREAD_BARRIER_WAIT 3
+.Os
+.Sh NAME
+.Nm pthread_barrier_wait
+.Nd synchornize at a barrier
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_barrier_wait "pthread_barrier_t *barrier"
+.Sh DESCRIPTION
+The
+.Fn pthread_barrier_wait
+function will block the calling thread until the required number of threads
+will call
+.Fn pthread_barrier_wait
+as specified at the object's intialization.
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_barrier_wait
+will return
+.Dv PTHREAD_BARRIER_SERIAL_THREAD
+for a single aribtrary thread and zero for each of the other threads,
+otherwise an error number will be returned to indicate the error.
+.Sh ERRORS
+.Fn pthread_barrier_wait
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa barrier
+is invalid.
+.Sh SEE ALSO
+.Xr pthread_barrier_init 3 ,
+.Xr pthread_barrierattr_init 3 ,
+.Xr pthread_barrierattr_getpshared 3
+.Sh STANDARDS
+.Fn pthread_barrier_wait
+conforms to
+.St -p1003.1-2008 .
diff --git a/lib/libpthread/man/pthread_barrierattr_getpshared.3 b/lib/libpthread/man/pthread_barrierattr_getpshared.3
new file mode 100644
index 00000000000..030a616b3a0
--- /dev/null
+++ b/lib/libpthread/man/pthread_barrierattr_getpshared.3
@@ -0,0 +1,85 @@
+.\" $OpenBSD: pthread_barrierattr_getpshared.3,v 1.1 2012/04/11 10:18:46 pirofti Exp $
+.\"
+.\" Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\"
+.Dd $Mdocdate: April 11 2012 $
+.Dt PTHREAD_BARRIERATTR_GETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_barrierattr_getpshared ,
+.Nm pthread_barrierattr_setpshared
+.Nd get and set the process-shared attribute of the barrier attribute's object
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_barrierattr_getpshared "pthread_barrierattr_t *attr" "int *pshared"
+.Ft int
+.Fn pthread_barrierattr_setpshared "pthread_barrierattr_t *attr" "int pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_barrierattr_getpshared
+function writes in
+.Fa pshared
+the current process-shared attribute value.
+.Pp
+The
+.Fn pthread_barrierattr_setpshared
+function sets the process-shared attribute as indicated in
+.Fa pshared .
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_barrierattr_getpshared
+and
+.Fn pthread_barrierattr_setpshared
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_barrierattr_getpshared
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Pp
+.Fn pthread_barrierattr_setpshared
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.It Bq Er ENOTSUP
+The value specified by
+.Fa pshared
+is not PTHREAD_PROCESS_PRIVATE.
+.El
+.Sh SEE ALSO
+.Xr pthread_barrierattr_init 3
+.Xr pthread_barrier_wait 3 ,
+.Xr pthread_barrier_init 3 ,
+.Sh STANDARDS
+.Fn pthread_barrierattr_getpshared
+and
+.Fn pthread_barrierattr_setpshared
+conform to
+.St -p1003.1-2008 .
+.Sh BUGS
+Currently only private barriers are supported and the pshared attribute is
+always set that way.
+Any attempts to change that value will trigger
+.Er ENOTSUP .
diff --git a/lib/libpthread/man/pthread_barrierattr_init.3 b/lib/libpthread/man/pthread_barrierattr_init.3
new file mode 100644
index 00000000000..ee159897ded
--- /dev/null
+++ b/lib/libpthread/man/pthread_barrierattr_init.3
@@ -0,0 +1,77 @@
+.\" $OpenBSD: pthread_barrierattr_init.3,v 1.1 2012/04/11 10:18:46 pirofti Exp $
+.\"
+.\" Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\"
+.Dd $Mdocdate: April 11 2012 $
+.Dt PTHREAD_BARRIERATTR_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_barrierattr_init ,
+.Nm pthread_barrierattr_destroy
+.Nd initialize and destroy a barrier attribute object
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_barrierattr_init "pthread_barrierattr_t *attr"
+.Ft int
+.Fn pthread_barrierattr_destroy "pthread_barrierattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_barrierattr_init
+function creates a new barrier attribute object.
+.Pp
+The
+.Fn pthread_barrierattr_destroy
+function frees the resources allocated for
+.Fa attr .
+.Sh RETURN VALUES
+If successful,
+.Fn pthread_barrierattr_init
+and
+.Fn pthread_barrierattr_destroy
+will return zero, otherwise an error number will be returned to
+indicate the error.
+.Sh ERRORS
+.Fn pthread_barrierattr_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.It Bq Er ENOMEM
+The process cannot allocate enough memory to create another barrier attribute
+object.
+.El
+.Pp
+.Fn pthread_barrierattr_destroy
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh SEE ALSO
+.Xr pthread_barrierattr_getpshared 3
+.Xr pthread_barrier_wait 3 ,
+.Xr pthread_barrier_init 3 ,
+.Sh STANDARDS
+.Fn pthread_barrierattr_init
+and
+.Fn pthread_barrierattr_destroy
+conform to
+.St -p1003.1-2008 .
diff --git a/lib/librthread/Makefile b/lib/librthread/Makefile
index 90147ff39c7..b36e2c80a2b 100644
--- a/lib/librthread/Makefile
+++ b/lib/librthread/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.28 2012/03/22 00:44:55 guenther Exp $
+# $OpenBSD: Makefile,v 1.29 2012/04/11 10:18:46 pirofti Exp $
# For ``COMPILER_VERSION''
.include <bsd.own.mk>
@@ -20,6 +20,8 @@ LDADD = -Wl,-znodelete,-zinitfirst
.PATH: ${.CURDIR}/arch/${MACHINE_CPU}
SRCS= rthread.c \
rthread_attr.c \
+ rthread_barrier.c \
+ rthread_barrier_attr.c \
rthread_cancel.c \
rthread_condattr.c \
rthread_debug.c \
diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h
index e7f5208d4e4..1ac8c771c65 100644
--- a/lib/librthread/rthread.h
+++ b/lib/librthread/rthread.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.h,v 1.37 2012/03/22 15:26:04 kurt Exp $ */
+/* $OpenBSD: rthread.h,v 1.38 2012/04/11 10:18:46 pirofti Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -122,6 +122,18 @@ struct rthread_cleanup_fn {
struct rthread_cleanup_fn *next;
};
+struct pthread_barrier {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int threshold;
+ int sofar;
+ int generation;
+};
+
+struct pthread_barrierattr {
+ int pshared;
+};
+
struct pthread {
struct sem donesem;
#if TLS_VARIANT == 1
diff --git a/lib/librthread/rthread_barrier.c b/lib/librthread/rthread_barrier.c
new file mode 100644
index 00000000000..f205b0c9f40
--- /dev/null
+++ b/lib/librthread/rthread_barrier.c
@@ -0,0 +1,145 @@
+/* $OpenBSD: rthread_barrier.c,v 1.1 2012/04/11 10:18:46 pirofti Exp $ */
+/*
+ * Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+
+#include "rthread.h"
+
+int
+pthread_barrier_init(pthread_barrier_t *barrier, pthread_barrierattr_t *attr,
+ unsigned int count) {
+ int rc = 0;
+ pthread_barrier_t b = NULL;
+
+ if (barrier == NULL) {
+ return EINVAL;
+ }
+ if (attr != NULL) {
+ if (*attr == NULL) {
+ return EINVAL;
+ }
+ if ((*attr)->pshared != PTHREAD_PROCESS_PRIVATE) {
+ return ENOTSUP;
+ }
+ }
+
+ b = calloc(1, sizeof *b);
+ if (b == NULL) {
+ return ENOMEM;
+ }
+
+ if ((rc = pthread_mutex_init(&b->mutex, NULL))) {
+ goto err;
+ }
+ if ((rc = pthread_cond_init(&b->cond, NULL))) {
+ goto err;
+ }
+
+ b->threshold = count;
+
+ *barrier = b;
+
+ return 0;
+
+err:
+ if (b) {
+ if (b->mutex) {
+ pthread_mutex_destroy(&b->mutex);
+ }
+ if (b->cond) {
+ pthread_cond_destroy(&b->cond);
+ }
+ free(b);
+ }
+ return rc;
+}
+
+int
+pthread_barrier_destroy(pthread_barrier_t *barrier)
+{
+ pthread_barrier_t b;
+
+ if (barrier == NULL || *barrier == NULL) {
+ return EINVAL;
+ }
+
+ b = *barrier;
+
+ if (b->sofar > 0) {
+ return EBUSY;
+ }
+
+ *barrier = NULL;
+ pthread_mutex_destroy(&b->mutex);
+ pthread_cond_destroy(&b->cond);
+ free(b);
+ return 0;
+}
+
+int
+pthread_barrier_wait(pthread_barrier_t *barrier)
+{
+ pthread_barrier_t b;
+ int rc, old_state, gen;
+ int done = 0;
+
+ if (barrier == NULL || *barrier == NULL) {
+ return EINVAL;
+ }
+
+ if ((rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state))) {
+ return rc;
+ }
+
+ b = *barrier;
+ if ((rc = pthread_mutex_lock(&b->mutex))) {
+ goto cancel;
+ }
+
+ _rthread_debug(6, "sofar: %d, threshold: %d\n", b->sofar, b->threshold);
+ if (++b->sofar == b->threshold) {
+ b->sofar = 0;
+ b->generation++;
+ if ((rc = pthread_cond_broadcast(&b->cond))) {
+ goto err;
+ }
+ done = 1;
+ _rthread_debug(6, "threshold reached\n");
+ } else {
+ gen = b->generation;
+ _rthread_debug(6, "waiting on condition\n");
+ do {
+ if ((rc = pthread_cond_wait(&b->cond, &b->mutex))) {
+ goto err;
+ }
+ } while (gen == b->generation);
+ }
+
+err:
+ if ((rc = pthread_mutex_unlock(&b->mutex))) {
+ return rc;
+ }
+cancel:
+ rc = pthread_setcancelstate(old_state, NULL);
+ if (rc == 0 && done) {
+ rc = PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ return rc;
+}
diff --git a/lib/librthread/rthread_barrier_attr.c b/lib/librthread/rthread_barrier_attr.c
new file mode 100644
index 00000000000..54f44ed232c
--- /dev/null
+++ b/lib/librthread/rthread_barrier_attr.c
@@ -0,0 +1,76 @@
+/* $OpenBSD: rthread_barrier_attr.c,v 1.1 2012/04/11 10:18:46 pirofti Exp $ */
+/*
+ * Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+
+#include "rthread.h"
+
+int
+pthread_barrierattr_init(pthread_barrierattr_t *attr)
+{
+ if (attr == NULL) {
+ return EINVAL;
+ }
+
+ *attr = calloc(1, sizeof **attr);
+ if (*attr == NULL) {
+ return ENOMEM;
+ }
+
+ (*attr)->pshared = PTHREAD_PROCESS_PRIVATE;
+
+ return 0;
+}
+
+int
+pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
+{
+ if (attr == NULL || *attr == NULL) {
+ return EINVAL;
+ }
+ free(*attr);
+ return 0;
+}
+
+int
+pthread_barrierattr_getpshared(pthread_barrierattr_t *attr, int *pshared)
+{
+ if (attr == NULL || *attr == NULL) {
+ return EINVAL;
+ }
+ *pshared = (*attr)->pshared;
+ return 0;
+}
+
+int
+pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)
+{
+ if (attr == NULL || *attr == NULL) {
+ return EINVAL;
+ }
+
+ if (pshared != PTHREAD_PROCESS_PRIVATE) {
+ return ENOTSUP;
+ }
+
+ (*attr)->pshared = pshared;
+
+ return 0;
+}