diff options
-rw-r--r-- | lib/libthr/thread/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_barrier.c | 129 | ||||
-rw-r--r-- | lib/libthr/thread/thr_barrierattr.c | 79 | ||||
-rw-r--r-- | lib/libthr/thread/thr_cancel.c | 1 | ||||
-rw-r--r-- | lib/libthr/thread/thr_private.h | 19 | ||||
-rw-r--r-- | lib/libthr/thread/thr_sig.c | 7 | ||||
-rw-r--r-- | share/man/man3/Makefile | 8 | ||||
-rw-r--r-- | share/man/man3/pthread_barrier_destroy.3 | 157 | ||||
-rw-r--r-- | share/man/man3/pthread_barrierattr.3 | 150 |
9 files changed, 551 insertions, 1 deletions
diff --git a/lib/libthr/thread/Makefile.inc b/lib/libthr/thread/Makefile.inc index c43737e..8e11911 100644 --- a/lib/libthr/thread/Makefile.inc +++ b/lib/libthr/thread/Makefile.inc @@ -6,6 +6,8 @@ SRCS+= \ thr_attr.c \ thr_autoinit.c \ + thr_barrier.c \ + thr_barrierattr.c \ thr_cancel.c \ thr_clean.c \ thr_concurrency.c \ diff --git a/lib/libthr/thread/thr_barrier.c b/lib/libthr/thread/thr_barrier.c new file mode 100644 index 0000000..c635820 --- /dev/null +++ b/lib/libthr/thread/thr_barrier.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 2004 Michael Telahun Makonnen <mtm@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 <pthread.h> +#include <stdlib.h> +#include <string.h> + +#include "thr_private.h" + +__weak_reference(_pthread_barrier_destroy, pthread_barrier_destroy); +__weak_reference(_pthread_barrier_init, pthread_barrier_init); +__weak_reference(_pthread_barrier_wait, pthread_barrier_wait); + +int +_pthread_barrier_destroy(pthread_barrier_t *barrier) +{ + if (*barrier == NULL) + return (EINVAL); + if ((*barrier)->b_subtotal > 0) + return (EBUSY); + PTHREAD_ASSERT((*barrier)->b_subtotal == 0, + "barrier count must be zero when destroyed"); + free(*barrier); + *barrier = NULL; + return (0); +} + +int +_pthread_barrier_init(pthread_barrier_t *barrier, + const pthread_barrierattr_t attr, unsigned int count) +{ + if (count < 1) + return (EINVAL); + *barrier = + (struct pthread_barrier *)malloc(sizeof(struct pthread_barrier)); + if (*barrier == NULL) + return (ENOMEM); + memset((void *)*barrier, 0, sizeof(struct pthread_barrier)); + (*barrier)->b_total = count; + TAILQ_INIT(&(*barrier)->b_barrq); + return (0); +} + +int +_pthread_barrier_wait(pthread_barrier_t *barrier) +{ + struct pthread_barrier *b; + struct pthread *ptd; + int error; + + if (*barrier == NULL) + return (EINVAL); + + /* + * Check if threads waiting on the barrier can be released. If + * so, release them and make this last thread the special thread. + */ + error = 0; + b = *barrier; + UMTX_LOCK(&b->b_lock); + if (b->b_subtotal == (b->b_total - 1)) { + TAILQ_FOREACH(ptd, &b->b_barrq, sqe) { + _thread_critical_enter(ptd); + PTHREAD_NEW_STATE(ptd, PS_RUNNING); + TAILQ_REMOVE(&b->b_barrq, ptd, sqe); + ptd->flags |= PTHREAD_FLAGS_BARR_REL; + _thread_critical_exit(ptd); + } + b->b_subtotal = 0; + UMTX_UNLOCK(&b->b_lock); + return (PTHREAD_BARRIER_SERIAL_THREAD); + } + + /* + * More threads need to reach the barrier. Suspend this thread. + */ + _thread_critical_enter(curthread); + TAILQ_INSERT_HEAD(&b->b_barrq, curthread, sqe); + PTHREAD_NEW_STATE(curthread, PS_BARRIER_WAIT); + _thread_critical_exit(curthread); + b->b_subtotal++; + PTHREAD_ASSERT(b->b_subtotal < b->b_total, + "the number of threads waiting at a barrier is too large"); + UMTX_UNLOCK(&b->b_lock); + do { + error = _thread_suspend(curthread, NULL); + if (error == EINTR) { + /* + * Make sure this thread wasn't released from + * the barrier while it was handling the signal. + */ + _thread_critical_enter(curthread); + if ((curthread->flags & PTHREAD_FLAGS_BARR_REL) != 0) { + curthread->flags &= ~PTHREAD_FLAGS_BARR_REL; + _thread_critical_exit(curthread); + error = 0; + break; + } + PTHREAD_NEW_STATE(curthread, PS_BARRIER_WAIT); + _thread_critical_exit(curthread); + } + } while (error == EINTR); + return (error); +} diff --git a/lib/libthr/thread/thr_barrierattr.c b/lib/libthr/thread/thr_barrierattr.c new file mode 100644 index 0000000..2fe3955 --- /dev/null +++ b/lib/libthr/thread/thr_barrierattr.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2004 Michael Telahun Makonnen <mtm@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 <pthread.h> +#include <stdlib.h> + +#include "thr_private.h" + +__weak_reference(_pthread_barrierattr_destroy, pthread_barrierattr_destroy); +__weak_reference(_pthread_barrierattr_init, pthread_barrierattr_init); +__weak_reference(_pthread_barrierattr_getpshared, + pthread_barrierattr_getpshared); +__weak_reference(_pthread_barrierattr_setpshared, + pthread_barrierattr_setpshared); + +int +_pthread_barrierattr_destroy(pthread_barrierattr_t *attr) +{ + if (*attr == NULL) + return (EINVAL); + free(*attr); + *attr = NULL; + return (0); +} + +int +_pthread_barrierattr_init(pthread_barrierattr_t *attr) +{ + *attr = + (pthread_barrierattr_t)malloc(sizeof(struct pthread_barrierattr)); + if ((*attr) == NULL) + return (ENOMEM); + (*attr)->ba_pshared = PTHREAD_PROCESS_PRIVATE; + return (0); +} + +int +_pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared) +{ + if (*attr == NULL) + return (EINVAL); + *pshared = (*attr)->ba_pshared; + return (0); +} + +int +_pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) +{ + if (*attr == NULL || (pshared != PTHREAD_PROCESS_PRIVATE && + pshared != PTHREAD_PROCESS_SHARED)) + return (EINVAL); + (*attr)->ba_pshared = pshared; + return (0); +} diff --git a/lib/libthr/thread/thr_cancel.c b/lib/libthr/thread/thr_cancel.c index d27b4b3..a539de7 100644 --- a/lib/libthr/thread/thr_cancel.c +++ b/lib/libthr/thread/thr_cancel.c @@ -93,6 +93,7 @@ retry: PTHREAD_NEW_STATE(pthread, PS_RUNNING); break; + case PS_BARRIER_WAIT: case PS_MUTEX_WAIT: case PS_COND_WAIT: /* diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index cad1d04..e42bb14 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -146,7 +146,6 @@ PTHREAD_SET_STATE(thrd, newstate); \ } while (0) - /* * TailQ initialization values. */ @@ -368,6 +367,22 @@ extern int _pthread_page_size; */ #define GET_CURRENT_TOD(tv) gettimeofday(&(tv), NULL) +struct pthread_barrierattr { + int ba_pshared; +}; + +/* + * POSIX Threads barrier object. + * Lock order: + * 1. pthread_barrier + * 2. pthread + */ +struct pthread_barrier { + TAILQ_HEAD(barrq_head, pthread) b_barrq; + struct umtx b_lock; + int b_total; + int b_subtotal; +}; struct pthread_rwlockattr { int pshared; @@ -388,6 +403,7 @@ enum pthread_state { PS_RUNNING, PS_MUTEX_WAIT, PS_COND_WAIT, + PS_BARRIER_WAIT, PS_SLEEP_WAIT, /* XXX We need to wrap syscalls to set this state */ PS_WAIT_WAIT, PS_JOIN, @@ -535,6 +551,7 @@ struct pthread { int flags; #define PTHREAD_FLAGS_PRIVATE 0x0001 #define PTHREAD_EXITING 0x0002 +#define PTHREAD_FLAGS_BARR_REL 0x0004 /* has been released from barrier */ #define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/ #define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ #define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */ diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c index 0b8ba2b..771afbc 100644 --- a/lib/libthr/thread/thr_sig.c +++ b/lib/libthr/thread/thr_sig.c @@ -130,6 +130,13 @@ _thread_sig_wrapper(int sig, siginfo_t *info, void *context) * after cleanup handling. */ switch (curthread->state) { + case PS_BARRIER_WAIT: + /* + * XXX - The thread has reached the barrier. We can't + * "back it away" from the barrier. + */ + _thread_critical_enter(curthread); + break; case PS_COND_WAIT: /* * Cache the address, since it will not be available diff --git a/share/man/man3/Makefile b/share/man/man3/Makefile index 8e5df1b..fb9ceb8 100644 --- a/share/man/man3/Makefile +++ b/share/man/man3/Makefile @@ -140,6 +140,8 @@ PTHREAD_MAN= pthread.3 \ pthread_attr.3 \ pthread_attr_get_np.3 \ pthread_attr_setcreatesuspend_np.3 \ + pthread_barrier_destroy.3 \ + pthread_barrierattr.3 \ pthread_cancel.3 \ pthread_cleanup_pop.3 \ pthread_cleanup_push.3 \ @@ -216,6 +218,12 @@ PTHREAD_MLINKS= pthread_attr.3 pthread_attr_destroy.3 \ pthread_attr.3 pthread_attr_setstack.3 \ pthread_attr.3 pthread_attr_setstackaddr.3 \ pthread_attr.3 pthread_attr_setstacksize.3 +PTHREAD_MLINKS+=pthread_barrier_destroy.3 pthread_barrier_init.3 \ + pthread_barrier_destroy.3 pthread_barrier_wait.3 +PTHREAD_MLINKS+=pthread_barrierattr.3 pthread_barrierattr_destroy.3 \ + pthread_barrierattr.3 pthread_barrierattr_getpshared.3 \ + pthread_barrierattr.3 pthread_barrierattr_init.3 \ + pthread_barrierattr.3 pthread_barrierattr_setpshared.3 PTHREAD_MLINKS+=pthread_condattr.3 pthread_condattr_destroy.3 \ pthread_condattr.3 pthread_condattr_init.3 PTHREAD_MLINKS+=pthread_getconcurrency.3 pthread_setconcurrency.3 diff --git a/share/man/man3/pthread_barrier_destroy.3 b/share/man/man3/pthread_barrier_destroy.3 new file mode 100644 index 0000000..27ded5b --- /dev/null +++ b/share/man/man3/pthread_barrier_destroy.3 @@ -0,0 +1,157 @@ +.\" Copyright (c) 2004 Michael Telahun Makonnen +.\" 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$ +.\" +.\" Note: The date here should be updated whenever a non-trivial +.\" change is made to the manual page. +.Dd February 19, 2004 +.Dt PTHREAD_BARRIER_DESTROY 3 PTHREAD_BARRIER_INIT 3 PTHREAD_BARRIER_WAIT 3 +.Os +.Sh NAME +.Nm pthread_barrier_destroy pthread_barrier_init pthread_barrier_wait +.Nd "destroy, initialize or wait on a barrier object" +.Sh LIBRARY +.Lb libpthread +.Lb libthr +.Sh SYNOPSIS +.In pthread.h +.Ft int +.Fn pthread_barrier_destroy "pthread_barrier_t *barrier" +.Ft int +.Fn pthread_barrier_init "pthread_barrier_t *barrier" "const pthread_barrierattr_t *attr" "int count" +.Ft int +.Fn pthread_barrier_wait "pthread_barrier_t *barrier" +.Sh DESCRIPTION +The +.Fn pthread_barrier_init +function will initialize +.Fa barrier +with attributes specified in +.Fa attr , +or if it is NULL, +with default attributes. +The number of threads that must call +.Fn pthread_barrier_wait +before any of the waiting threads can be +released is specified by +.Fa count . +The +.Fn pthread_barrier_destroy +function will destroy +.Fa barrier +and release any resources that may have been allocated on its behalf. +.Pp +The +.Fn pthread_barrier_wait +function will synchronize calling threads at +.Fa barrier . +The threads will be blocked from +making further progress until +a sufficient number of threads calls this function. +The number of threads that must call it before +any of them will be released is determined by the +.Fa count +argument to +.Fn pthread_barrier_init . +Once the threads have been released the barrier will be reset. +.Sh DIAGNOSTICS +If successful, +both +.Fn pthread_barrier_destroy +and +.Fn pthread_barrier_init +will return zero. +Otherwise an error number will be returned to indicate the error. +If the call to +.Fn pthread_barrier_wait +is successful all but one of the threads will return zero. +That one thread will return PTHREAD_BARRIER_SERIAL_THREAD. +Otherwise an error number will be returned to indicate the error. +.Pp +None of these functions will return EINTR. +.Sh IMPLIMENTATION NOTES +In both +.Lb libpthread +and +.Lb libthr +the PTHREAD_BARRIER_SERIAL_THREAD return value will +always be returned by the last thread to reach the barrier. +.Sh ERRORS +The +.Fn pthread_barrier_destroy +function will fail if: +.Bl -tag -width Er +.It Bq Er EBUSY +An attempt was made to destroy +.Fa barrier +while it was in use. +.El +.Pp +The +.Fn pthread_barrier_destroy +and +.Fn pthread_barrier_wait +functions may fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The value specified by +.Fa barrier +is invalid. +.El +.Pp +The +.Fn pthread_barrier_init +function will fail if: +.Bl -tag -width Er +.It Bq Er EAGAIN +The system lacks resources, +other than memory, +to initialize +.Fa barrier . +.It Bq Er EINVAL +The +.Fa count +argument is less than 1. +.It Bq Er ENOMEM +Insufficient memory to initialize +.Fa barrier . +.El +.Sh SEE ALSO +.Xr pthread_barrier_wait 3 , +.Xr pthread_barrierattr 3 +.Sh HISTORY +The +.Fn pthread_barrier_destroy , +.Fn pthread_barrier_init +and +.Fn pthread_barrier_wait +functions first appeared in +.Lb libpthread +in +.Fx 5.2 , +and in +.Lb libthr +in +.Fx 5.3 . diff --git a/share/man/man3/pthread_barrierattr.3 b/share/man/man3/pthread_barrierattr.3 new file mode 100644 index 0000000..2931bdf --- /dev/null +++ b/share/man/man3/pthread_barrierattr.3 @@ -0,0 +1,150 @@ +.\" Copyright (c) 2004 Michael Telahun Makonnen +.\" 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$ +.\" +.\" Note: The date here should be updated whenever a non-trivial +.\" change is made to the manual page. +.Dd February 19, 2004 +.Dt PTHREAD_BARRIERATTR_DESTROY 3 PTHREAD_BARRIERATTR_GETPSHARED 3 PTHREAD_BARRIERATTR_INIT 3 PTHREAD_BARRIERATTR_SETPSHARED 3 +.Os +.Sh NAME +.Nm pthread_barrierattr_destroy pthread_barrierattr_getpshared +.Nm pthread_barrierattr_init pthread_barrierattr_setpshared +.Nd "manipulate a barrier attribute object" +.Sh LIBRARY +.Lb libpthread +.Lb libthr +.Sh SYNOPSIS +.In pthread.h +.Ft int +.Fn pthread_barrierattr_destroy "pthread_barrierattr_t *attr" +.Ft int +.Fn pthread_barrierattr_getpshared "const pthread_barrierattr_t *attr" "int *pshared" +.Ft int +.Fn pthread_barrierattr_init "pthread_barrierattr_t *attr" +.Ft int +.Fn pthread_barrierattr_setpshared "pthread_barrierattr_t *attr" "int pshared" +.Sh DESCRIPTION +The +.Fn pthread_barrierattr_init +function will initialize +.Fa attr +with default attributes. +The +.Fn pthread_barrierattr_destroy +function will destroy +.Fa attr +and release any resources that may have been allocated on its behalf. +.Pp +The +.Fn pthread_barrierattr_getpshared +function will put the value of the process-shared attribute from +.Fa attr +into the memory area pointed to by +.Fa pshared . +The +.Fn pthread_barrierattr_setpshared +function will set the process-shared attribute of +.Fa attr +to the value specified in +.Fa pshared. +The argument +.Fa pshared +may have one of the following values: +.Bl -tag -width ".Dv PTHREAD_PROCESS_PRIVATE" +.It Dv PTHREAD_PROCESS_PRIVATE +The barrier object it is attached to may only be accessed by +threads in the same process as the one that created the object. +.It Dv PTHREAD_PROCESS_SHARED +The barrier object it is attached to may be accessed by +threads in processes other than the one that created the object. +.El +.Sh DIAGNOSTICS +If successful all these functions will return zero. +Otherwise an error number will be returned to indicate the error. +.Pp +None of these functions will return EINTR. +.Pp +.Sh ERRORS +The +.Fn pthread_barrierattr_destroy , +.Fn pthread_barrierattr_getpshared +and +.Fn pthread_barrierattr_setpshared +functions may fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The value specified by +.Fa attr +is invalid. +.El +.Pp +The +.Fn pthread_barrierattr_init +function will fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +Insufficient memory to initialize the barrier attribute object +.Fa attr . +.El +.Pp +The +.Fn pthread_barrierattr_setpshared +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The value specified in +.Fa pshared +is not one of the allowed values. +.El +.Sh SEE ALSO +.Xr pthread_barrier_destroy 3 , +.Xr pthread_barrier_init 3 , +.Xr pthread_barrier_wait 3 , +.Sh HISTORY +The +.Fn pthread_barrierattr +functions first appeared in +.Lb libpthread +in +.Fx 5.2 , +and in +.Lb libthr +in +.Fx 5.3 . +.Sh BUGS +The implementation of +.Fn pthread_barriers +does not fully conform to +.St -p1003.2 +because the process-shared attribute is ignored in +.Lb libthr , +and in +.Lb libpthread +if any value other than +.Dv PTHREAD_PROCESSES_PRIVATE +is specified in a call to +.Fn pthread_barrierattr_setpshared +it will return EINVAL. |