pthread yet again

This commit is contained in:
2017-05-12 17:53:28 +00:00
parent d5e4fc0151
commit aa2076a2eb
83 changed files with 14283 additions and 0 deletions

245
lib/libpthread/Makefile Normal file
View File

@@ -0,0 +1,245 @@
# $NetBSD: Makefile,v 1.85 2014/12/16 20:05:54 pooka Exp $
#
WARNS?= 5
LIB= pthread
.include <bsd.own.mk>
.if defined(PTHREAD_MACHINE_ARCH) && !empty(PTHREAD_MACHINE_ARCH) && \
exists(${.CURDIR}/arch/${PTHREAD_MACHINE_ARCH})
ARCHSUBDIR= ${PTHREAD_MACHINE_ARCH}
.elif defined(PTHREAD_MACHINE_CPU) && !empty(PTHREAD_MACHINE_CPU) && \
exists(${.CURDIR}/arch/${PTHREAD_MACHINE_CPU})
ARCHSUBDIR= ${PTHREAD_MACHINE_CPU}
.elif exists(${.CURDIR}/arch/${MACHINE_ARCH})
ARCHSUBDIR= ${MACHINE_ARCH}
.elif exists(${.CURDIR}/arch/${MACHINE_CPU})
ARCHSUBDIR= ${MACHINE_CPU}
.else
.BEGIN:
@echo "WARNING: no ARCHSUBDIR for ${MACHINE_ARCH}/${MACHINE_CPU}; skipping..."
.endif
INCS= pthread.h pthread_types.h pthread_queue.h
INCSDIR=/usr/include
.if defined(ARCHSUBDIR)
ARCHDIR= ${.CURDIR}/arch/${ARCHSUBDIR}
.PATH: ${ARCHDIR}
CPPFLAGS+= -I${ARCHDIR} -I${.CURDIR} -I${.OBJDIR} -D_LIBC -D_REENTRANT
CPPFLAGS+= -I${.CURDIR}/../libc/include
CPPFLAGS+= -D__LIBPTHREAD_SOURCE__ -D__LIBC_THREAD_STUBS
# XXX: This crappy poke at libc's internals needs to be fixed.
CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${.CURDIR}/../libc
# providing alternative MI implementations for creating an lwp is
# possible by setting PTHREAD_MAKELWP. Currently, alternatives are
# set by the rumprun software stacks (see repo.rumpkernel.org)
PTHREAD_MAKELWP?= pthread_makelwp_netbsd.c
#
# NOTE: When you create a new file for libpthread, make sure that pthread.c
# gets a reference to a symbol in that file. Otherwise, Unix's stupid static
# library semantics will end up discarding potentially important objects.
#
SRCS= pthread.c
SRCS+= pthread_attr.c
SRCS+= pthread_barrier.c
# used by rumprun-posix to work around symbol collisions
.if ${PTHREAD_CANCELSTUB:Uyes} != "no"
SRCS+= pthread_cancelstub.c
.endif
SRCS+= pthread_cond.c
SRCS+= pthread_lock.c
SRCS+= ${PTHREAD_MAKELWP}
SRCS+= pthread_misc.c
SRCS+= pthread_mutex.c
SRCS+= pthread_once.c
SRCS+= pthread_rwlock.c
SRCS+= pthread_specific.c
SRCS+= pthread_spin.c
SRCS+= pthread_tsd.c
SRCS+= res_state.c
SRCS+= sem.c
# Architecture-dependent files
.if exists(${ARCHDIR}/pthread_md.S)
SRCS+= pthread_md.S
.endif
.if exists(${ARCHDIR}/Makefile.inc)
.include "${ARCHDIR}/Makefile.inc"
.endif
# The PTHREAD__COMPAT flag builds a libpthread that can be dropped
# into a NetBSD 2/3/4 chroot with a NetBSD 5 or later kernel.
# This makes threading work in the chroot, no other modifications
# required.
#
.if defined(PTHREAD__COMPAT)
SRCS+= pthread_compat.c
.PATH.c: ${.CURDIR}/../../common/lib/libc/arch/${ARCHSUBDIR}/atomic
.PATH.S: ${.CURDIR}/../../common/lib/libc/arch/${ARCHSUBDIR}/atomic
.PATH.c: ${.CURDIR}/../../common/lib/libc/atomic
.PATH.c: ${.CURDIR}/../libc/misc
.include "../../common/lib/libc/arch/${ARCHSUBDIR}/atomic/Makefile.inc"
.endif
ALIGN_FUNCTIONS= ${${ACTIVE_CC} == "gcc":? -falign-functions=32 :}
.if ${MACHINE_CPU} != "m68k" && ${MACHINE_CPU} != "sh3" && ${MACHINE_ARCH} != "vax"
OMIT_FRAME_POINTER= -fomit-frame-pointer
.else
OMIT_FRAME_POINTER=
.endif
# The TSD routines are used in the implementation of profiling, and so
# can't be profiled themselves.
COPTS.pthread_specific.c+= ${OMIT_FRAME_POINTER} ${ALIGN_FUNCTIONS}
pthread_specific.po: pthread_specific.o
${_MKTARGET_CREATE}
cp pthread_specific.o pthread_specific.po
# Internal spinlock routines are performance critical. Don't profile them,
# it's incompatibile with -fomit-frame-pointer.
COPTS.pthread_lock.c+= ${OMIT_FRAME_POINTER} ${ALIGN_FUNCTIONS}
pthread_lock.po: pthread_lock.o
${_MKTARGET_CREATE}
cp pthread_lock.o pthread_lock.po
COPTS.pthread_mutex.c+= ${OMIT_FRAME_POINTER} ${ALIGN_FUNCTIONS}
pthread_mutex.po: pthread_mutex.o
${_MKTARGET_CREATE}
cp pthread_mutex.o pthread_mutex.po
COPTS.pthread.c += -Wno-stack-protector -Wno-format-nonliteral
COPTS.pthread_attr.c += -Wno-format-nonliteral
MAN+= affinity.3 pthread.3 \
pthread_attr.3 \
pthread_attr_get_np.3 \
pthread_attr_getdetachstate.3 \
pthread_attr_getguardsize.3 \
pthread_attr_getinheritsched.3 \
pthread_attr_getname_np.3 \
pthread_attr_getschedparam.3 \
pthread_attr_getscope.3 \
pthread_attr_getstack.3 \
pthread_attr_setcreatesuspend_np.3 \
pthread_barrier.3 pthread_barrierattr.3 \
pthread_cancel.3 pthread_cleanup_push.3 \
pthread_cond.3 pthread_condattr.3 \
pthread_create.3 pthread_detach.3 pthread_equal.3 \
pthread_curcpu_np.3 \
pthread_exit.3 \
pthread_getname_np.3 \
pthread_getspecific.3 pthread_join.3 \
pthread_key_create.3 pthread_kill.3 \
pthread_mutex.3 pthread_mutexattr.3 \
pthread_once.3 pthread_rwlock.3 pthread_rwlockattr.3 \
pthread_schedparam.3 pthread_self.3 \
pthread_sigmask.3 pthread_spin.3 \
pthread_suspend_np.3 pthread_testcancel.3
MLINKS+= pthread_attr_get_np.3 pthread_getattr_np.3
MLINKS+= affinity.3 pthread_setaffinity_np.3
MLINKS+= affinity.3 pthread_getaffinity_np.3
MLINKS+= pthread_attr.3 pthread_attr_init.3
MLINKS+= pthread_attr.3 pthread_attr_destroy.3
MLINKS+= pthread_attr_getdetachstate.3 pthread_attr_setdetachstate.3
MLINKS+= pthread_attr_getguardsize.3 pthread_attr_setguardsize.3
MLINKS+= pthread_attr_getinheritsched.3 pthread_attr_setinheritsched.3
MLINKS+= pthread_attr_getname_np.3 pthread_attr_setname_np.3
MLINKS+= pthread_attr_getschedparam.3 pthread_attr_setschedparam.3 \
pthread_attr_getschedparam.3 pthread_attr_getschedpolicy.3 \
pthread_attr_getschedparam.3 pthread_attr_setschedpolicy.3
MLINKS+= pthread_attr_getscope.3 pthread_attr_setscope.3
MLINKS+= pthread_attr_getstack.3 pthread_attr_setstack.3 \
pthread_attr_getstack.3 pthread_attr_getstacksize.3 \
pthread_attr_getstack.3 pthread_attr_setstacksize.3 \
pthread_attr_getstack.3 pthread_attr_getstackaddr.3 \
pthread_attr_getstack.3 pthread_attr_setstackaddr.3
MLINKS+= pthread_cleanup_push.3 pthread_cleanup_pop.3
MLINKS+= pthread_barrier.3 pthread_barrier_init.3
MLINKS+= pthread_barrier.3 pthread_barrier_destroy.3
MLINKS+= pthread_barrier.3 pthread_barrier_wait.3
MLINKS+= pthread_barrierattr.3 pthread_barrierattr_init.3
MLINKS+= pthread_barrierattr.3 pthread_barrierattr_destroy.3
MLINKS+= pthread_cond.3 pthread_cond_init.3
MLINKS+= pthread_cond.3 pthread_cond_destroy.3
MLINKS+= pthread_cond.3 pthread_cond_broadcast.3
MLINKS+= pthread_cond.3 pthread_cond_wait.3
MLINKS+= pthread_cond.3 pthread_cond_signal.3
MLINKS+= pthread_cond.3 pthread_cond_timedwait.3
MLINKS+= pthread_condattr.3 pthread_condattr_init.3
MLINKS+= pthread_condattr.3 pthread_condattr_destroy.3
MLINKS+= pthread_condattr.3 pthread_condattr_setclock.3
MLINKS+= pthread_getname_np.3 pthread_setname_np.3
MLINKS+= pthread_getspecific.3 pthread_setspecific.3
MLINKS+= pthread_key_create.3 pthread_key_delete.3
MLINKS+= pthread_mutex.3 pthread_mutex_init.3
MLINKS+= pthread_mutex.3 pthread_mutex_destroy.3
MLINKS+= pthread_mutex.3 pthread_mutex_lock.3
MLINKS+= pthread_mutex.3 pthread_mutex_trylock.3
MLINKS+= pthread_mutex.3 pthread_mutex_unlock.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_init.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_destroy.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_settype.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_gettype.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_init.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_destroy.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_rdlock.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_wrlock.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_unlock.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_timedrdlock.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_timedwrlock.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_tryrdlock.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_trywrlock.3
MLINKS+= pthread_rwlockattr.3 pthread_rwlockattr_init.3
MLINKS+= pthread_rwlockattr.3 pthread_rwlockattr_destroy.3
MLINKS+= pthread_spin.3 pthread_spin_init.3
MLINKS+= pthread_spin.3 pthread_spin_destroy.3
MLINKS+= pthread_spin.3 pthread_spin_lock.3
MLINKS+= pthread_spin.3 pthread_spin_trylock.3
MLINKS+= pthread_spin.3 pthread_spin_unlock.3
MLINKS+= pthread_schedparam.3 pthread_setschedparam.3
MLINKS+= pthread_schedparam.3 pthread_getschedparam.3
MLINKS+= pthread_suspend_np.3 pthread_resume_np.3
MLINKS+= pthread_testcancel.3 pthread_setcancelstate.3
MLINKS+= pthread_testcancel.3 pthread_setcanceltype.3
.include <bsd.lib.mk>
.else
.include <bsd.man.mk>
.include <bsd.files.mk>
.include <bsd.inc.mk>
.endif
# WARNS=2 sets -Wcast-qual. This causes problems for one of
# pthread_setspecific() and pthread_getspecific(), since the constness
# of the argument to setspecific() has to be discarded *somewhere*
# before returning it from getspecific().
CWARNFLAGS+= -Wno-cast-qual

9
lib/libpthread/README Normal file
View File

@@ -0,0 +1,9 @@
$NetBSD: README,v 1.6 2009/04/16 18:37:30 wiz Exp $
When making changes to libpthread, please ensure that libpthread_dbg
still compiles.
Due to limitations in the current pthread implementation, makecontext(3)
and sigaltstack(2) should not be used in programs which link against
libpthread (whether threads are used or not). This has been noted in the
makecontext(3), sigaltstack(2), and pthread(3) man pages.

12
lib/libpthread/TODO Normal file
View File

@@ -0,0 +1,12 @@
$NetBSD: TODO,v 1.17 2012/02/03 21:11:17 joerg Exp $
Interfaces/features to implement:
- Realtime extensions: priority inheritance.
- Allow threads to change their stack size.
- Allow threads to modify the red zone size; cf. pthread_attr_setguardsize(3).
- Keep a pool of dead LWPs so that we do not have take the full hit of
_lwp_create() every time pthread_create() is called.

140
lib/libpthread/affinity.3 Normal file
View File

@@ -0,0 +1,140 @@
.\" $NetBSD: affinity.3,v 1.8 2011/12/05 10:27:40 wiz Exp $
.\"
.\" Copyright (c) 2008 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Mindaugas Rasiukevicius <rmind at NetBSD org>.
.\"
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd December 4, 2011
.Dt AFFINITY 3
.Os
.Sh NAME
.Nm pthread_setaffinity_np ,
.Nm pthread_getaffinity_np
.Nd affinity of threads
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.In sched.h
.Ft int
.Fn pthread_setaffinity_np "pthread_t thread" "size_t size" "cpuset_t *set"
.Ft int
.Fn pthread_getaffinity_np "pthread_t thread" "size_t size" "cpuset_t *set"
.Sh DESCRIPTION
Thread affinity allows to run the thread on specified CPU or CPUs only.
.Pp
The
.Fn pthread_setaffinity_np
function sets the affinity mask
.Fa set
for
.Fa thread .
At least one valid CPU must be set in the mask.
.Pp
The
.Fn pthread_getaffinity_np
function gets the affinity mask of
.Fa thread
into
.Fa set .
Note that
.Fa set
must be created and initialized using the
.Xr cpuset 3
functions.
.Sh IMPLEMENTATION NOTES
Setting CPU
.Nm
requires super-user privileges.
Ordinary users can be allowed to control CPU affinity
of their threads via the
.Pa security.models.extensions.user_set_cpu_affinity
.Xr sysctl 7 .
See
.Xr secmodel_extensions 9 .
.Pp
Portable applications should not use the
.Fn pthread_setaffinity_np
and
.Fn pthread_getaffinity_np
functions.
.Sh RETURN VALUES
The
.Fn pthread_setaffinity_np
and
.Fn pthread_getaffinity_np
functions return 0 on success.
Otherwise, an error number is returned to indicate the error.
.Sh EXAMPLES
An example of code fragment, which sets the affinity for the current
thread to the CPU whose ID is 0:
.Bd -literal
cpuset_t *cset;
pthread_t pth;
cpuid_t ci;
cset = cpuset_create();
if (cset == NULL) {
err(EXIT_FAILURE, "cpuset_create");
}
ci = 0;
cpuset_set(ci, cset);
pth = pthread_self();
error = pthread_setaffinity_np(pth, cpuset_size(cset), cset);
if (error) {
...
}
cpuset_destroy(cset);
.Ed
.Sh COMPATIBILITY
Both functions are non-standard extensions.
.Sh ERRORS
Both functions may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The specified
.Fa set
was invalid.
.It Bq Er EPERM
The calling process lacks the appropriate privileges to perform
the operation.
.It Bq Er ESRCH
No thread could be found corresponding to the one specified by
.Fa thread .
.El
.Sh NOTES
There is an alternative processor sets interface, see
.Xr pset 3 .
However, thread affinity and processor sets are mutually exclusive,
hence mixing of these interfaces is prohibited.
.Sh SEE ALSO
.Xr cpuset 3 ,
.Xr pset 3 ,
.Xr pthread_getschedparam 3 ,
.Xr pthread_setschedparam 3 ,
.Xr sched 3 ,
.Xr schedctl 8

View File

@@ -0,0 +1,57 @@
/* $NetBSD: pthread_md.h,v 1.1 2014/08/10 05:47:37 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_AARCH64_MD_H
#define _LIB_PTHREAD_AARCH64_MD_H
static inline uintptr_t
pthread__sp(void)
{
uintptr_t ret;
__asm __volatile("mov %0, sp" : "=r" (ret));
return ret;
}
#define pthread__smt_pause() __asm __volatile("wfe") /* wfe */
#define pthread__smt_wake() __asm __volatile("sev") /* sev */
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_SPSR] = 0;
#endif /* _LIB_PTHREAD_AARCH64_MD_H */

View File

@@ -0,0 +1,57 @@
/* $NetBSD: pthread_md.S,v 1.1 2009/05/18 13:03:35 njoly Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nick Hudson.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
.align 2
LEAF(pthread__ras_simple_lock_init, 1)
stl zero, 0(a0)
nop
RET
END(pthread__ras_simple_lock_init)
.align 2
LEAF(pthread__ras_simple_lock_try, 1)
ldiq t0, 1
pthread__lock_ras_start: .globl pthread__lock_ras_start
ldl v0, 0(a0)
stl t0, 0(a0)
pthread__lock_ras_end: .globl pthread__lock_ras_end
cmpeq v0, 0, v0
RET
END(pthread__ras_simple_lock_try)
.align 2
LEAF(pthread__ras_simple_unlock, 1)
stl zero, 0(a0)
nop
RET
END(pthread__ras_simple_unlock)

View File

@@ -0,0 +1,57 @@
/* $NetBSD: pthread_md.h,v 1.7 2011/01/25 19:12:04 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_ALPHA_MD_H
#define _LIB_PTHREAD_ALPHA_MD_H
#define PTHREAD__ASM_RASOPS
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("mov $30, %0" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
* 0x0008 is ALPHA_PSL_USERSET from arch/alpha/include/alpha_cpu.h
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_PS] = 0x0008;
#endif /* _LIB_PTHREAD_ALPHA_MD_H */

View File

@@ -0,0 +1,80 @@
/* $NetBSD: pthread_md.h,v 1.9 2013/08/15 22:37:29 matt Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
#ifndef _LIB_PTHREAD_ARM_MD_H
#define _LIB_PTHREAD_ARM_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm volatile("mov %0, sp"
: "=r" (ret));
return (ret);
}
#if defined(__thumb__) && defined(_ARM_ARCH_6)
#define pthread__smt_pause() __asm __volatile(".inst.n 0xbf20") /* wfe */
#define pthread__smt_wake() __asm __volatile(".inst.n 0xbf40") /* sev */
#elif !defined(__thumb__)
#define pthread__smt_pause() __asm __volatile(".inst 0xe320f002") /* wfe */
#define pthread__smt_wake() __asm __volatile(".inst 0xe320f004") /* sev */
#else
#define pthread__smt_pause()
#define pthread__smt_wake()
#endif
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
*/
#ifdef __APCS_26__
#define _INITCONTEXT_U_MD(ucp) \
/* Set R15_MODE_USR in the PC */ \
(ucp)->uc_mcontext.__gregs[_REG_PC] = \
((ucp)->uc_mcontext.__gregs[_REG_PC] & 0x3fffffc) | 0x0;
#else
/* Set CPSR to PSR_USE32_MODE (0x10) from arm/armreg.h */
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_CPSR] = 0x10;
#endif
#endif /* _LIB_PTHREAD_ARM_MD_H */

View File

@@ -0,0 +1,67 @@
/* $NetBSD: pthread_md.S,v 1.1 2009/05/16 22:20:40 ad Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Wayne Knowles
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
LEAF_ENTRY(pthread__ras_simple_lock_init)
ldi 1,%ret0 /* 1 == unlocked */
stw %ret0,0(%arg0)
stw %ret0,4(%arg0)
stw %ret0,8(%arg0)
stw %ret0,12(%arg0)
bv,n %r0(%rp)
EXIT(pthread__ras_simple_lock_init)
.global pthread__lock_ras_start
.global pthread__lock_ras_end
LEAF_ENTRY(pthread__ras_simple_lock_try)
ldo 15(%arg0),%arg0
depi 0,31,4,%arg0
pthread__lock_ras_start:
ldw 0(%arg0),%ret0
stw %r0,0(%arg0) /* 0 == locked */
pthread__lock_ras_end:
comiclr,= 0,%ret0,%ret0 /* if locked return 0 */
ldi 1,%ret0 /* else return 1 */
bv,n %r0(%rp)
EXIT(pthread__ras_simple_lock_try)
LEAF_ENTRY(pthread__ras_simple_unlock)
ldo 15(%arg0),%arg0
depi 0,31,4,%arg0
ldi 1,%ret0 /* 1 == unlocked */
bv %r0(%rp)
stw %ret0,0(%arg0)
EXIT(pthread__ras_simple_unlock)

View File

@@ -0,0 +1,64 @@
/* $NetBSD: pthread_md.h,v 1.8 2011/01/25 19:12:05 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_HPPA_MD_H
#define _LIB_PTHREAD_HPPA_MD_H
#include <machine/frame.h>
#define PTHREAD__ASM_RASOPS
static inline unsigned long
pthread__sp(void)
{
register unsigned long sp __asm("r30");
return sp;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_PSW] = 0x4000f;
/*
* Usable stack space below the ucontext_t.
*/
#define STACKSPACE (HPPA_FRAME_SIZE)
/* Don't need additional memory barriers. */
#define PTHREAD__ATOMIC_IS_MEMBAR
#endif /* !_LIB_PTHREAD_HPPA_MD_H */

View File

@@ -0,0 +1,94 @@
/* $NetBSD: pthread_md.h,v 1.20 2012/03/02 23:19:47 joerg Exp $ */
/*-
* Copyright (c) 2001, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams, and by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_I386_MD_H
#define _LIB_PTHREAD_I386_MD_H
#include <sys/ucontext.h>
#include <ucontext.h>
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("movl %%esp, %0" : "=g" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_UESP])
static inline void
_initcontext_u_md(ucontext_t *ucp)
{
__asm ("pushfl; popl %0" : "=a" (ucp->uc_mcontext.__gregs[_REG_EFL]));
__asm ("pushl %%cs; popl %0" : "=a" (ucp->uc_mcontext.__gregs[_REG_CS]));
__asm ("movl %%ds, %0" : "=a" (ucp->uc_mcontext.__gregs[_REG_DS]));
__asm ("movl %%es, %0" : "=a" (ucp->uc_mcontext.__gregs[_REG_ES]));
__asm ("movl %%fs, %0" : "=a" (ucp->uc_mcontext.__gregs[_REG_FS]));
__asm ("movl %%gs, %0" : "=a" (ucp->uc_mcontext.__gregs[_REG_GS]));
__asm ("movl %%ss, %0" : "=a" (ucp->uc_mcontext.__gregs[_REG_SS]));
}
#define _INITCONTEXT_U_MD(ucp) _initcontext_u_md(ucp);
#define pthread__smt_pause() __asm __volatile("rep; nop" ::: "memory")
/* Don't need additional memory barriers. */
#define PTHREAD__ATOMIC_IS_MEMBAR
static inline void *
_atomic_cas_ptr(volatile void *ptr, void *old, void *new)
{
volatile uintptr_t *cast = ptr;
void *ret;
__asm __volatile ("lock; cmpxchgl %2, %1"
: "=a" (ret), "=m" (*cast)
: "r" (new), "m" (*cast), "0" (old));
return ret;
}
static inline void *
_atomic_cas_ptr_ni(volatile void *ptr, void *old, void *new)
{
volatile uintptr_t *cast = ptr;
void *ret;
__asm __volatile ("cmpxchgl %2, %1"
: "=a" (ret), "=m" (*cast)
: "r" (new), "m" (*cast), "0" (old));
return ret;
}
#endif /* _LIB_PTHREAD_I386_MD_H */

View File

@@ -0,0 +1,45 @@
/* $NetBSD: pthread_md.h,v 1.1 2015/04/17 13:14:19 martin Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_IA64_MD_H
#define _LIB_PTHREAD_IA64_MD_H
// #define PTHREAD__ASM_RASOPS
static inline unsigned long
pthread__sp(void)
{
return 0;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
#endif /* _LIB_PTHREAD_IA64_MD_H */

View File

@@ -0,0 +1,49 @@
/* $NetBSD: pthread_md.h,v 1.8 2011/01/25 19:12:05 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_M68K_MD_H
#define _LIB_PTHREAD_M68K_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("movl %%sp, %0" : "=g" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_A7])
/* m68k will not go SMP */
#define PTHREAD__ATOMIC_IS_MEMBAR
#endif /* _LIB_PTHREAD_M68K_MD_H */

View File

@@ -0,0 +1,47 @@
/* $NetBSD: pthread_md.h,v 1.9 2011/01/25 19:12:05 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_MIPS_MD_H
#define _LIB_PTHREAD_MIPS_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("move %0, $sp" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
#endif /* !_LIB_PTHREAD_MIPS_MD_H */

View File

@@ -0,0 +1,47 @@
/* $NetBSD: pthread_md.h,v 1.1 2014/09/03 19:34:26 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_OR1K_MD_H
#define _LIB_PTHREAD_OR1K_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("l.ori %0, r0, 0" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[1])
#endif /* _LIB_PTHREAD_OR1K_MD_H */

View File

@@ -0,0 +1,61 @@
/* $NetBSD: pthread_md.h,v 1.7 2011/01/25 19:12:05 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Allen Briggs for Wasabi Systems, Inc.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
#ifndef _LIB_PTHREAD_POWERPC_MD_H
#define _LIB_PTHREAD_POWERPC_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("mr %0,1" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[1])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
* 0xd032 is PSL_USERSET from arch/powerpc/include/psl.h
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_MSR] = 0xd032;
#endif /* _LIB_PTHREAD_POWERPC_MD_H */

View File

@@ -0,0 +1,47 @@
/* $NetBSD: pthread_md.h,v 1.2 2015/03/31 01:36:27 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_RISCV_MD_H
#define _LIB_PTHREAD_RISCV_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("move\t%0, sp" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
#endif /* _LIB_PTHREAD_RISCV_MD_H */

View File

@@ -0,0 +1,62 @@
/* $NetBSD: pthread_md.h,v 1.8 2011/01/25 19:12:06 christos Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
#ifndef _LIB_PTHREAD_SH3_MD_H
#define _LIB_PTHREAD_SH3_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("mov r15, %0" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_R15])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_SR] = 0;
/* sh3 will not go SMP */
#define PTHREAD__ATOMIC_IS_MEMBAR
#endif /* _LIB_PTHREAD_SH3_MD_H */

View File

@@ -0,0 +1,50 @@
/* $NetBSD: pthread_md.h,v 1.8 2011/01/25 19:12:06 christos Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_SPARC_MD_H
#define _LIB_PTHREAD_SPARC_MD_H
/*
* pthread__sp used for identifying thread
*/
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("mov %%sp, %0" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_O6])
/* Don't need additional memory barriers. */
#define PTHREAD__ATOMIC_IS_MEMBAR
#endif /* _LIB_PTHREAD_SPARC_MD_H */

View File

@@ -0,0 +1,47 @@
/* $NetBSD: pthread_md.h,v 1.7 2011/01/25 19:12:06 christos Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_SPARC64_MD_H
#define _LIB_PTHREAD_SPARC64_MD_H
/*
* pthread__sp used for identifying thread
*/
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("mov %%sp, %0" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_O6])
#endif /* _LIB_PTHREAD_SPARC64_MD_H */

View File

@@ -0,0 +1,58 @@
/* $NetBSD: pthread_md.h,v 1.8 2011/01/25 19:12:06 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_VAX_MD_H
#define _LIB_PTHREAD_VAX_MD_H
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("movl %%sp,%0" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_SP])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
* 0x03c00000 is PSL_U|PSL_PREVU from arch/vax/include/psl.h
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_PSL] = 0x03c00000;
/* Don't need additional memory barriers. */
#define PTHREAD__ATOMIC_IS_MEMBAR
#endif /* _LIB_PTHREAD_VAX_MD_H */

View File

@@ -0,0 +1,97 @@
/* $NetBSD: pthread_md.h,v 1.12 2011/01/25 19:12:06 christos Exp $ */
/*-
* Copyright (c) 2001, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*
* Adapted for x86_64 by fvdl@NetBSD.org
*/
#ifndef _LIB_PTHREAD_X86_64_MD_H
#define _LIB_PTHREAD_X86_64_MD_H
#include <sys/ucontext.h>
static inline unsigned long
pthread__sp(void)
{
unsigned long ret;
__asm("movq %%rsp, %0" : "=g" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[_REG_URSP])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
* 0x23 is GSEL(GUDATA_SEL, SEL_UPL), and
* 0x1b is GSEL(GUCODE_SEL, SEL_UPL).
* 0x202 is PSL_USERSET.
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_GS] = 0x23, \
(ucp)->uc_mcontext.__gregs[_REG_FS] = 0x23, \
(ucp)->uc_mcontext.__gregs[_REG_ES] = 0x23, \
(ucp)->uc_mcontext.__gregs[_REG_DS] = 0x23, \
(ucp)->uc_mcontext.__gregs[_REG_CS] = 0x1b, \
(ucp)->uc_mcontext.__gregs[_REG_SS] = 0x23, \
(ucp)->uc_mcontext.__gregs[_REG_RFL] = 0x202;
#define pthread__smt_pause() __asm __volatile("rep; nop" ::: "memory")
/* Don't need additional memory barriers. */
#define PTHREAD__ATOMIC_IS_MEMBAR
static inline void *
_atomic_cas_ptr(volatile void *ptr, void *old, void *new)
{
volatile uintptr_t *cast = ptr;
void *ret;
__asm __volatile ("lock; cmpxchgq %2, %1"
: "=a" (ret), "=m" (*cast)
: "r" (new), "m" (*cast), "0" (old));
return ret;
}
static inline void *
_atomic_cas_ptr_ni(volatile void *ptr, void *old, void *new)
{
volatile uintptr_t *cast = ptr;
void *ret;
__asm __volatile ("cmpxchgq %2, %1"
: "=a" (ret), "=m" (*cast)
: "r" (new), "m" (*cast), "0" (old));
return ret;
}
#endif /* _LIB_PTHREAD_X86_64_MD_H */

178
lib/libpthread/pthread.3 Normal file
View File

@@ -0,0 +1,178 @@
.\" $NetBSD: pthread.3,v 1.14 2010/05/16 12:23:32 jruoho Exp $
.\"
.\" Copyright (c) 2003, 2007, 2009 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Hubert Feyrer <hubertf@NetBSD.org> and Thomas Klausner <wiz@NetBSD.org>.
.\"
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd May 16, 2010
.Dt PTHREAD 3
.Os
.Sh NAME
.Nm pthread
.Nd POSIX Threads Library
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Pp
.Nm cc
.Op Ar flags
.Ar files
.Fl lpthread
.Op Ar libraries
.Sh DESCRIPTION
The
.Nm
library provides an implementation of the standard
.Tn POSIX
threads library.
.Pp
The
.Nx
implementation is based on 1:1 thread model, therefore each
.Nm
has a kernel thread, called a light-weight process (LWP).
.Pp
Note that the system private thread interfaces upon which the
.Nm
library is built are subject to change without notice.
In order to remain compatible with future
.Nx
releases, programs must be linked against the dynamic version of the
thread library.
Statically linked programs using the
.Tn POSIX
threads framework may not work when run on a future version of the system.
.Sh FUNCTIONS
The following functions comprise the core of the
.Nm
library:
.Bl -column -offset indent "pthread_barrier_destroy(3)" "XXX"
.It Sy Function Ta Sy Description
.It Xr pthread_attr 3 Ta thread attribute operations
.It Xr pthread_barrier_destroy 3 Ta destroy a barrier
.It Xr pthread_barrier_init 3 Ta create a barrier
.It Xr pthread_barrier_wait 3 Ta wait for a barrier
.It Xr pthread_barrierattr 3 Ta barrier attribute operations
.It Xr pthread_cancel 3 Ta cancel the execution of a thread
.It Xr pthread_cleanup_push 3 Ta add or remove cleanup functions
.It Xr pthread_cond_broadcast 3 Ta unblock one or more threads
.It Xr pthread_cond_destroy 3 Ta destroy a condition variable
.It Xr pthread_cond_init 3 Ta create a condition variable
.It Xr pthread_cond_wait 3 Ta wait for a condition variable
.It Xr pthread_condattr 3 Ta condition attribute operations
.It Xr pthread_create 3 Ta create a new thread
.It Xr pthread_detach 3 Ta detach a thread
.It Xr pthread_equal 3 Ta compare thread identifiers
.It Xr pthread_exit 3 Ta terminate the calling thread
.It Xr pthread_getspecific 3 Ta get a thread-specific data value
.It Xr pthread_join 3 Ta wait for thread termination
.It Xr pthread_key_create 3 Ta thread-specific data key creation
.It Xr pthread_key_delete 3 Ta delete a thread-specific data key
.It Xr pthread_kill 3 Ta send a signal to a specific thread
.It Xr pthread_mutex_destroy 3 Ta free a mutex
.It Xr pthread_mutex_init 3 Ta create a mutex
.It Xr pthread_mutex_lock 3 Ta acquire a lock on a mutex
.It Xr pthread_mutex_unlock 3 Ta unlock a mutex
.It Xr pthread_mutexattr 3 Ta mutex attribute operations
.It Xr pthread_once 3 Ta dynamic package initialization
.It Xr pthread_rwlock_destroy 3 Ta destroy a read/write lock
.It Xr pthread_rwlock_init 3 Ta initialize a read/write lock
.It Xr pthread_rwlock_rdlock 3 Ta acquire a read/write lock for reading
.It Xr pthread_rwlock_unlock 3 Ta release a read/write lock
.It Xr pthread_rwlock_wrlock 3 Ta acquire a read/write lock for writing
.It Xr pthread_rwlockattr 3 Ta read/write lock attribute operations
.It Xr pthread_schedparam 3 Ta thread scheduling manipulation
.It Xr pthread_self 3 Ta get the ID of the calling thread
.It Xr pthread_setspecific 3 Ta get a thread-specific data value
.It Xr pthread_sigmask 3 Ta manipulate a thread's signal mask
.It Xr pthread_spin_destroy 3 Ta destroy a spin lock
.It Xr pthread_spin_init 3 Ta initialize a spin lock
.It Xr pthread_spin_lock 3 Ta acquire a spin lock
.It Xr pthread_spin_unlock 3 Ta release a spin lock
.It Xr pthread_testcancel 3 Ta set cancelability state
.El
.Sh ENVIRONMENT
The following environment variables affect the behavior of the library:
.Bl -tag -width "XXX"
.It Ev PTHREAD_DIAGASSERT
Possible values are any combinations of:
.Pp
.Bl -tag -width "X " -offset 1n -compact
.It Em A
Report errors to application by error return, but do not abort.
.It Em a
Abort on errors, creating a core dump for further debugging.
.It Em E
Do not log errors to stdout.
.It Em e
Log errors to stdout.
.It Em L
Do not log errors via
.Xr syslogd 8 .
.It Em l
Log errors via
.Xr syslogd 8 .
.El
.Pp
If not set in the environment, the
.Nm
library behaves as if
.Em AEL
has been specified.
.It Ev PTHREAD_STACKSIZE
Integer value giving the stack size in kilobytes.
This allows to set a smaller stack size than the default stack size.
The default stack size is the current limit on the stack size as
set with the shell's command to change limits
.Ic ( limit
for
.Xr csh 1 ,
or
.Ic ulimit
for
.Xr sh 1 ) .
.El
.Sh SEE ALSO
.Rs
.%A David R. Butenhof
.%T Programming with POSIX(R) Threads
.%D 1997
.%I Addison-Wesley
.Re
.Sh STANDARDS
The
.Nm
library conforms to
.St -p1003.1-2001 .
.Sh CAVEATS
Due to limitations in the current pthread implementation,
.Xr makecontext 3
and
.Xr sigaltstack 2
should not be used in programs which link against the
.Nm
library (whether threads are used or not).

1396
lib/libpthread/pthread.c Normal file

File diff suppressed because it is too large Load Diff

384
lib/libpthread/pthread.h Normal file
View File

@@ -0,0 +1,384 @@
/* $NetBSD: pthread.h,v 1.35 2012/11/03 03:10:50 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_H
#define _LIB_PTHREAD_H
#include <sys/cdefs.h>
#include <time.h> /* For timespec */
#include <sched.h>
#include <sys/featuretest.h>
#include <pthread_types.h>
__BEGIN_DECLS
int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
int pthread_create(pthread_t * __restrict,
const pthread_attr_t * __restrict, void *(*)(void *),
void * __restrict);
void pthread_exit(void *) __attribute__((__noreturn__));
int pthread_join(pthread_t, void **);
int pthread_equal(pthread_t, pthread_t);
pthread_t pthread_self(void);
int pthread_detach(pthread_t);
int pthread_getrrtimer_np(void);
int pthread_setrrtimer_np(int);
int pthread_attr_init(pthread_attr_t *);
int pthread_attr_destroy(pthread_attr_t *);
int pthread_attr_get_np(pthread_t, pthread_attr_t *);
int pthread_attr_getguardsize(const pthread_attr_t * __restrict,
size_t * __restrict);
int pthread_attr_setguardsize(pthread_attr_t *, size_t);
int pthread_attr_getinheritsched(const pthread_attr_t * __restrict,
int * __restrict);
int pthread_attr_setinheritsched(pthread_attr_t *, int);
int pthread_attr_getschedparam(const pthread_attr_t * __restrict,
struct sched_param * __restrict);
int pthread_attr_setschedparam(pthread_attr_t * __restrict,
const struct sched_param * __restrict);
int pthread_attr_getschedpolicy(const pthread_attr_t * __restrict,
int * __restrict);
int pthread_attr_setschedpolicy(pthread_attr_t *, int);
int pthread_attr_getscope(const pthread_attr_t * __restrict,
int * __restrict);
int pthread_attr_setscope(pthread_attr_t *, int);
int pthread_attr_getstack(const pthread_attr_t * __restrict,
void ** __restrict, size_t * __restrict);
int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
int pthread_attr_getstacksize(const pthread_attr_t * __restrict,
size_t * __restrict);
int pthread_attr_setstacksize(pthread_attr_t *, size_t);
int pthread_attr_getstackaddr(const pthread_attr_t * __restrict,
void ** __restrict);
int pthread_attr_setstackaddr(pthread_attr_t *, void *);
int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
int pthread_attr_setdetachstate(pthread_attr_t *, int);
int pthread_attr_getname_np(const pthread_attr_t *, char *,
size_t, void **);
int pthread_attr_setname_np(pthread_attr_t *, const char *, void *);
int pthread_mutex_init(pthread_mutex_t * __restrict,
const pthread_mutexattr_t * __restrict);
int pthread_mutex_destroy(pthread_mutex_t *);
int pthread_mutex_lock(pthread_mutex_t *);
int pthread_mutex_trylock(pthread_mutex_t *);
int pthread_mutex_unlock(pthread_mutex_t *);
int pthread_mutexattr_init(pthread_mutexattr_t *);
int pthread_mutexattr_destroy(pthread_mutexattr_t *);
int pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict,
int * __restrict);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int);
int pthread_cond_init(pthread_cond_t * __restrict,
const pthread_condattr_t * __restrict);
int pthread_cond_destroy(pthread_cond_t *);
int pthread_cond_wait(pthread_cond_t * __restrict,
pthread_mutex_t * __restrict);
#ifndef __LIBC12_SOURCE__
int pthread_cond_timedwait(pthread_cond_t * __restrict,
pthread_mutex_t * __restrict, const struct timespec * __restrict);
#endif
int pthread_cond_signal(pthread_cond_t *);
int pthread_cond_broadcast(pthread_cond_t *);
int pthread_condattr_init(pthread_condattr_t *);
#if defined(_NETBSD_SOURCE)
int pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
#endif
int pthread_condattr_destroy(pthread_condattr_t *);
int pthread_once(pthread_once_t *, void (*)(void));
int pthread_key_create(pthread_key_t *, void (*)(void *));
int pthread_key_delete(pthread_key_t);
int pthread_setspecific(pthread_key_t, const void *);
void* pthread_getspecific(pthread_key_t);
int pthread_cancel(pthread_t);
int pthread_setcancelstate(int, int *);
int pthread_setcanceltype(int, int *);
void pthread_testcancel(void);
int pthread_getname_np(pthread_t, char *, size_t);
int pthread_setname_np(pthread_t, const char *, void *);
int pthread_attr_setcreatesuspend_np(pthread_attr_t *);
int pthread_suspend_np(pthread_t);
int pthread_resume_np(pthread_t);
unsigned int pthread_curcpu_np(void);
struct pthread_cleanup_store {
void *pad[4];
};
#define pthread_cleanup_push(routine, arg) \
{ \
struct pthread_cleanup_store __store; \
pthread__cleanup_push((routine),(arg), &__store);
#define pthread_cleanup_pop(execute) \
pthread__cleanup_pop((execute), &__store); \
}
void pthread__cleanup_push(void (*)(void *), void *, void *);
void pthread__cleanup_pop(int, void *);
int pthread_spin_init(pthread_spinlock_t *, int);
int pthread_spin_destroy(pthread_spinlock_t *);
int pthread_spin_lock(pthread_spinlock_t *);
int pthread_spin_trylock(pthread_spinlock_t *);
int pthread_spin_unlock(pthread_spinlock_t *);
int pthread_rwlock_init(pthread_rwlock_t * __restrict,
const pthread_rwlockattr_t * __restrict);
int pthread_rwlock_destroy(pthread_rwlock_t *);
int pthread_rwlock_rdlock(pthread_rwlock_t *);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
int pthread_rwlock_wrlock(pthread_rwlock_t *);
int pthread_rwlock_trywrlock(pthread_rwlock_t *);
#ifndef __LIBC12_SOURCE__
int pthread_rwlock_timedrdlock(pthread_rwlock_t * __restrict,
const struct timespec * __restrict);
int pthread_rwlock_timedwrlock(pthread_rwlock_t * __restrict,
const struct timespec * __restrict);
#endif
int pthread_rwlock_unlock(pthread_rwlock_t *);
int pthread_rwlockattr_init(pthread_rwlockattr_t *);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
int pthread_barrier_init(pthread_barrier_t * __restrict,
const pthread_barrierattr_t * __restrict, unsigned int);
int pthread_barrier_wait(pthread_barrier_t *);
int pthread_barrier_destroy(pthread_barrier_t *);
int pthread_barrierattr_init(pthread_barrierattr_t *);
int pthread_barrierattr_destroy(pthread_barrierattr_t *);
int pthread_getschedparam(pthread_t, int * __restrict,
struct sched_param * __restrict);
int pthread_setschedparam(pthread_t, int, const struct sched_param *);
int pthread_setschedprio(pthread_t, int);
int *pthread__errno(void);
#if defined(_NETBSD_SOURCE)
int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);
int pthread_setaffinity_np(pthread_t, size_t, cpuset_t *);
int pthread_getattr_np(pthread_t, pthread_attr_t *);
int pthread_mutex_held_np(pthread_mutex_t *);
pthread_t pthread_mutex_owner_np(pthread_mutex_t *);
int pthread_rwlock_held_np(pthread_rwlock_t *);
int pthread_rwlock_wrheld_np(pthread_rwlock_t *);
int pthread_rwlock_rdheld_np(pthread_rwlock_t *);
int pthread_cond_has_waiters_np(pthread_cond_t *);
#endif /* _NETBSD_SOURCE */
__END_DECLS
#define PTHREAD_CREATE_JOINABLE 0
#define PTHREAD_CREATE_DETACHED 1
#define PTHREAD_INHERIT_SCHED 0
#define PTHREAD_EXPLICIT_SCHED 1
#define PTHREAD_SCOPE_PROCESS 0
#define PTHREAD_SCOPE_SYSTEM 1
#define PTHREAD_PROCESS_PRIVATE 0
#define PTHREAD_PROCESS_SHARED 1
#define PTHREAD_CANCEL_DEFERRED 0
#define PTHREAD_CANCEL_ASYNCHRONOUS 1
#define PTHREAD_CANCEL_ENABLE 0
#define PTHREAD_CANCEL_DISABLE 1
#define PTHREAD_BARRIER_SERIAL_THREAD 1234567
/*
* POSIX 1003.1-2001, section 2.5.9.3: "The symbolic constant
* PTHREAD_CANCELED expands to a constant expression of type (void *)
* whose value matches no pointer to an object in memory nor the value
* NULL."
*/
#define PTHREAD_CANCELED ((void *) 1)
/*
* Maximum length of a thread's name, including the terminating NUL.
*/
#define PTHREAD_MAX_NAMELEN_NP 32
/*
* Mutex attributes.
*/
#define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_ERRORCHECK 1
#define PTHREAD_MUTEX_RECURSIVE 2
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
#define PTHREAD_COND_INITIALIZER _PTHREAD_COND_INITIALIZER
#define PTHREAD_MUTEX_INITIALIZER _PTHREAD_MUTEX_INITIALIZER
#define PTHREAD_ONCE_INIT _PTHREAD_ONCE_INIT
#define PTHREAD_RWLOCK_INITIALIZER _PTHREAD_RWLOCK_INITIALIZER
#define PTHREAD_SPINLOCK_INITIALIZER _PTHREAD_SPINLOCK_INITIALIZER
/*
* Use macros to rename many pthread functions to the corresponding
* libc symbols which are either trivial/no-op stubs or the real
* thing, depending on whether libpthread is linked in to the
* program. This permits code, particularly libraries that do not
* directly use threads but want to be thread-safe in the presence of
* threaded callers, to use pthread mutexes and the like without
* unnecessairly including libpthread in their linkage.
*
* Left out of this list are functions that can't sensibly be trivial
* or no-op stubs in a single-threaded process (pthread_create,
* pthread_kill, pthread_detach), functions that normally block and
* wait for another thread to do something (pthread_join), and
* functions that don't make sense without the previous functions
* (pthread_attr_*). The pthread_cond_wait and pthread_cond_timedwait
* functions are useful in implementing certain protection mechanisms,
* though a non-buggy app shouldn't end up calling them in
* single-threaded mode.
*
* The rename is done as:
* #define pthread_foo __libc_foo
* instead of
* #define pthread_foo(x) __libc_foo((x))
* in order that taking the address of the function ("func =
* &pthread_foo;") continue to work.
*
* POSIX/SUSv3 requires that its functions exist as functions (even if
* macro versions exist) and specifically that "#undef pthread_foo" is
* legal and should not break anything. Code that does such will not
* successfully get the stub behavior implemented here and will
* require libpthread to be linked in.
*/
#ifndef __LIBPTHREAD_SOURCE__
__BEGIN_DECLS
int __libc_mutex_init(pthread_mutex_t * __restrict, const pthread_mutexattr_t * __restrict);
int __libc_mutex_lock(pthread_mutex_t *);
int __libc_mutex_trylock(pthread_mutex_t *);
int __libc_mutex_unlock(pthread_mutex_t *);
int __libc_mutex_destroy(pthread_mutex_t *);
int __libc_mutexattr_init(pthread_mutexattr_t *);
int __libc_mutexattr_settype(pthread_mutexattr_t *, int);
int __libc_mutexattr_destroy(pthread_mutexattr_t *);
__END_DECLS
#define pthread_mutex_init __libc_mutex_init
#define pthread_mutex_lock __libc_mutex_lock
#define pthread_mutex_trylock __libc_mutex_trylock
#define pthread_mutex_unlock __libc_mutex_unlock
#define pthread_mutex_destroy __libc_mutex_destroy
#define pthread_mutexattr_init __libc_mutexattr_init
#define pthread_mutexattr_settype __libc_mutexattr_settype
#define pthread_mutexattr_destroy __libc_mutexattr_destroy
__BEGIN_DECLS
int __libc_cond_init(pthread_cond_t * __restrict,
const pthread_condattr_t * __restrict);
int __libc_cond_signal(pthread_cond_t *);
int __libc_cond_broadcast(pthread_cond_t *);
int __libc_cond_wait(pthread_cond_t * __restrict,
pthread_mutex_t * __restrict);
#ifndef __LIBC12_SOURCE__
int __libc_cond_timedwait(pthread_cond_t * __restrict,
pthread_mutex_t * __restrict, const struct timespec * __restrict);
#endif
int __libc_cond_destroy(pthread_cond_t *);
__END_DECLS
#define pthread_cond_init __libc_cond_init
#define pthread_cond_signal __libc_cond_signal
#define pthread_cond_broadcast __libc_cond_broadcast
#define pthread_cond_wait __libc_cond_wait
#define pthread_cond_timedwait __libc_cond_timedwait
#define pthread_cond_destroy __libc_cond_destroy
__BEGIN_DECLS
int __libc_rwlock_init(pthread_rwlock_t * __restrict,
const pthread_rwlockattr_t * __restrict);
int __libc_rwlock_rdlock(pthread_rwlock_t *);
int __libc_rwlock_wrlock(pthread_rwlock_t *);
int __libc_rwlock_tryrdlock(pthread_rwlock_t *);
int __libc_rwlock_trywrlock(pthread_rwlock_t *);
int __libc_rwlock_unlock(pthread_rwlock_t *);
int __libc_rwlock_destroy(pthread_rwlock_t *);
__END_DECLS
#define pthread_rwlock_init __libc_rwlock_init
#define pthread_rwlock_rdlock __libc_rwlock_rdlock
#define pthread_rwlock_wrlock __libc_rwlock_wrlock
#define pthread_rwlock_tryrdlock __libc_rwlock_tryrdlock
#define pthread_rwlock_trywrlock __libc_rwlock_trywrlock
#define pthread_rwlock_unlock __libc_rwlock_unlock
#define pthread_rwlock_destroy __libc_rwlock_destroy
__BEGIN_DECLS
int __libc_thr_keycreate(pthread_key_t *, void (*)(void *));
int __libc_thr_setspecific(pthread_key_t, const void *);
void *__libc_thr_getspecific(pthread_key_t);
int __libc_thr_keydelete(pthread_key_t);
__END_DECLS
#define pthread_key_create __libc_thr_keycreate
#define pthread_setspecific __libc_thr_setspecific
#define pthread_getspecific __libc_thr_getspecific
#define pthread_key_delete __libc_thr_keydelete
__BEGIN_DECLS
int __libc_thr_once(pthread_once_t *, void (*)(void));
pthread_t __libc_thr_self(void);
void __libc_thr_exit(void *) __attribute__((__noreturn__));
int __libc_thr_setcancelstate(int, int *);
int __libc_thr_equal(pthread_t, pthread_t);
unsigned int __libc_thr_curcpu(void);
__END_DECLS
#define pthread_once __libc_thr_once
#define pthread_self __libc_thr_self
#define pthread_exit __libc_thr_exit
#define pthread_setcancelstate __libc_thr_setcancelstate
#define pthread_equal __libc_thr_equal
#define pthread_curcpu_np __libc_thr_curcpu
#endif /* __LIBPTHREAD_SOURCE__ */
#endif /* _LIB_PTHREAD_H */

View File

@@ -0,0 +1,155 @@
.\" $NetBSD: pthread_attr.3,v 1.22 2012/11/10 23:12:36 uwe Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
.\" the first lines of this file unmodified other than the possible
.\" addition of one or more copyright notices.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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: src/lib/libpthread/man/pthread_attr.3,v 1.11 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_ATTR 3
.Os
.Sh NAME
.Nm pthread_attr_init ,
.Nm pthread_attr_destroy
.Nd thread attribute operations
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_init "pthread_attr_t *attr"
.Ft int
.Fn pthread_attr_destroy "pthread_attr_t *attr"
.Sh DESCRIPTION
Thread attributes are used to specify parameters to
.Fn pthread_create .
One attribute object can be used in multiple calls to
.Fn pthread_create ,
with or without modifications between the calls.
The
.Vt pthread_attr_t
type is an opaque representation of the thread attributes;
any access to the object other than via the described
.Fn pthread_attr_*
functions may result in undefined behavior.
.Pp
The
.Fn pthread_attr_init
function initializes
.Fa attr
with the default thread attributes used in the implementation.
Depending on the implementation, undefined behavior may follow
if an uninitialized thread attribute object is used with some of
the thread attribute functions.
It is therefore a good practice to always use
.Fn pthread_attr_init ,
even if this might be unnecessary.
Undefined behavior may also follow if an already initialized
.Fa attr
is used with
.Fn pthread_attr_init .
.Pp
When the attribute object is no longer needed,
it should be destroyed by using
.Fn pthread_attr_destroy .
The function has no effect on threads that
were created by using a given attribute object.
A destroyed
.Fa attr
can be reinitialized using
.Fn pthread_attr_init ,
but all other actions with the destroyed object are unspecified.
.Pp
The following standard thread attribute functions are available:
.Bl -column -offset indent "pthread_attr_getinheritsched " "XXX"
.It Sy Function Ta Sy Description
.It Xr pthread_attr_getdetachstate 3 Ta thread detach state
.It Xr pthread_attr_getguardsize 3 Ta thread guard size
.It Xr pthread_attr_getinheritsched 3 Ta inherit scheduler attribute
.It Xr pthread_attr_getschedparam 3 Ta thread scheduling parameter
.It Xr pthread_attr_getschedpolicy 3 Ta thread scheduling policy
.It Xr pthread_attr_getscope 3 Ta thread contention scope
.It Xr pthread_attr_getstack 3 Ta thread stack
.It Xr pthread_attr_getstacksize 3 Ta thread stack size
.It Xr pthread_attr_getstackaddr 3 Ta thread stack address
.El
.Pp
Each listed
.Fn pthread_attr_get*
function has a
.Fn pthread_attr_set*
counterpart.
In addition, the following
.Nx
specific extensions are available:
.Bl -column -offset indent "pthread_attr_getinheritsched " "XXX"
.It Sy Function Ta Sy Description
.It Xr pthread_attr_get_np 3 Ta attributes of a running thread
.It Xr pthread_attr_getname_np 3 Ta descriptive name of an attribute
.El
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
No errors are defined for
.Fn pthread_attr_init
and
.Fn pthread_attr_destroy .
.Sh SEE ALSO
.Xr pthread_create 3 ,
.Xr pthread_join 3
.Sh STANDARDS
Both
.Fn pthread_attr_init
and
.Fn pthread_attr_destroy
conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,464 @@
/* $NetBSD: pthread_attr.c,v 1.16 2012/03/02 18:06:05 joerg Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_attr.c,v 1.16 2012/03/02 18:06:05 joerg Exp $");
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef __lint__
#define pthread_attr_get_np _pthread_attr_get_np
#endif
#include "pthread.h"
#include "pthread_int.h"
__weak_alias(pthread_attr_get_np, _pthread_attr_get_np)
static struct pthread_attr_private *pthread__attr_init_private(
pthread_attr_t *);
static struct pthread_attr_private *
pthread__attr_init_private(pthread_attr_t *attr)
{
struct pthread_attr_private *p;
if ((p = attr->pta_private) != NULL)
return p;
p = malloc(sizeof(*p));
if (p != NULL) {
memset(p, 0, sizeof(*p));
attr->pta_private = p;
p->ptap_policy = SCHED_OTHER;
}
return p;
}
int
pthread_attr_init(pthread_attr_t *attr)
{
attr->pta_magic = PT_ATTR_MAGIC;
attr->pta_flags = 0;
attr->pta_private = NULL;
return 0;
}
int
pthread_attr_destroy(pthread_attr_t *attr)
{
struct pthread_attr_private *p;
if ((p = attr->pta_private) != NULL)
free(p);
return 0;
}
int
pthread_attr_get_np(pthread_t thread, pthread_attr_t *attr)
{
struct pthread_attr_private *p;
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
attr->pta_flags = thread->pt_flags &
(PT_FLAG_DETACHED | PT_FLAG_SCOPE_SYSTEM | PT_FLAG_EXPLICIT_SCHED);
p->ptap_namearg = thread->pt_name;
p->ptap_stackaddr = thread->pt_stack.ss_sp;
p->ptap_stacksize = thread->pt_stack.ss_size;
p->ptap_guardsize = pthread__pagesize;
return pthread_getschedparam(thread, &p->ptap_policy, &p->ptap_sp);
}
int
pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
{
if (attr->pta_flags & PT_FLAG_DETACHED)
*detachstate = PTHREAD_CREATE_DETACHED;
else
*detachstate = PTHREAD_CREATE_JOINABLE;
return 0;
}
int
pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
{
switch (detachstate) {
case PTHREAD_CREATE_JOINABLE:
attr->pta_flags &= ~PT_FLAG_DETACHED;
break;
case PTHREAD_CREATE_DETACHED:
attr->pta_flags |= PT_FLAG_DETACHED;
break;
default:
return EINVAL;
}
return 0;
}
int
pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guard)
{
struct pthread_attr_private *p;
if ((p = attr->pta_private) == NULL)
*guard = (size_t)sysconf(_SC_PAGESIZE);
else
*guard = p->ptap_guardsize;
return 0;
}
int
pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard)
{
struct pthread_attr_private *p;
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
p->ptap_guardsize = guard;
return 0;
}
int
pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
{
if (attr->pta_flags & PT_FLAG_EXPLICIT_SCHED)
*inherit = PTHREAD_EXPLICIT_SCHED;
else
*inherit = PTHREAD_INHERIT_SCHED;
return 0;
}
int
pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
{
switch (inherit) {
case PTHREAD_INHERIT_SCHED:
attr->pta_flags &= ~PT_FLAG_EXPLICIT_SCHED;
break;
case PTHREAD_EXPLICIT_SCHED:
attr->pta_flags |= PT_FLAG_EXPLICIT_SCHED;
break;
default:
return EINVAL;
}
return 0;
}
int
pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
{
if (attr->pta_flags & PT_FLAG_SCOPE_SYSTEM)
*scope = PTHREAD_SCOPE_SYSTEM;
else
*scope = PTHREAD_SCOPE_PROCESS;
return 0;
}
int
pthread_attr_setscope(pthread_attr_t *attr, int scope)
{
switch (scope) {
case PTHREAD_SCOPE_PROCESS:
attr->pta_flags &= ~PT_FLAG_SCOPE_SYSTEM;
break;
case PTHREAD_SCOPE_SYSTEM:
attr->pta_flags |= PT_FLAG_SCOPE_SYSTEM;
break;
default:
return EINVAL;
}
return 0;
}
int
pthread_attr_setschedparam(pthread_attr_t *attr,
const struct sched_param *param)
{
struct pthread_attr_private *p;
int error;
if (param == NULL)
return EINVAL;
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
error = pthread__checkpri(param->sched_priority);
if (error == 0)
p->ptap_sp = *param;
return error;
}
int
pthread_attr_getschedparam(const pthread_attr_t *attr,
struct sched_param *param)
{
struct pthread_attr_private *p;
if (param == NULL)
return EINVAL;
p = attr->pta_private;
if (p == NULL)
memset(param, 0, sizeof(*param));
else
*param = p->ptap_sp;
return 0;
}
int
pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
{
struct pthread_attr_private *p;
switch (policy) {
case SCHED_OTHER:
case SCHED_FIFO:
case SCHED_RR:
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
p->ptap_policy = policy;
return 0;
default:
return ENOTSUP;
}
}
int
pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
{
struct pthread_attr_private *p;
p = attr->pta_private;
if (p == NULL) {
*policy = SCHED_OTHER;
return 0;
}
*policy = p->ptap_policy;
return 0;
}
int
pthread_attr_getstack(const pthread_attr_t *attr, void **addr, size_t *size)
{
struct pthread_attr_private *p;
if ((p = attr->pta_private) == NULL) {
*addr = NULL;
*size = pthread__stacksize;
} else {
*addr = p->ptap_stackaddr;
*size = p->ptap_stacksize;
}
return 0;
}
int
pthread_attr_setstack(pthread_attr_t *attr, void *addr, size_t size)
{
struct pthread_attr_private *p;
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
p->ptap_stackaddr = addr;
p->ptap_stacksize = size;
return 0;
}
int
pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *size)
{
struct pthread_attr_private *p;
if ((p = attr->pta_private) == NULL)
*size = pthread__stacksize;
else
*size = p->ptap_stacksize;
return 0;
}
int
pthread_attr_setstacksize(pthread_attr_t *attr, size_t size)
{
struct pthread_attr_private *p;
if (size < (size_t)sysconf(_SC_THREAD_STACK_MIN))
return EINVAL;
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
p->ptap_stacksize = size;
return 0;
}
int
pthread_attr_getstackaddr(const pthread_attr_t *attr, void **addr)
{
struct pthread_attr_private *p;
if ((p = attr->pta_private) == NULL)
*addr = NULL;
else
*addr = p->ptap_stackaddr;
return 0;
}
int
pthread_attr_setstackaddr(pthread_attr_t *attr, void *addr)
{
struct pthread_attr_private *p;
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
p->ptap_stackaddr = addr;
return 0;
}
int
pthread_attr_getname_np(const pthread_attr_t *attr, char *name, size_t len,
void **argp)
{
struct pthread_attr_private *p;
if ((p = attr->pta_private) == NULL) {
name[0] = '\0';
if (argp != NULL)
*argp = NULL;
} else {
strlcpy(name, p->ptap_name, len);
if (argp != NULL)
*argp = p->ptap_namearg;
}
return 0;
}
int
pthread_attr_setname_np(pthread_attr_t *attr, const char *name, void *arg)
{
struct pthread_attr_private *p;
int namelen;
p = pthread__attr_init_private(attr);
if (p == NULL)
return ENOMEM;
namelen = snprintf(p->ptap_name, PTHREAD_MAX_NAMELEN_NP, name, arg);
if (namelen >= PTHREAD_MAX_NAMELEN_NP) {
p->ptap_name[0] = '\0';
return EINVAL;
}
p->ptap_namearg = arg;
return 0;
}
int
pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
{
attr->pta_flags |= PT_FLAG_SUSPENDED;
return 0;
}
int
pthread_getattr_np(pthread_t thread, pthread_attr_t *attr)
{
int error;
if ((error = pthread_attr_init(attr)) != 0)
return error;
if ((error = pthread_attr_get_np(thread, attr)) != 0) {
(void)pthread_attr_destroy(attr);
return error;
}
return 0;
}

View File

@@ -0,0 +1,121 @@
.\" $NetBSD: pthread_attr_get_np.3,v 1.4 2010/08/06 05:35:42 christos Exp $
.\"
.\" Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd August 6, 2010
.Dt PTHREAD_ATTR_GET_NP 3
.Os
.Sh NAME
.Nm pthread_attr_get_np
.Nd get attributes of existing thread
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_get_np "pthread_t thread" "pthread_attr_t *attr"
.Ft int
.Fn pthread_getattr_np "pthread_t thread" "pthread_attr_t *attr"
.Sh DESCRIPTION
The
.Fn pthread_attr_get_np
and
.Fn pthread_getattr_np
functions can be used to retrieve attributes of a running
.Fa thread .
The result is stored to
.Fa attr .
.Pp
For
.Fn pthread_attr_get_np
.Fa attr
should be initialized prior to the call by using
.Xr pthread_attr_init 3 .
.Fn pthread_getattr_np
does this automatically.
.Pp
For both functions
.Fa attr
should be freed when it is not in use anymore with
.Xr pthread_attr_destroy 3 .
.Pp
Most fields of
.Fa attr
are the same ones provided during thread creation time as a parameter to
.Xr pthread_create 3 .
The exceptions include:
.Bl -bullet -offset indent
.It
The detach state -- a joinable thread
may have detached itself after the creation.
.It
The guard size, which may vary if the application
has allocated its own thread stack.
.It
The stack address and size;
.Fn pthread_attr_get_np
will always return the thread's real stack address and size,
regardless of the values in the original attributes structure.
.El
.Pp
The returned
.Vt pthread_attr_t
structure is supposed to be used in conjunction with the
.Fn pthread_attr_get*
functions to retrieve individual values from the structure.
When the returned
.Fa attr
is no longer needed, it should be destroyed by using
.Xr pthread_attr_destroy 3 .
.Sh RETURN VALUES
Upon successful completion,
.Fn pthread_attr_get_np
and
.Fn pthread_getattr_np
return 0.
Otherwise an error number is returned to indicate the error.
.Sh COMPATIBILITY
The
.Fn pthread_attr_get_np
and
.Fn pthread_getattr_np
functions are non-standard extensions.
.Sh ERRORS
The
.Fn pthread_attr_get_np
and
.Fn pthread_getattr_np
functions will fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
Insufficient memory.
.It Bq Er ESRCH
Non-existent
.Fa thread .
.El
.Sh SEE ALSO
.Xr pthread 3 ,
.Xr pthread_attr 3

View File

@@ -0,0 +1,119 @@
.\" $NetBSD: pthread_attr_getdetachstate.3,v 1.2 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
.\" the first lines of this file unmodified other than the possible
.\" addition of one or more copyright notices.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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: src/lib/libpthread/man/pthread_attr.3,v 1.11 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_ATTR_GETDETACHSTATE 3
.Os
.Sh NAME
.Nm pthread_attr_getdetachstate
.Nd get and set the
.Dq detach state
attribute
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_getdetachstate "const pthread_attr_t *attr" "int *detachstate"
.Ft int
.Fn pthread_attr_setdetachstate "pthread_attr_t *attr" "int detachstate"
.Sh DESCRIPTION
The attribute parameters for the
.Fn pthread_attr_getdetachstate
and
.Fn pthread_attr_setdetachstate
functions are mutually exclusive and must be one of:
.Bl -tag -width PTHREAD_CREATE_DETACHED -offset 2n
.It Dv PTHREAD_CREATE_JOINABLE
The threads must explicitly be waited for using the
.Xr pthread_join 3
function once they exit for their status to be received and their resources
to be freed.
This is the default.
.It Dv PTHREAD_CREATE_DETACHED
The thread's resources will automatically be freed once the thread exits,
and the thread will not be joined.
.El
.Pp
If the thread is created as detached,
it is an error to use the thread
.Tn ID
with
.Xr pthread_detach 3
or
.Xr pthread_join 3 .
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
No errors are defined for
.Fn pthread_attr_getdetachstate .
.Pp
The
.Fn pthread_attr_setdetachstate
function should fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa detachstate
is invalid.
.El
.Sh SEE ALSO
.Xr pthread_attr 3 ,
.Xr pthread_detach 3 ,
.Xr pthread_join 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,124 @@
.\" $NetBSD: pthread_attr_getguardsize.3,v 1.2 2010/07/08 18:24:34 wiz Exp $
.\"
.\" Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd July 7, 2010
.Dt PTHREAD_ATTR_GETGUARDSIZE 3
.Os
.Sh NAME
.Nm pthread_attr_getguardsize
.Nd get and set thread guard size
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_getguardsize \
"const pthread_attr_t * restrict attr" "size_t * restrict guardsize"
.Ft int
.Fn pthread_attr_setguardsize "pthread_attr_t *attr" "size_t guardsize"
.Sh DESCRIPTION
The
.Fn pthread_attr_getguardsize
and
.Fn pthread_attr_setguardsize
functions get and set
.Fa guardsize
in the
.Fa attr
object.
If
.Fa guardsize
is larger than 0, the system reserves
an additional region of guarded memory of at least
.Fa guardsize
bytes at the end of the thread's stack for each new thread created by using
.Fa attr .
.Pp
The guarded area is understood to be pages of memory
that are protected from read and write access.
While the guarded area should be rounded by the system page size,
the actual default size is implementation-defined.
In
.Nx
the default
.Fa guardsize
is
.Dv _SC_PAGESIZE ,
the system page size.
.Pp
The rationale behind
.Fa guardsize
is two-fold:
.Bl -enum -offset 2n
.It
On the one hand, it provides protection against overflow of the stack pointer.
If there is a guard area and a thread overflows its
stack pointer into this extra memory area, it should receive a
.Dv SIGSEGV
signal or experience other comparable fatal error condition.
Note that if a thread allocates large data structures on stack,
it may be necessary to raise the default
.Fa guardsize
in order to detect stack overflows.
.It
On the other hand, the overflow protection may waste system resources
if an application that creates a large number of threads knows that it
will never overflow the stack.
In this case it is possible to set
.Fa guardsize
to 0.
.El
.Pp
If
.Xr pthread_attr_setstack 3
or
.Xr pthread_attr_setstackaddr 3
is used to set the stack address attribute in
.Fa attr ,
the guard size attribute is ignored and no guard area will be allocated;
it is the responsibility of the application to handle the overflow conditions.
.Sh RETURN VALUES
If successful, both functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
No errors are defined for
.Fn pthread_attr_getguardsize .
.Pp
The
.Fn pthread_attr_setguardsize
may fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
There was insufficient memory.
.El
.Sh SEE ALSO
.Xr pthread_attr 3 ,
.Xr pthread_attr_setstack 3 ,
.Xr sysconf 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2008 .

View File

@@ -0,0 +1,112 @@
.\" $NetBSD: pthread_attr_getinheritsched.3,v 1.3 2013/05/10 21:06:14 christos Exp $
.\"
.\" Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd May 10, 2013
.Dt PTHREAD_ATTR_GETINHERITSCHED 3
.Os
.Sh NAME
.Nm pthread_attr_getinheritsched
.Nd get and set
.Dq inheritsched
attribute
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_getinheritsched \
"const pthread_attr_t * restrict attr" "int * restrict inheritsched"
.Ft int
.Fn pthread_attr_setinheritsched "pthread_attr_t *attr" "int inheritsched"
.Sh DESCRIPTION
The
.Fn pthread_attr_getinheritsched
and
.Fn pthread_attr_setinheritsched
functions get and set, respectively, the inherit scheduler attribute,
.Fa inheritsched ,
in the
.Fa attr
object.
The
.Fa inheritsched
parameter specifies whether a tread created by using
.Fa attr
will obtain its scheduling attributes directly from
.Fa attr
or whether it will inherit these from the calling thread.
.Pp
Two values are possible for
.Fa inheritsched :
.Bl -tag -width PTHREAD_EXPLICIT_SCHED -offset indent
.It Dv PTHREAD_INHERIT_SCHED
The thread scheduling attributes will be
inherited from the creating thread and the ones in
.Fa attr
are ignored.
.It Dv PTHREAD_EXPLICIT_SCHED
The thread scheduling attributes will be set to the corresponding values in
.Fa attr .
.El
.Pp
The following thread scheduling attributes are affected by
.Fa inheritsched :
.Bl -bullet -offset indent
.It
Scheduling policy; see
.Xr pthread_attr_setschedpolicy 3 .
.It
Scheduling parameter; see
.Xr pthread_attr_getschedparam 3 .
.It
Scheduling contention scope; see
.Xr pthread_attr_getscope 3 .
.El
.Sh RETURN VALUES
If successful, both functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh COMPATIBILITY
The standard leaves it unspecified which (if any) is the default
inherit scheduler attribute in a newly initialized attribute object.
.Sh ERRORS
No errors are defined for
.Fn pthread_attr_getinheritsched .
.Pp
The
.Fn pthread_attr_setinheritsched
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa inheritsched
is invalid.
.El
.Sh SEE ALSO
.Xr pthread_attr 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2008 .

View File

@@ -0,0 +1,109 @@
.\" $NetBSD: pthread_attr_getname_np.3,v 1.6 2010/07/09 10:55:57 jruoho Exp $
.\"
.\" Copyright (c)2007 YAMAMOTO Takashi,
.\" 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.
.\"
.\" ------------------------------------------------------------
.Dd July 7, 2010
.Dt PTHREAD_ATTR_GETNAME_NP 3
.Os
.Sh NAME
.Nm pthread_attr_getname_np
.Nd get and set descriptive name of an attribute
.\" ------------------------------------------------------------
.Sh LIBRARY
.Lb libpthread
.\" ------------------------------------------------------------
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_getname_np \
"const pthread_attr_t attr" "char *name" "size_t len"
.Ft int
.Fn pthread_attr_setname_np \
"pthread_attr_t attr" "const char *name" "void *arg"
.\" ------------------------------------------------------------
.Sh DESCRIPTION
The
.Fn pthread_attr_getname_np
function gets the descriptive name of a thread attribute.
It takes the following arguments:
.Bl -tag -width target -offset indent
.It Fa attr
The attribute whose descriptive name will be obtained.
.It Fa name
The buffer to be filled with the descriptive name of the attribute.
.It Fa len
The size of the buffer
.Fa name
in bytes.
.El
.Pp
The
.Fn pthread_attr_setname_np
function sets the descriptive name of a thread attribute.
It takes the following arguments:
.Bl -tag -width attr -offset indent
.It Fa attr
The attribute whose descriptive name will be set.
.It Fa name
The
.Xr printf 3
format string to be used to construct the descriptive name of the attribute.
The resulted descriptive name should be shorter than
.Dv PTHREAD_MAX_NAMELEN_NP .
.It Fa arg
The
.Xr printf 3
argument used with
.Fa name .
.El
.\" ------------------------------------------------------------
.Sh RETURN VALUES
Both functions return 0 on success.
Otherwise, an error number is returned.
.\" ------------------------------------------------------------
.Sh COMPATIBILITY
Both functions are non-standard extensions.
.\" ------------------------------------------------------------
.Sh ERRORS
No errors are defined for
.Fn pthread_attr_getname_np .
.Pp
The
.Fn pthread_attr_setname_np
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The supplied descriptive
.Fa name
was longer than
.Dv PTHREAD_MAX_NAMELEN_NP .
.It Bq Er ENOMEM
There was insufficient memory for the operation.
.El
.\" ------------------------------------------------------------
.Sh SEE ALSO
.Xr pthread_attr 3 ,
.Xr pthread_getname_np 3

View File

@@ -0,0 +1,124 @@
.\" $NetBSD: pthread_attr_getschedparam.3,v 1.2 2010/07/08 22:19:26 jruoho Exp $
.\"
.\" Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd July 7, 2010
.Dt PTHREAD_ATTR_GETSCHEDPARAM 3
.Os
.Sh NAME
.Nm pthread_attr_getschedparam
.Nd get and set scheduling attributes
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_getschedparam \
"const pthread_attr_t * restrict attr" "struct sched_param * restrict param"
.Ft int
.Fn pthread_attr_setschedparam \
"pthread_attr_t *attr" "const struct sched_param *param"
.Ft int
.Fn pthread_attr_getschedpolicy \
"const pthread_attr_t * restrict attr" "int * restrict policy"
.Ft int
.Fn pthread_attr_setschedpolicy "pthread_attr_t *attr" "int policy"
.Sh DESCRIPTION
The
.Fn pthread_attr_getschedparam
and
.Fn pthread_attr_setschedparam
functions obtain and set the scheduling parameter attribute in the
.Fa attr
object.
The
.Vt sched_param
structure is defined in
.In sched.h .
At minimum this structure contains only a single member,
.Vt sched_priority .
Refer to
.Xr pthread_schedparam 3
and
.Xr sched 3
for additional details.
.Pp
The
.Fn pthread_attr_getschedpolicy
and
.Fn pthread_attr_setschedpolicy
functions get and set the scheduling policy attribute,
.Fa policy ,
in the
.Fa attr
object.
The supported values of
.Fa policy
are the same ones listed in
.Xr pthread_schedparam 3 .
.Sh RETURN VALUES
If successful, all described functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
The
.Fn pthread_attr_getschedparam
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
An invalid parameter was specified.
.El
.Pp
The
.Fn pthread_attr_setschedparam
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
An invalid parameter was specified.
.It Bq Er ENOMEM
There was insufficient memory.
.El
.Pp
The
.Fn pthread_attr_setschedpolicy
function may fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
There was insufficient memory.
.It Bq Er ENOTSUP
An unsupported
.Fa policy
was specified.
.El
.Pp
No errors are defined for
.Fn pthread_attr_getschedpolicy .
.Sh SEE ALSO
.Xr pthread_attr 3 ,
.Xr pthread_schedparam 3 ,
.Xr sched 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2008 .

View File

@@ -0,0 +1,99 @@
.\" $NetBSD: pthread_attr_getscope.3,v 1.2 2010/07/07 10:22:33 njoly Exp $
.\"
.\" Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd July 7, 2010
.Dt PTHREAD_ATTR_GETSCOPE 3
.Os
.Sh NAME
.Nm pthread_attr_getscope
.Nd get and set the contention scope attribute
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_getscope \
"const pthread_attr_t * restrict attr" "int * restrict contentionscope"
.Ft int
.Fn pthread_attr_setscope "pthread_attr_t *attr" "int contentionscope"
.Sh DESCRIPTION
The
.Fn pthread_attr_getscope
and
.Fn pthread_attr_setscope
functions get and set, respectively, the contention scope attribute in the
.Fa attr
object.
.Pp
The
.Fa contentionscope
parameter specifies the scheduling contention scope of a thread.
It is only possible to set the scope of a thread before the thread is created.
There are two possible contention scopes:
.Bl -tag -width PTHREAD_SCOPE_PROCESS -offset 2n
.It Dv PTHREAD_SCOPE_SYSTEM
The thread will contend for
.Tn CPU
resources with all other processes and threads in the system.
Generally this means that the user thread is bound directly to the
kernel scheduling for its entire lifetime.
.It Dv PTHREAD_SCOPE_PROCESS
The thread will contend with other threads with the same scope attribute.
In general, this means that all
.Dv PTHREAD_SCOPE_PROCESS
threads are grouped together and this group of threads contends for
.Tn CPU
resources.
This is commonly seen to require a hybrid
.Pq Dq M:N
threading model in order to multiplex the user and kernel space scheduling.
.El
.Pp
Only
.Dv PTHREAD_SCOPE_SYSTEM
is supported in
.Nx .
.Sh RETURN VALUES
Upon successful completion, both functions return 0.
Otherwise an error number is returned to indicate the error.
.Sh ERRORS
No errors are defined for
.Fn pthread_attr_getscope .
.Pp
The
.Fn pthread_attr_setscope
function shall fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
Invalid parameter.
.El
.Sh SEE ALSO
.Xr pthread_attr 3 ,
.Xr csf 9
.Sh STANDARDS
Both functions conform to
.St -p1003.1-96 .

View File

@@ -0,0 +1,175 @@
.\" $NetBSD: pthread_attr_getstack.3,v 1.5 2010/07/09 17:15:59 jruoho Exp $
.\"
.\" Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd July 9, 2010
.Dt PTHREAD_ATTR_GETSTACK 3
.Os
.Sh NAME
.Nm pthread_attr_getstack
.Nd get and set thread stack attributes
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_getstack \
"const pthread_attr_t * restrict attr" \
"void ** restrict stackaddr, size_t * restrict stacksize"
.Ft int
.Fn pthread_attr_setstack \
"pthread_attr_t * restrict attr" "void *stackaddr, size_t stacksize"
.Ft int
.Fn pthread_attr_getstacksize \
"const pthread_attr_t * restrict attr" "size_t * restrict stacksize"
.Ft int
.Fn pthread_attr_setstacksize \
"pthread_attr_t *attr" "size_t stacksize"
.Ft int
.Fn pthread_attr_getstackaddr \
"const pthread_attr_t * restrict attr" "void ** restrict stackaddr"
.Ft int
.Fn pthread_attr_setstackaddr \
"pthread_attr_t *attr" "void *stackaddr"
.Sh DESCRIPTION
The
.Fn pthread_attr_getstack
and
.Fn pthread_attr_setstack
functions get and set, respectively, the thread stack attributes
.Fa stackaddr
and
.Fa stacksize
in the
.Fa attr
object.
The remaining four functions behave similarly,
but instead of getting or setting both
.Fa stackaddr
and
.Fa stacksize ,
these get and set the values individually.
.Pp
The
.Fa stacksize
parameter is defined to be the minimum stack size (in bytes)
allocated for the thread's stack during the creation of the thread.
The
.Fa stackaddr
attribute specifies the location of storage to be used for the thread's stack.
All pages within the stack described by
.Fa stackaddr
and
.Fa stacksize
should be both readable and writable by the thread.
.Pp
The behavior is undefined in all functions if the
.Fa attr
parameter does not refer to an attribute object initialized by using
.Xr pthread_attr_init 3
prior to the call.
In addition, undefined behavior may follow if the
.Fn pthread_attr_getstack
function is called before the
.Fa stackaddr
attribute has been set.
.Ss Rationale
The rationale behind these functions is to address cases where an application
may be used in an environment where the stack of a thread must be placed to
some particular region of memory.
For the majority of applications, this is seldom necessary,
and the use of these functions should be generally avoided.
At least few potential caveats can be mentioned.
.Bl -bullet -offset 2n
.It
There is a certain degree of ambiguity in the
.Tn POSIX
standard with respect to thread stack.
.It
The exact behavior of the functions may vary
both across machines and operating systems.
In particular, the address specified by
.Fa stackaddr
should be suitably aligned.
The system page size, as specified by
.Xr sysconf 3 ,
and the use of
.Xr posix_memalign 3
may guarantee some degree of portability.
Also
.Xr mmap 2
provides means for alignment.
.It
If the application modifies the stack address, it claims also
the responsibility of allocating the stack area and guarding it against
possible stack overflow.
No default guard area will be allocated (see
.Xr pthread_attr_getguardsize 3 ) .
It may be necessary to manually use
.Xr mprotect 2
in order to define a guard area at the end of the allocated stack.
.It
Moreover, if
.Fa attr
is used to create multiple threads, the stack address must be changed
by the application between successive calls to
.Xr pthread_create 3 .
.El
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
No errors are defined for the three functions that obtain the stack values.
The three functions that set the stack values may fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
There was insufficient memory to complete the operation.
.El
.Pp
The
.Fn pthread_attr_setstacksize
function may additionally fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The specified
.Fa stacksize
is less than
.Dv PTHREAD_STACK_MIN
or exceeds some system-imposed limit.
.El
.Sh SEE ALSO
.Xr pthread_attr 3 ,
.Xr pthread_attr_setguardsize 3
.Sh STANDARDS
All described functions conform to
.St -p1003.1-2001 .
Note that
.Fn pthread_attr_getstackaddr
and
.Fn pthread_attr_setstackaddr
were however removed from the specification in the
.St -p1003.1-2008
revision.

View File

@@ -0,0 +1,66 @@
.\" $NetBSD: pthread_attr_setcreatesuspend_np.3,v 1.4 2010/07/09 09:10:34 jruoho Exp $
.\"
.\" Copyright (c) 2003 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Christos Zoulas.
.\"
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd July 9, 2010
.Dt PTHREAD_ATTR_SETCREATESUSPEND_NP 3
.Os
.Sh NAME
.Nm pthread_attr_setcreatesuspend_np
.Nd set attribute to create a thread suspended
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_attr_setcreatesuspend_np "pthread_attr_t attr"
.Sh DESCRIPTION
The
.Fn pthread_attr_setcreatesuspend_np
function sets the
.Ar attr
argument, so that if this
.Ar attr
is used in a
.Xr pthread_create 3
call, then the thread created will not run, but it will remain blocked
in the suspended queue, until
.Xr pthread_resume_np 3
is called on it.
.Sh RETURN VALUES
The
.Fn pthread_attr_setcreatesuspend_np
function always returns 0.
.Sh COMPATIBILITY
The function is a non-standard extension.
.Sh ERRORS
No errors are defined.
.Sh SEE ALSO
.Xr pthread_create 3 ,
.Xr pthread_resume_np 3 ,
.Xr pthread_suspend_np 3

View File

@@ -0,0 +1,162 @@
.\" $NetBSD: pthread_barrier.3,v 1.4 2010/07/09 18:07:20 jruoho Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" ----------------------------------------------------------------------------
.Dd July 8, 2010
.Dt PTHREAD_BARRIER 3
.Os
.Sh NAME
.Nm pthread_barrier
.Nd barrier interface
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_barrier_init "pthread_barrier_t * restrict barrier" \
"const pthread_barrierattr_t * restrict attr" "unsigned int count"
.Ft int
.Fn pthread_barrier_destroy "pthread_barrier_t *barrier"
.Ft int
.Fn pthread_barrier_wait "pthread_barrier_t *barrier"
.\" ----------------------------------------------------------------------------
.Sh DESCRIPTION
The
.Fn pthread_barrier_init
function creates a new barrier with attributes
.Fa attr
and
.Fa count .
The
.Fa count
parameter indicates the number of threads
which will participate in the barrier.
The
.Xr pthread_barrierattr_init 3
function may be used to specify the attributes supplied in
.Fa attr .
If
.Fa attr
is
.Dv NULL ,
the default attributes are used.
Barriers are most commonly used in the decomposition of parallel loops.
.Pp
.\" -----
The
.Fn pthread_barrier_destroy
function causes the resources allocated to
.Fa barrier
to be released.
No threads should be blocked on
.Fa barrier .
.Pp
.\" -----
The
.Fn pthread_barrier_wait
function causes the current thread to wait on the barrier specified.
Once as many threads as specified by the
.Fa count
parameter to the corresponding
.Fn pthread_barrier_init
call have called
.Fn pthread_barrier_wait ,
all threads will wake up, return from their respective
.Fn pthread_barrier_wait
calls and continue execution.
.\" ----------------------------------------------------------------------------
.Sh RETURN VALUES
If successful,
.Fn pthread_barrier_init
will return zero and put the new barrier id into
.Fa barrier ,
otherwise an error number will be returned to indicate the error.
.Pp
.\" -----
If successful,
.Fn pthread_barrier_destroy
will return zero.
Otherwise an error value will be returned.
.Pp
.\" -----
If successful,
.Fn pthread_barrier_wait
will return zero for all waiting threads except for one.
One thread will receive status
.Dv PTHREAD_BARRIER_SERIAL_THREAD ,
which is intended to indicate that this thread may be used to update
shared data.
It is the responsibility of this thread to insure the visibility
and atomicity of any updates to shared data with respect to the
other threads participating in the barrier.
In the case of failure, an error value will be returned.
.\" ----------------------------------------------------------------------------
.Sh ERRORS
The
.Fn pthread_barrier_init
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa count
is zero or
.Fa attr
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_barrier_destroy
function may fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The
.Fa barrier
still has active threads associated with it.
.It Bq Er EINVAL
The value specified by
.Fa barrier
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_barrier_wait
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa barrier
is invalid.
.El
.\" ---------------------------------------------------------------------------
.Sh SEE ALSO
.Xr pthread_barrierattr 3 ,
.Xr pthread_cond 3 ,
.Xr pthread_mutex 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,137 @@
/* $NetBSD: pthread_barrier.c,v 1.19 2009/01/29 21:19:35 ad Exp $ */
/*-
* Copyright (c) 2001, 2003, 2006, 2007, 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams, by Jason R. Thorpe, and by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_barrier.c,v 1.19 2009/01/29 21:19:35 ad Exp $");
#include <errno.h>
#include "pthread.h"
#include "pthread_int.h"
int
pthread_barrier_init(pthread_barrier_t *barrier,
const pthread_barrierattr_t *attr, unsigned int count)
{
if (attr != NULL && attr->ptba_magic != _PT_BARRIERATTR_MAGIC)
return EINVAL;
if (count == 0)
return EINVAL;
barrier->ptb_magic = _PT_BARRIER_MAGIC;
PTQ_INIT(&barrier->ptb_waiters);
barrier->ptb_initcount = count;
barrier->ptb_curcount = 0;
barrier->ptb_generation = 0;
return 0;
}
int
pthread_barrier_destroy(pthread_barrier_t *barrier)
{
if (barrier->ptb_magic != _PT_BARRIER_MAGIC)
return EINVAL;
if (barrier->ptb_curcount != 0)
return EBUSY;
return 0;
}
int
pthread_barrier_wait(pthread_barrier_t *barrier)
{
pthread_mutex_t *interlock;
pthread_t self;
unsigned int gen;
if (barrier->ptb_magic != _PT_BARRIER_MAGIC)
return EINVAL;
/*
* A single arbitrary thread is supposed to return
* PTHREAD_BARRIER_SERIAL_THREAD, and everone else
* is supposed to return 0. Since pthread_barrier_wait()
* is not a cancellation point, this is trivial; we
* simply elect that the thread that causes the barrier
* to be satisfied gets the special return value. Note
* that this final thread does not actually need to block,
* but instead is responsible for waking everyone else up.
*/
self = pthread__self();
interlock = pthread__hashlock(barrier);
pthread_mutex_lock(interlock);
if (barrier->ptb_curcount + 1 == barrier->ptb_initcount) {
barrier->ptb_generation++;
barrier->ptb_curcount = 0;
pthread__unpark_all(&barrier->ptb_waiters, self,
interlock);
pthread_mutex_unlock(interlock);
return PTHREAD_BARRIER_SERIAL_THREAD;
}
barrier->ptb_curcount++;
gen = barrier->ptb_generation;
for (;;) {
PTQ_INSERT_TAIL(&barrier->ptb_waiters, self, pt_sleep);
self->pt_sleepobj = &barrier->ptb_waiters;
(void)pthread__park(self, interlock, &barrier->ptb_waiters,
NULL, 0, __UNVOLATILE(&interlock->ptm_waiters));
if (__predict_true(gen != barrier->ptb_generation)) {
break;
}
pthread_mutex_lock(interlock);
if (gen != barrier->ptb_generation) {
pthread_mutex_unlock(interlock);
break;
}
}
return 0;
}
int
pthread_barrierattr_init(pthread_barrierattr_t *attr)
{
attr->ptba_magic = _PT_BARRIERATTR_MAGIC;
return 0;
}
int
pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
{
if (attr->ptba_magic != _PT_BARRIERATTR_MAGIC)
return EINVAL;
attr->ptba_magic = _PT_BARRIERATTR_DEAD;
return 0;
}

View File

@@ -0,0 +1,77 @@
.\" $NetBSD: pthread_barrierattr.3,v 1.9 2010/07/09 10:45:36 wiz Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd July 9, 2010
.Dt PTHREAD_BARRIERATTR 3
.Os
.Sh NAME
.Nm pthread_barrierattr_init ,
.Nm pthread_barrierattr_destroy ,
.Nd barrier attribute operations
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_barrierattr_init "pthread_barrierattr_t *attr"
.Ft int
.Fn pthread_barrierattr_destroy "pthread_barrierattr_t *attr"
.Sh DESCRIPTION
Barrier attributes are used to specify parameters to be used with
.Xr pthread_barrier_init 3 .
One attribute object can be used in multiple calls to
.Fn pthread_barrier_init ,
with or without modifications between calls.
.Pp
The
.Fn pthread_barrierattr_init
function initializes
.Fa attr
with the default barrier attributes.
.Pp
The
.Fn pthread_barrierattr_destroy
function destroys
.Fa attr .
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
No error codes are defined for
.Fn pthread_barrierattr_init .
.Pp
The
.Fn pthread_barrierattr_destroy
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa attr
is invalid.
.El
.Sh SEE ALSO
.Xr pthread_barrier_init 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,134 @@
.\" $NetBSD: pthread_cancel.3,v 1.6 2014/03/12 07:32:46 dholland Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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: src/lib/libpthread/man/pthread_cancel.3,v 1.7 2002/09/16 19:29:28 mini Exp $
.Dd July 9, 2010
.Dt PTHREAD_CANCEL 3
.Os
.Sh NAME
.Nm pthread_cancel
.Nd cancel execution of a thread
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_cancel "pthread_t thread"
.Sh DESCRIPTION
The
.Fn pthread_cancel
function requests that
.Fa thread
be canceled.
The target thread's cancelability state and type determines
whether and when the target thread reacts to the cancellation request.
.Bl -enum -offset 2n
.It
The cancelability
.Em state
of a thread is determined by the
.Xr pthread_setcancelstate 3
function.
The state can be either:
.Bl -bullet -offset 2n
.It
.Dv PTHREAD_CANCEL_ENABLE :
the cancelability type determines when the actual cancellation occurs.
This is the default.
.It
.Dv PTHREAD_CANCEL_DISABLE :
the request from
.Fn pthread_cancel
remains queued until the cancellation is enabled by the thread.
.El
.It
The cancellation
.Em type
of a thread is determined by the
.Xr pthread_setcanceltype 3
function.
The type can be either:
.Bl -bullet -offset 2n
.It
.Dv PTHREAD_CANCEL_DEFERRED :
the cancellation will be delayed until the thread calls
a function that is a cancellation point.
This is the default.
The available cancellation points are listed in
.Xr pthread_setcanceltype 3 .
.It
.Dv PTHREAD_CANCEL_ASYNCHRONOUS :
the thread can be canceled at any time.
.El
.El
.Pp
When the thread reacts to the cancellation request, the following occur:
.Bl -enum -offset 2n
.It
The cancellation cleanup handlers for the thread are called; see
.Xr pthread_cleanup_push 3 .
.It
When the last cancellation cleanup handler returns,
the thread-specific data destructor functions will be called for the thread.
.It
When the last destructor function returns, the thread will be terminated; see
.Xr pthread_exit 3 .
.El
.Pp
The cancellation processing in the target thread runs asynchronously with
respect to the calling thread returning from
.Fn pthread_cancel .
.Pp
A status of
.Dv PTHREAD_CANCELED
is made available to any threads joining with the target.
The symbolic
constant
.Dv PTHREAD_CANCELED
expands to a constant expression of type
.Ft (void *) ,
whose value matches no pointer to an object in memory nor the value
.Dv NULL .
.Sh RETURN VALUES
If successful, the
.Fn pthread_cancel
functions will return zero.
Otherwise an error number will be returned to
indicate the error.
.Sh ERRORS
The
.Fn pthread_cancel
function may fail if:
.Bl -tag -width Er
.It Bq Er ESRCH
No thread could be found corresponding to that specified by the given
thread ID.
.El
.Sh SEE ALSO
.Xr pthread_cleanup_pop 3 ,
.Xr pthread_join 3 ,
.Xr pthread_testcancel 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,641 @@
/* $NetBSD: pthread_cancelstub.c,v 1.38 2013/03/21 16:49:12 christos Exp $ */
/*-
* Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/* Disable namespace mangling, Fortification is useless here anyway. */
#undef _FORTIFY_SOURCE
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_cancelstub.c,v 1.38 2013/03/21 16:49:12 christos Exp $");
#ifndef lint
/*
* This is necessary because the names are always weak (they are not
* POSIX functions).
*/
#define fsync_range _fsync_range
#define pollts _pollts
/*
* XXX this is necessary to get the prototypes for the __sigsuspend14
* XXX and __msync13 internal names, instead of the application-visible
* XXX sigsuspend and msync names. It's kind of gross, but we're pretty
* XXX intimate with libc already.
*/
#define __LIBC12_SOURCE__
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <aio.h>
#include <errno.h>
#include <fcntl.h>
#include <mqueue.h>
#include <poll.h>
#include <stdarg.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/event.h>
#include <compat/sys/mman.h>
#include <compat/sys/poll.h>
#include <compat/sys/select.h>
#include <compat/sys/event.h>
#include <compat/sys/wait.h>
#include <compat/include/mqueue.h>
#include <compat/include/signal.h>
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
int pthread__cancel_stub_binder;
int _sys_accept(int, struct sockaddr *, socklen_t *);
int _sys___aio_suspend50(const struct aiocb * const [], int,
const struct timespec *);
int __aio_suspend50(const struct aiocb * const [], int,
const struct timespec *);
int _sys_close(int);
int _sys_connect(int, const struct sockaddr *, socklen_t);
int _sys_fcntl(int, int, ...);
int _sys_fdatasync(int);
int _sys_fsync(int);
int _sys_fsync_range(int, int, off_t, off_t);
int _sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
size_t, const struct timespec *);
int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
int _sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
const struct timespec *);
ssize_t _sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
const struct timespec *);
ssize_t _sys_msgrcv(int, void *, size_t, long, int);
int _sys_msgsnd(int, const void *, size_t, int);
int _sys___msync13(void *, size_t, int);
int _sys___nanosleep50(const struct timespec *, struct timespec *);
int __nanosleep50(const struct timespec *, struct timespec *);
int _sys_open(const char *, int, ...);
int _sys_poll(struct pollfd *, nfds_t, int);
int _sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
const sigset_t *);
ssize_t _sys_pread(int, void *, size_t, off_t);
int _sys___pselect50(int, fd_set *, fd_set *, fd_set *,
const struct timespec *, const sigset_t *);
ssize_t _sys_pwrite(int, const void *, size_t, off_t);
ssize_t _sys_read(int, void *, size_t);
ssize_t _sys_readv(int, const struct iovec *, int);
int _sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
int _sys___wait450(pid_t, int *, int, struct rusage *);
ssize_t _sys_write(int, const void *, size_t);
ssize_t _sys_writev(int, const struct iovec *, int);
int _sys___sigsuspend14(const sigset_t *);
int ____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
struct timespec * __restrict);
int __sigsuspend14(const sigset_t *);
#define TESTCANCEL(id) do { \
if (__predict_true(!__uselibcstub) && \
__predict_false((id)->pt_cancel)) \
pthread__cancelled(); \
} while (/*CONSTCOND*/0)
int
accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_accept(s, addr, addrlen);
TESTCANCEL(self);
return retval;
}
int
__aio_suspend50(const struct aiocb * const list[], int nent,
const struct timespec *timeout)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___aio_suspend50(list, nent, timeout);
TESTCANCEL(self);
return retval;
}
int
__kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
size_t nrev, const struct timespec *ts)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts);
TESTCANCEL(self);
return retval;
}
int
close(int d)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_close(d);
TESTCANCEL(self);
return retval;
}
int
connect(int s, const struct sockaddr *addr, socklen_t namelen)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_connect(s, addr, namelen);
TESTCANCEL(self);
return retval;
}
int
fcntl(int fd, int cmd, ...)
{
int retval;
pthread_t self;
va_list ap;
self = pthread__self();
TESTCANCEL(self);
va_start(ap, cmd);
retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
va_end(ap);
TESTCANCEL(self);
return retval;
}
int
fdatasync(int d)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_fdatasync(d);
TESTCANCEL(self);
return retval;
}
int
fsync(int d)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_fsync(d);
TESTCANCEL(self);
return retval;
}
int
fsync_range(int d, int f, off_t s, off_t e)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_fsync_range(d, f, s, e);
TESTCANCEL(self);
return retval;
}
int
mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
TESTCANCEL(self);
return retval;
}
ssize_t
mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
TESTCANCEL(self);
return retval;
}
int
__mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
unsigned msg_prio, const struct timespec *abst)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst);
TESTCANCEL(self);
return retval;
}
ssize_t
__mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
const struct timespec *abst)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst);
TESTCANCEL(self);
return retval;
}
ssize_t
msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
TESTCANCEL(self);
return retval;
}
int
msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
TESTCANCEL(self);
return retval;
}
int
__msync13(void *addr, size_t len, int flags)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___msync13(addr, len, flags);
TESTCANCEL(self);
return retval;
}
int
open(const char *path, int flags, ...)
{
int retval;
pthread_t self;
va_list ap;
self = pthread__self();
TESTCANCEL(self);
va_start(ap, flags);
retval = _sys_open(path, flags, va_arg(ap, mode_t));
va_end(ap);
TESTCANCEL(self);
return retval;
}
int
__nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
/*
* For now, just nanosleep. In the future, maybe pass a ucontext_t
* to _lwp_nanosleep() and allow it to recycle our kernel stack.
*/
retval = _sys___nanosleep50(rqtp, rmtp);
TESTCANCEL(self);
return retval;
}
int
poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_poll(fds, nfds, timeout);
TESTCANCEL(self);
return retval;
}
int
__pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
const sigset_t *sigmask)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___pollts50(fds, nfds, ts, sigmask);
TESTCANCEL(self);
return retval;
}
ssize_t
pread(int d, void *buf, size_t nbytes, off_t offset)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_pread(d, buf, nbytes, offset);
TESTCANCEL(self);
return retval;
}
int
__pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
sigmask);
TESTCANCEL(self);
return retval;
}
ssize_t
pwrite(int d, const void *buf, size_t nbytes, off_t offset)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_pwrite(d, buf, nbytes, offset);
TESTCANCEL(self);
return retval;
}
ssize_t
read(int d, void *buf, size_t nbytes)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_read(d, buf, nbytes);
TESTCANCEL(self);
return retval;
}
ssize_t
readv(int d, const struct iovec *iov, int iovcnt)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_readv(d, iov, iovcnt);
TESTCANCEL(self);
return retval;
}
int
__select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)
{
int retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
TESTCANCEL(self);
return retval;
}
pid_t
__wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
{
pid_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___wait450(wpid, status, options, rusage);
TESTCANCEL(self);
return retval;
}
ssize_t
write(int d, const void *buf, size_t nbytes)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_write(d, buf, nbytes);
TESTCANCEL(self);
return retval;
}
ssize_t
writev(int d, const struct iovec *iov, int iovcnt)
{
ssize_t retval;
pthread_t self;
self = pthread__self();
TESTCANCEL(self);
retval = _sys_writev(d, iov, iovcnt);
TESTCANCEL(self);
return retval;
}
int
__sigsuspend14(const sigset_t *sigmask)
{
pthread_t self;
int retval;
self = pthread__self();
TESTCANCEL(self);
retval = _sys___sigsuspend14(sigmask);
TESTCANCEL(self);
return retval;
}
int
__sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info,
const struct timespec * __restrict timeout)
{
pthread_t self;
int retval;
struct timespec tout, *tp;
if (timeout) {
tout = *timeout;
tp = &tout;
} else
tp = NULL;
self = pthread__self();
TESTCANCEL(self);
retval = ____sigtimedwait50(set, info, tp);
TESTCANCEL(self);
return retval;
}
int
sigwait(const sigset_t * __restrict set, int * __restrict sig)
{
pthread_t self;
int saved_errno;
int new_errno;
int retval;
self = pthread__self();
saved_errno = errno;
TESTCANCEL(self);
retval = ____sigtimedwait50(set, NULL, NULL);
TESTCANCEL(self);
new_errno = errno;
errno = saved_errno;
if (retval < 0) {
return new_errno;
}
*sig = retval;
return 0;
}
__strong_alias(_close, close)
__strong_alias(_fcntl, fcntl)
__strong_alias(_fdatasync, fdatasync)
__strong_alias(_fsync, fsync)
__weak_alias(fsync_range, _fsync_range)
__strong_alias(_mq_send, mq_send)
__strong_alias(_mq_receive, mq_receive)
__strong_alias(_msgrcv, msgrcv)
__strong_alias(_msgsnd, msgsnd)
__strong_alias(___msync13, __msync13)
__strong_alias(___nanosleep50, __nanosleep50)
__strong_alias(_open, open)
__strong_alias(_poll, poll)
__strong_alias(_pread, pread)
__strong_alias(_pwrite, pwrite)
__strong_alias(_read, read)
__strong_alias(_readv, readv)
__strong_alias(_sigwait, sigwait)
__strong_alias(_write, write)
__strong_alias(_writev, writev)
#endif /* !lint */

View File

@@ -0,0 +1,118 @@
.\" $NetBSD: pthread_cleanup_push.3,v 1.6 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
.\" 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.
.\" 3. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_cleanup_push.3,v 1.11 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_CLEANUP 3
.Os
.Sh NAME
.Nm pthread_cleanup_push ,
.Nm pthread_cleanup_pop
.Nd add and remove cleanup functions for thread exit
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft void
.Fn pthread_cleanup_push "void \*[lp]*cleanup_routine\*[rp]\*[lp]void *\*[rp]" "void *arg"
.Ft void
.Fn pthread_cleanup_pop "int execute"
.Sh DESCRIPTION
The
.Fn pthread_cleanup_push
function adds
.Fa cleanup_routine
to the top of the stack of cleanup handlers that
get called when the current thread exits.
.Pp
The
.Fn pthread_cleanup_pop
function pops the top cleanup routine off of the current threads cleanup
routine stack, and, if
.Fa execute
is non-zero, it will execute the function.
.Pp
When
.Fa cleanup_routine
is called, it is passed
.Fa arg
as its only argument.
.Pp
These functions may be implemented as macros which contain scope delimiters;
therefore, there must be a matching
.Fn pthread_cleanup_pop
for every
.Fn pthread_cleanup_push
at the same level of lexical scoping.
.Pp
The effect of calling
.Fn longjmp
or
.Fn siglongjmp
is undefined after a call to
.Fn pthread_cleanup_push
but before the matching call to
.Fn pthread_cleanup_pop
after the jump buffer was filled.
.Sh RETURN VALUES
Neither
.Fn pthread_cleanup_push
nor
.Fn pthread_cleanup_pop
returns a value.
.Sh ERRORS
None.
.Sh SEE ALSO
.Xr pthread_exit 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,208 @@
/* $NetBSD: pthread_compat.c,v 1.3 2014/01/31 20:44:01 christos Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software developed for The NetBSD Foundation
* by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* libc symbols that are not present before NetBSD 5.0.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_compat.c,v 1.3 2014/01/31 20:44:01 christos Exp $");
#include <sys/param.h>
#include <sys/syscall.h>
#include <sys/aio.h>
#include <lwp.h>
#include <unistd.h>
#include <sched.h>
#include "pthread.h"
#include "pthread_int.h"
static void __pthread_init(void) __attribute__((__constructor__, __used__));
void __libc_thr_init(void);
void __libc_atomic_init(void);
int _sys_sched_yield(void);
int _sys_aio_suspend(const struct aiocb * const[], int,
const struct timespec *);
int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
int _sys_mq_timedsend(mqd_t, const char *, size_t, unsigned,
const struct timespec *);
ssize_t _sys_mq_timedreceive(mqd_t, char *, size_t, unsigned *,
const struct timespec *);
static void
__pthread_init(void)
{
__libc_atomic_init();
__libc_thr_init();
}
int
_lwp_kill(lwpid_t a, int b)
{
return syscall(SYS__lwp_kill, a, b);
}
int
_lwp_detach(lwpid_t a)
{
return syscall(SYS__lwp_detach, a);
}
int
_lwp_park(clockid_t a, int b, const struct timespec *c, lwpid_t d,
const void *e, const void *f)
{
return syscall(SYS____lwp_park60, a, b, c, d, e, f);
}
int
_lwp_unpark(lwpid_t a, const void *b)
{
return syscall(SYS__lwp_unpark, a, b);
}
ssize_t
_lwp_unpark_all(const lwpid_t *a, size_t b, const void *c)
{
return (ssize_t)syscall(SYS__lwp_unpark_all, a, b, c);
}
int
_lwp_setname(lwpid_t a, const char *b)
{
return syscall(SYS__lwp_setname, a, b);
}
int
_lwp_getname(lwpid_t a, char *b, size_t c)
{
return syscall(SYS__lwp_getname, a, b, c);
}
int
_lwp_ctl(int a, struct lwpctl **b)
{
return syscall(SYS__lwp_ctl, a, b);
}
int
_sys_sched_yield(void)
{
return syscall(SYS_sched_yield);
}
int
sched_yield(void)
{
return syscall(SYS_sched_yield);
}
int
_sched_setaffinity(pid_t a, lwpid_t b, size_t c, const cpuset_t *d)
{
return syscall(SYS__sched_setaffinity, a, b, c, d);
}
int
_sched_getaffinity(pid_t a, lwpid_t b, size_t c, cpuset_t *d)
{
return syscall(SYS__sched_getaffinity, a, b, c, d);
}
int
_sched_setparam(pid_t a, lwpid_t b, int c, const struct sched_param *d)
{
return syscall(SYS__sched_setparam, a, b, c, d);
}
int
_sched_getparam(pid_t a, lwpid_t b, int *c, struct sched_param *d)
{
return syscall(SYS__sched_getparam, a, b, c, d);
}
int
_sys_aio_suspend(const struct aiocb * const a[], int b,
const struct timespec *c)
{
return syscall(SYS_aio_suspend, a, b, c);
}
int
_sys_mq_send(mqd_t a, const char *b, size_t c, unsigned d)
{
return syscall(SYS_mq_send, a, b, c, d);
}
ssize_t
_sys_mq_receive(mqd_t a, char *b, size_t c, unsigned *d)
{
return (ssize_t)syscall(SYS_mq_receive, a, b, c, d);
}
int
_sys_mq_timedsend(mqd_t a, const char *b, size_t c, unsigned d,
const struct timespec *e)
{
return syscall(SYS_mq_timedsend, a, b,c ,d, e);
}
ssize_t
_sys_mq_timedreceive(mqd_t a, char *b, size_t c, unsigned *d,
const struct timespec *e)
{
return (ssize_t)syscall(SYS_mq_timedreceive, a, b, c, d, e);
}

View File

@@ -0,0 +1,275 @@
.\" $NetBSD: pthread_cond.3,v 1.6 2012/11/12 23:11:05 uwe Exp $
.\"
.\" Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
.\" 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.
.\" 3. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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.
.\"
.\" ----------------------------------------------------------------------------
.Dd July 8, 2010
.Dt PTHREAD_COND 3
.Os
.Sh NAME
.Nm pthread_cond
.Nd condition variable interface
.Sh LIBRARY
.Lb libpthread
.\" ----------------------------------------------------------------------------
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_cond_init "pthread_cond_t * restrict cond" \
"const pthread_condattr_t * restrict attr"
.Vt pthread_cond_t cond No = Dv PTHREAD_COND_INITIALIZER;
.Ft int
.Fn pthread_cond_destroy "pthread_cond_t *cond"
.Ft int
.Fn pthread_cond_broadcast "pthread_cond_t *cond"
.Ft int
.Fn pthread_cond_signal "pthread_cond_t *cond"
.Ft int
.Fn pthread_cond_wait "pthread_cond_t * restrict cond" \
"pthread_mutex_t * restrict mutex"
.Ft int
.Fn pthread_cond_timedwait "pthread_cond_t * restrict cond" \
"pthread_mutex_t * restrict mutex" "const struct timespec * restrict abstime"
.\" ----------------------------------------------------------------------------
.Sh DESCRIPTION
Condition variables are intended to be used to communicate changes in
the state of data shared between threads.
Condition variables are always associated with a mutex to provide
synchronized access to the shared data.
A single predicate should always be associated with a
condition variable.
The predicate should identify a state of the
shared data that must be true before the thread proceeds.
.Pp
The
.Fn pthread_cond_init
function creates a new condition variable, with attributes specified with
.Fa attr .
If
.Fa attr
is
.Dv NULL
the default attributes are used.
The
.Fn pthread_cond_destroy
function frees the resources allocated by the condition variable
.Fa cond .
.Pp
The macro
.Dv PTHREAD_COND_INITIALIZER
can be used to initialize a condition variable when it can be statically
allocated and the default attributes are appropriate.
The effect is similar to calling
.Fn pthread_cond_init
with
.Fa attr
specified as
.Dv NULL ,
except that no error checking is done.
.Pp
.\" -----
The difference between
.Fn pthread_cond_broadcast
and
.Fn pthread_cond_signal
is that the former unblocks all threads waiting for the condition variable,
whereas the latter blocks only one waiting thread.
If no threads are waiting on
.Fa cond ,
neither function has any effect.
If more than one thread is blocked on a condition variable,
the used scheduling policy determines the order in which threads are unblocked.
The same mutex used for waiting must be held while calling either function.
Although neither function strictly enforces this requirement,
undefined behavior may follow if the mutex is not held.
.Pp
.\" -----
The
.Fn pthread_cond_wait
function atomically blocks the current thread waiting on the condition
variable specified by
.Fa cond ,
and unlocks the mutex specified by
.Fa mutex .
The
.Fn pthread_cond_timedwait
function behaves similarly, but unblocks also
if the system time reaches the time specified in
.Fa abstime ,
represented as
.Em struct timespec
(see
.Xr timespec 3 ) .
With both functions the waiting thread unblocks after another thread calls
.Fn pthread_cond_signal
or
.Fn pthread_cond_broadcast
with the same condition variable and by holding the same
.Fa mutex
that was associated with
.Fa cond
by either one of the blocking functions.
The current thread holds the lock on
.Fa mutex
upon return from either function.
.\" -----
.Pp
Note that a call to
.Fn pthread_cond_wait
or
.Fn pthread_cond_timedwait
may wake up spontaneously, without a call to
.Fn pthread_cond_signal
or
.Fn pthread_cond_broadcast .
The caller should prepare for this by invoking either function
within a predicate loop that tests whether the thread should proceed.
.Pp
.\" -----
As noted, when calling either function that waits on a condition variable,
a temporary binding is established between the condition variable
.Fa cond
and the mutex
.Fa mutex .
During this time, the effect of an attempt by any thread to wait on
that condition variable using a different mutex is undefined.
The same mutex must be held while broadcasting or signaling on
.Fa cond .
Additionally, the same mutex must be used for concurrent calls to
.Fn pthread_cond_wait
and
.Fn pthread_cond_timedwait .
Only when a condition variable is known to be quiescent may an application
change the mutex associated with it.
In this implementation, none of the functions enforce this requirement, but
if the mutex is not held or independent mutexes are used the resulting
behaviour is undefined.
.\" ----------------------------------------------------------------------------
.Sh RETURN VALUES
If successful, all functions return zero.
Otherwise, an error number will be returned to indicate the error.
.Sh ERRORS
The
.Fn pthread_cond_init
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa attr
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_cond_destroy
function may fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The variable
.Fa cond
is locked by another thread.
.It Bq Er EINVAL
The value specified by
.Fa cond
is invalid.
.El
.Pp
.\" -----
Both
.Fn pthread_cond_broadcast
and
.Fn pthread_cond_signal
may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa cond
is invalid.
.El
.Pp
.\" -----
Both
.Fn pthread_cond_wait
and
.Fn pthread_cond_timedwait
may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa cond
or the value specified by
.Fa mutex
is invalid.
.It Bq Er EPERM
The value specified by
.Fa mutex
was not locked in the condition wait.
.El
.Pp
The
.Fn pthread_cond_timedwait
function may additionally fail if:
.Bl -tag -width Er
.It Bq Er ETIMEDOUT
The system time has reached or exceeded the time specified in
.Fa abstime .
.El
.Sh SEE ALSO
.Xr pthread 3 ,
.Xr pthread_barrier 3 ,
.Xr pthread_condattr 3 ,
.Xr pthread_mutex 3 ,
.Xr pthread_rwlock 3 ,
.Xr pthread_spin 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,418 @@
/* $NetBSD: pthread_cond.c,v 1.63 2014/01/31 20:44:01 christos Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* We assume that there will be no contention on pthread_cond_t::ptc_lock
* because functioning applications must call both the wait and wakeup
* functions while holding the same application provided mutex. The
* spinlock is present only to prevent libpthread causing the application
* to crash or malfunction as a result of corrupted data structures, in
* the event that the application is buggy.
*
* If there is contention on spinlock when real-time threads are in use,
* it could cause a deadlock due to priority inversion: the thread holding
* the spinlock may not get CPU time to make forward progress and release
* the spinlock to a higher priority thread that is waiting for it.
* Contention on the spinlock will only occur with buggy applications,
* so at the time of writing it's not considered a major bug in libpthread.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_cond.c,v 1.63 2014/01/31 20:44:01 christos Exp $");
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
int _sys___nanosleep50(const struct timespec *, struct timespec *);
extern int pthread__started;
static int pthread_cond_wait_nothread(pthread_t, pthread_mutex_t *,
pthread_cond_t *, const struct timespec *);
int _pthread_cond_has_waiters_np(pthread_cond_t *);
__weak_alias(pthread_cond_has_waiters_np,_pthread_cond_has_waiters_np)
__strong_alias(__libc_cond_init,pthread_cond_init)
__strong_alias(__libc_cond_signal,pthread_cond_signal)
__strong_alias(__libc_cond_broadcast,pthread_cond_broadcast)
__strong_alias(__libc_cond_wait,pthread_cond_wait)
__strong_alias(__libc_cond_timedwait,pthread_cond_timedwait)
__strong_alias(__libc_cond_destroy,pthread_cond_destroy)
static clockid_t
pthread_cond_getclock(const pthread_cond_t *cond)
{
return cond->ptc_private ?
*(clockid_t *)cond->ptc_private : CLOCK_REALTIME;
}
int
pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
if (__predict_false(__uselibcstub))
return __libc_cond_init_stub(cond, attr);
pthread__error(EINVAL, "Invalid condition variable attribute",
(attr == NULL) || (attr->ptca_magic == _PT_CONDATTR_MAGIC));
cond->ptc_magic = _PT_COND_MAGIC;
pthread_lockinit(&cond->ptc_lock);
PTQ_INIT(&cond->ptc_waiters);
cond->ptc_mutex = NULL;
if (attr && attr->ptca_private) {
cond->ptc_private = malloc(sizeof(clockid_t));
if (cond->ptc_private == NULL)
return errno;
*(clockid_t *)cond->ptc_private =
*(clockid_t *)attr->ptca_private;
} else
cond->ptc_private = NULL;
return 0;
}
int
pthread_cond_destroy(pthread_cond_t *cond)
{
if (__predict_false(__uselibcstub))
return __libc_cond_destroy_stub(cond);
pthread__error(EINVAL, "Invalid condition variable",
cond->ptc_magic == _PT_COND_MAGIC);
pthread__error(EBUSY, "Destroying condition variable in use",
cond->ptc_mutex == NULL);
cond->ptc_magic = _PT_COND_DEAD;
free(cond->ptc_private);
return 0;
}
int
pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime)
{
pthread_t self;
int retval;
clockid_t clkid = pthread_cond_getclock(cond);
if (__predict_false(__uselibcstub))
return __libc_cond_timedwait_stub(cond, mutex, abstime);
pthread__error(EINVAL, "Invalid condition variable",
cond->ptc_magic == _PT_COND_MAGIC);
pthread__error(EINVAL, "Invalid mutex",
mutex->ptm_magic == _PT_MUTEX_MAGIC);
pthread__error(EPERM, "Mutex not locked in condition wait",
mutex->ptm_owner != NULL);
self = pthread__self();
/* Just hang out for a while if threads aren't running yet. */
if (__predict_false(pthread__started == 0)) {
return pthread_cond_wait_nothread(self, mutex, cond, abstime);
}
if (__predict_false(self->pt_cancel)) {
pthread__cancelled();
}
/* Note this thread as waiting on the CV. */
pthread__spinlock(self, &cond->ptc_lock);
cond->ptc_mutex = mutex;
PTQ_INSERT_HEAD(&cond->ptc_waiters, self, pt_sleep);
self->pt_sleepobj = cond;
pthread__spinunlock(self, &cond->ptc_lock);
do {
self->pt_willpark = 1;
pthread_mutex_unlock(mutex);
self->pt_willpark = 0;
self->pt_blocking++;
do {
retval = _lwp_park(clkid, TIMER_ABSTIME, abstime,
self->pt_unpark, __UNVOLATILE(&mutex->ptm_waiters),
__UNVOLATILE(&mutex->ptm_waiters));
self->pt_unpark = 0;
} while (retval == -1 && errno == ESRCH);
self->pt_blocking--;
membar_sync();
pthread_mutex_lock(mutex);
/*
* If we have cancelled then exit. POSIX dictates that
* the mutex must be held when we action the cancellation.
*
* If we absorbed a pthread_cond_signal() and cannot take
* the wakeup, we must ensure that another thread does.
*
* If awoke early, we may still be on the sleep queue and
* must remove ourself.
*/
if (__predict_false(retval != 0)) {
switch (errno) {
case EINTR:
case EALREADY:
retval = 0;
break;
default:
retval = errno;
break;
}
}
if (__predict_false(self->pt_cancel | retval)) {
pthread_cond_signal(cond);
if (self->pt_cancel) {
pthread__cancelled();
}
break;
}
} while (self->pt_sleepobj != NULL);
return retval;
}
int
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
if (__predict_false(__uselibcstub))
return __libc_cond_wait_stub(cond, mutex);
return pthread_cond_timedwait(cond, mutex, NULL);
}
static int __noinline
pthread__cond_wake_one(pthread_cond_t *cond)
{
pthread_t self, signaled;
pthread_mutex_t *mutex;
lwpid_t lid;
pthread__error(EINVAL, "Invalid condition variable",
cond->ptc_magic == _PT_COND_MAGIC);
/*
* Pull the first thread off the queue. If the current thread
* is associated with the condition variable, remove it without
* awakening (error case in pthread_cond_timedwait()).
*/
self = pthread__self();
pthread__spinlock(self, &cond->ptc_lock);
if (self->pt_sleepobj == cond) {
PTQ_REMOVE(&cond->ptc_waiters, self, pt_sleep);
self->pt_sleepobj = NULL;
}
signaled = PTQ_FIRST(&cond->ptc_waiters);
if (__predict_false(signaled == NULL)) {
cond->ptc_mutex = NULL;
pthread__spinunlock(self, &cond->ptc_lock);
return 0;
}
mutex = cond->ptc_mutex;
if (PTQ_NEXT(signaled, pt_sleep) == NULL) {
cond->ptc_mutex = NULL;
PTQ_INIT(&cond->ptc_waiters);
} else {
PTQ_REMOVE(&cond->ptc_waiters, signaled, pt_sleep);
}
signaled->pt_sleepobj = NULL;
lid = signaled->pt_lid;
pthread__spinunlock(self, &cond->ptc_lock);
/*
* For all valid uses of pthread_cond_signal(), the caller will
* hold the mutex that the target is using to synchronize with.
* To avoid the target awakening and immediately blocking on the
* mutex, transfer the thread to be awoken to the current thread's
* deferred wakeup list. The waiter will be set running when the
* caller (this thread) releases the mutex.
*/
if (__predict_false(self->pt_nwaiters == (size_t)pthread__unpark_max)) {
(void)_lwp_unpark_all(self->pt_waiters, self->pt_nwaiters,
__UNVOLATILE(&mutex->ptm_waiters));
self->pt_nwaiters = 0;
}
self->pt_waiters[self->pt_nwaiters++] = lid;
pthread__mutex_deferwake(self, mutex);
return 0;
}
int
pthread_cond_signal(pthread_cond_t *cond)
{
if (__predict_false(__uselibcstub))
return __libc_cond_signal_stub(cond);
if (__predict_true(PTQ_EMPTY(&cond->ptc_waiters)))
return 0;
return pthread__cond_wake_one(cond);
}
static int __noinline
pthread__cond_wake_all(pthread_cond_t *cond)
{
pthread_t self, signaled;
pthread_mutex_t *mutex;
u_int max;
size_t nwaiters;
pthread__error(EINVAL, "Invalid condition variable",
cond->ptc_magic == _PT_COND_MAGIC);
/*
* Try to defer waking threads (see pthread_cond_signal()).
* Only transfer waiters for which there is no pending wakeup.
*/
self = pthread__self();
pthread__spinlock(self, &cond->ptc_lock);
max = pthread__unpark_max;
mutex = cond->ptc_mutex;
nwaiters = self->pt_nwaiters;
PTQ_FOREACH(signaled, &cond->ptc_waiters, pt_sleep) {
if (__predict_false(nwaiters == max)) {
/* Overflow. */
(void)_lwp_unpark_all(self->pt_waiters,
nwaiters, __UNVOLATILE(&mutex->ptm_waiters));
nwaiters = 0;
}
signaled->pt_sleepobj = NULL;
self->pt_waiters[nwaiters++] = signaled->pt_lid;
}
PTQ_INIT(&cond->ptc_waiters);
self->pt_nwaiters = nwaiters;
cond->ptc_mutex = NULL;
pthread__spinunlock(self, &cond->ptc_lock);
pthread__mutex_deferwake(self, mutex);
return 0;
}
int
pthread_cond_broadcast(pthread_cond_t *cond)
{
if (__predict_false(__uselibcstub))
return __libc_cond_broadcast_stub(cond);
if (__predict_true(PTQ_EMPTY(&cond->ptc_waiters)))
return 0;
return pthread__cond_wake_all(cond);
}
int
_pthread_cond_has_waiters_np(pthread_cond_t *cond)
{
return !PTQ_EMPTY(&cond->ptc_waiters);
}
int
pthread_condattr_init(pthread_condattr_t *attr)
{
attr->ptca_magic = _PT_CONDATTR_MAGIC;
attr->ptca_private = NULL;
return 0;
}
int
pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clck)
{
switch (clck) {
case CLOCK_MONOTONIC:
case CLOCK_REALTIME:
if (attr->ptca_private == NULL)
attr->ptca_private = malloc(sizeof(clockid_t));
if (attr->ptca_private == NULL)
return errno;
*(clockid_t *)attr->ptca_private = clck;
return 0;
default:
return EINVAL;
}
}
int
pthread_condattr_destroy(pthread_condattr_t *attr)
{
pthread__error(EINVAL, "Invalid condition variable attribute",
attr->ptca_magic == _PT_CONDATTR_MAGIC);
attr->ptca_magic = _PT_CONDATTR_DEAD;
free(attr->ptca_private);
return 0;
}
/* Utility routine to hang out for a while if threads haven't started yet. */
static int
pthread_cond_wait_nothread(pthread_t self, pthread_mutex_t *mutex,
pthread_cond_t *cond, const struct timespec *abstime)
{
struct timespec now, diff;
int retval;
if (abstime == NULL) {
diff.tv_sec = 99999999;
diff.tv_nsec = 0;
} else {
clockid_t clck = pthread_cond_getclock(cond);
clock_gettime(clck, &now);
if (timespeccmp(abstime, &now, <))
timespecclear(&diff);
else
timespecsub(abstime, &now, &diff);
}
do {
pthread__testcancel(self);
pthread_mutex_unlock(mutex);
retval = _sys___nanosleep50(&diff, NULL);
pthread_mutex_lock(mutex);
} while (abstime == NULL && retval == 0);
pthread__testcancel(self);
if (retval == 0)
return ETIMEDOUT;
else
/* spurious wakeup */
return 0;
}

View File

@@ -0,0 +1,117 @@
.\" $NetBSD: pthread_condattr.3,v 1.9 2012/11/03 09:20:36 wiz Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
.\" the first lines of this file unmodified other than the possible
.\" addition of one or more copyright notices.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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: src/lib/libpthread/man/pthread_condattr.3,v 1.10 2002/09/16 19:29:28 mini Exp $
.Dd November 2, 2012
.Dt PTHREAD_CONDATTR 3
.Os
.Sh NAME
.Nm pthread_condattr_init
.Nd condition attribute operations
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_condattr_init "pthread_condattr_t *attr"
.Ft int
.Fn pthread_condattr_setclock "pthread_condattr_t *attr" "clockid_t clock"
.Ft int
.Fn pthread_condattr_destroy "pthread_condattr_t *attr"
.Sh DESCRIPTION
Condition attribute objects are used to specify parameters to the
.Xr pthread_cond_init 3
function.
The
.Fn pthread_condattr_init
function initializes a condition attribute object with the default attributes
and the
.Fn pthread_condattr_destroy
function destroys a condition attribute object.
The
.Fn pthread_condattr_setclock
function sets the system clock to be used for time comparisons to
the one specified in
.Fa clock .
Valid clock values are
.Dv CLOCK_MONOTONIC
and
.Dv CLOCK_REALTIME
(the default).
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
No errors are defined for
.Fn pthread_condattr_init .
.Pp
The
.Fn pthread_condattr_destroy
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa attr
is invalid.
.El
.Sh SEE ALSO
.Xr pthread_cond_init 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .
.Sh CAVEATS
The usefulness of the functions is questionable as the
.Nx
implementation does not support any non-default attributes.
These functions do not conform to the
.St -p1003.1-2008
revision of the standard, which mandates two additional attributes,
the clock attribute and the process-shared attribute.

View File

@@ -0,0 +1,157 @@
.\" $NetBSD: pthread_create.3,v 1.7 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_create.3,v 1.16 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_CREATE 3
.Os
.Sh NAME
.Nm pthread_create
.Nd create a new thread
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_create "pthread_t * restrict thread" "const pthread_attr_t * restrict attr" "void *(*start_routine)(void *)" "void * restrict arg"
.Sh DESCRIPTION
The
.Fn pthread_create
function is used to create a new thread, with attributes specified by
.Fa attr ,
within a process.
If
.Fa attr
is
.Dv NULL ,
the default attributes are used.
.Pp
The attributes specified via
.Fa attr
are copied into the new thread.
Any subsequent modifications to the attributes object
.Fa attr
points to will have no effect upon already-created threads.
It is thus also safe to pass the same
.Fa attr
to multiple calls to
.Fn pthread_create .
.Pp
Upon
successful completion
.Fn pthread_create
will store the ID of the created thread in the location specified by
.Fa thread .
The thread is created executing
.Fa start_routine
with
.Fa arg
as its sole argument.
.Pp
If the
.Fa start_routine
returns, the effect is as if there was an implicit call to
.Fn pthread_exit
using the return value of
.Fa start_routine
as the exit status.
Note that the thread in which
.Fn main
was originally invoked differs from this.
When it returns from
.Fn main ,
the effect is as if there was an implicit call to
.Fn exit
using the return value of
.Fn main
as the exit status.
.Pp
The signal state of the new thread is initialized as:
.Bl -bullet -offset indent
.It
The signal mask is inherited from the creating thread.
.It
The set of signals pending for the new thread is empty.
.El
.Sh RETURN VALUES
If successful, the
.Fn pthread_create
function will return zero.
Otherwise an error number will be returned to
indicate the error.
.Sh ERRORS
.Fn pthread_create
shall fail if:
.Bl -tag -width Er
.It Bq Er EAGAIN
The system lacks the necessary resources to create another thread, or
the system-imposed limit on the total number of threads in a process
.Dv PTHREAD_THREADS_MAX
would be exceeded.
.It Bq Er EINVAL
The value specified by
.Fa attr
is invalid.
.El
.Sh SEE ALSO
.Xr fork 2 ,
.Xr pthread_attr 3 ,
.Xr pthread_cleanup_pop 3 ,
.Xr pthread_cleanup_push 3 ,
.Xr pthread_exit 3 ,
.Xr pthread_join 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,66 @@
.\" $NetBSD: pthread_curcpu_np.3,v 1.2 2011/11/10 16:44:47 wiz Exp $
.\"
.\" Copyright (c)2011 YAMAMOTO Takashi,
.\" 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.
.\"
.\" ------------------------------------------------------------
.Dd November 10, 2011
.Dt PTHREAD_CURCPU_NP 3
.Os
.\" ------------------------------------------------------------
.Sh NAME
.Nm pthread_curcpu_np
.Nd get current CPU identifier
.\" ------------------------------------------------------------
.Sh SYNOPSIS
.In pthread.h
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.Ft unsigned int
.Fn pthread_curcpu_np \
"void"
.\" ------------------------------------------------------------
.Sh DESCRIPTION
The
.Fn pthread_curcpu_np
function provides a way for a thread to know which CPU it's currently running
on.
.Pp
Note that, unless the thread is bound to a specific CPU, the result might be
already stale when the function returns.
However, it still can be useful as a hint to achieve better CPU locality.
.\" ------------------------------------------------------------
.Sh RETURN VALUES
The
.Fn pthread_curcpu_np
function returns the integer identifier of the CPU which is currently
running the calling thread.
.\" ------------------------------------------------------------
.Sh COMPATIBILITY
The
.Fn pthread_curcpu_np
function is a non-standard extension.
.\" ------------------------------------------------------------
.Sh SEE ALSO
.Xr affinity 3 ,
.Xr pthread 3

View File

@@ -0,0 +1,108 @@
.\" $NetBSD: pthread_detach.3,v 1.4 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_detach.3,v 1.13 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_DETACH 3
.Os
.Sh NAME
.Nm pthread_detach
.Nd detach a thread
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_detach "pthread_t thread"
.Sh DESCRIPTION
The
.Fn pthread_detach
function is used to indicate to the implementation that storage for the
thread
.Fa thread
can be reclaimed when the thread terminates.
If
.Fa thread
has not terminated,
.Fn pthread_detach
will not cause it to terminate.
The effect of multiple
.Fn pthread_detach
calls on the same target thread is unspecified.
.Sh RETURN VALUES
If successful, the
.Fn pthread_detach
function will return zero.
Otherwise an error number will be returned to
indicate the error.
.Sh ERRORS
.Fn pthread_detach
shall fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa thread
does not refer to a joinable thread.
.It Bq Er ESRCH
No thread could be found corresponding to that specified by the given
thread ID,
.Fa thread .
.El
.Sh SEE ALSO
.Xr pthread_join 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,92 @@
.\" $NetBSD: pthread_equal.3,v 1.4 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_equal.3,v 1.11 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_EQUAL 3
.Os
.Sh NAME
.Nm pthread_equal
.Nd compare thread IDs
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_equal "pthread_t t1" "pthread_t t2"
.Sh DESCRIPTION
The
.Fn pthread_equal
function compares the thread IDs
.Fa t1
and
.Fa t2 .
.Sh RETURN VALUES
The
.Fn pthread_equal
function will return non-zero if the thread IDs
.Fa t1
and
.Fa t2
correspond to the same thread, otherwise it will return zero.
.Sh ERRORS
None.
.Sh SEE ALSO
.Xr pthread_create 3 ,
.Xr pthread_exit 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,129 @@
.\" $NetBSD: pthread_exit.3,v 1.5 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_exit.3,v 1.16 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_EXIT 3
.Os
.Sh NAME
.Nm pthread_exit
.Nd terminate the calling thread
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft void
.Fn pthread_exit "void *value_ptr"
.Sh DESCRIPTION
The
.Fn pthread_exit
function terminates the calling thread and makes the value
.Fa value_ptr
available to any successful join with the terminating thread.
Any
cancellation cleanup handlers that have been pushed and are not yet popped
are popped in the reverse order that they were pushed and then executed.
After all cancellation handlers have been executed, if the thread has any
thread-specific data, appropriate destructor functions are called in an
unspecified order.
Thread termination does not release any application
visible process resources, including, but not limited to, mutexes and
file descriptors, nor does it perform any process level cleanup
actions, including, but not limited to, calling
.Fn atexit
routines that may exist.
.Pp
An implicit call to
.Fn pthread_exit
is made when a thread other than the thread in which
.Fn main
was first invoked returns from the start routine that was used to create
it.
The function's return value serves as the thread's exit status.
.Pp
The behavior of
.Fn pthread_exit
is undefined if called from a cancellation handler or destructor function
that was invoked as the result of an implicit or explicit call to
.Fn pthread_exit .
.Pp
After a thread has terminated, the result of access to local (auto)
variables of the thread is undefined.
Thus, references to local variables
of the exiting thread should not be used for the
.Fn pthread_exit
.Fa value_ptr
parameter value.
.Pp
The process will exit with an exit status of 0 after the last thread has
been terminated.
The behavior is as if the implementation called
.Fn exit
with a zero argument at thread termination time.
.Sh RETURN VALUES
The
.Fn pthread_exit
function cannot return to its caller.
.Sh ERRORS
None.
.Sh SEE ALSO
.Xr _exit 2 ,
.Xr exit 3 ,
.Xr pthread_create 3 ,
.Xr pthread_join 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,107 @@
.\" $NetBSD: pthread_getname_np.3,v 1.4 2010/07/09 07:31:01 jruoho Exp $
.\"
.\" Copyright (c)2007 YAMAMOTO Takashi,
.\" 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.
.\"
.\" ------------------------------------------------------------
.Dd July 9, 2010
.Dt PTHREAD_GETNAME_NP 3
.Os
.Sh NAME
.Nm pthread_getname_np
.Nd get and set descriptive name of a thread
.\" ------------------------------------------------------------
.Sh LIBRARY
.Lb libpthread
.\" ------------------------------------------------------------
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_getname_np "pthread_t thread" "char *name" "size_t len"
.Ft int
.Fn pthread_setname_np "pthread_t thread" "const char *name" "void *arg"
.\" ------------------------------------------------------------
.Sh DESCRIPTION
The
.Fn pthread_getname_np
function obtains the descriptive name of a thread.
It takes the following arguments:
.Bl -tag -width target -offset indent
.It Fa thread
The thread whose descriptive name will be obtained.
.It Fa name
The buffer to be filled with the descriptive name of the thread.
.It Fa len
The size of the buffer
.Fa name
in bytes.
.El
.Pp
The
.Fn pthread_setname_np
function sets the descriptive name of a thread.
It takes the following arguments:
.Bl -tag -width target -offset indent
.It Fa thread
The thread whose descriptive name will be set.
.It Fa name
The
.Xr printf 3
format string to be used to construct the descriptive name of the thread.
The resulted descriptive name should be shorter than
.Dv PTHREAD_MAX_NAMELEN_NP .
.It Fa arg
The
.Xr printf 3
argument used with
.Fa name .
.El
.\" ------------------------------------------------------------
.Sh RETURN VALUES
Both functions return 0 on success.
Otherwise, an error number is returned to indicate the error.
.\" ------------------------------------------------------------
.Sh COMPATIBILITY
Both functions are non-standard extensions.
.\" ------------------------------------------------------------
.Sh ERRORS
Both functions may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
Invalid parameter.
.It Bq Er ESRCH
Non-existent
.Fa thread .
.El
.Pp
The
.Fn pthread_setname_np
function may also fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
There was insufficient memory for the operation.
.El
.Sh SEE ALSO
.Xr pthread_attr_get_np 3 ,
.Xr pthread_attr_getname_np 3

View File

@@ -0,0 +1,123 @@
.\" $NetBSD: pthread_getspecific.3,v 1.5 2010/07/09 10:49:48 wiz Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_getspecific.3,v 1.11 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_GETSPECIFIC 3
.Os
.Sh NAME
.Nm pthread_getspecific
.Nd thread-specific data value
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft void *
.Fn pthread_getspecific "pthread_key_t key"
.Ft int
.Fn pthread_setspecific "pthread_key_t key" "const void *value"
.Sh DESCRIPTION
The
.Fn pthread_getspecific
function returns the value currently bound to the specified
.Fa key
on behalf of the calling thread.
Conversely, the
.Fn pthread_setspecific
function associates a thread-specific value with a
.Fa key
obtained via a previous call to
.Xr pthread_key_create 3 .
Different threads have different values bound to each key.
These values are typically pointers to blocks of dynamically
allocated memory that have been reserved for use by the calling thread.
.Pp
Undefined behavior may follow if either function is called with a
.Fa key
value not obtained from
.Xr pthread_key_create 3 ,
or if the call is made after
.Fa key
has been deleted with
.Xr pthread_key_delete 3 .
It is possible to call either function from
a thread-specific data destructor function.
Note however that this is not well defined for the
.Fn pthread_setspecific
function;
lost storage or infinite loops may occur.
.Sh RETURN VALUES
The
.Fn pthread_getspecific
function will return 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
.Dv NULL
is returned.
If successful, the
.Fn pthread_setspecific
function will return zero.
Otherwise an error number will be returned to
indicate the error.
.Sh ERRORS
No errors are defined for either function.
.Sh SEE ALSO
.Xr pthread_key_create 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,333 @@
/* $NetBSD: pthread_int.h,v 1.92 2015/05/29 16:05:13 christos Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* NOTE: when changing anything in this file, please ensure that
* libpthread_dbg still compiles.
*/
#ifndef _LIB_PTHREAD_INT_H
#define _LIB_PTHREAD_INT_H
#include <sys/tls.h>
/* #define PTHREAD__DEBUG */
#define ERRORCHECK
#include "pthread_types.h"
#include "pthread_queue.h"
#include "pthread_md.h"
/* Need to use libc-private names for atomic operations. */
#include "../../common/lib/libc/atomic/atomic_op_namespace.h"
#include <sys/atomic.h>
#include <sys/rbtree.h>
#include <limits.h>
#include <lwp.h>
#include <signal.h>
#include <stdbool.h>
#ifdef __GNUC__
#define PTHREAD_HIDE __attribute__ ((visibility("hidden")))
#else
#define PTHREAD_HIDE /* nothing */
#endif
#define PTHREAD__UNPARK_MAX 32
/*
* The size of this structure needs to be no larger than struct
* __pthread_cleanup_store, defined in pthread.h.
*/
struct pt_clean_t {
PTQ_ENTRY(pt_clean_t) ptc_next;
void (*ptc_cleanup)(void *);
void *ptc_arg;
};
/* Private data for pthread_attr_t */
struct pthread_attr_private {
char ptap_name[PTHREAD_MAX_NAMELEN_NP];
void *ptap_namearg;
void *ptap_stackaddr;
size_t ptap_stacksize;
size_t ptap_guardsize;
struct sched_param ptap_sp;
int ptap_policy;
};
struct pthread_lock_ops {
void (*plo_init)(__cpu_simple_lock_t *);
int (*plo_try)(__cpu_simple_lock_t *);
void (*plo_unlock)(__cpu_simple_lock_t *);
void (*plo_lock)(__cpu_simple_lock_t *);
};
struct __pthread_st {
pthread_t pt_self; /* Must be first. */
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
struct tls_tcb *pt_tls; /* Thread Local Storage area */
#endif
unsigned int pt_magic; /* Magic number */
int pt_state; /* running, blocked, etc. */
pthread_mutex_t pt_lock; /* lock on state */
int pt_flags; /* see PT_FLAG_* below */
int pt_cancel; /* Deferred cancellation */
int pt_errno; /* Thread-specific errno. */
stack_t pt_stack; /* Our stack */
bool pt_stack_allocated;
size_t pt_guardsize;
void *pt_exitval; /* Read by pthread_join() */
char *pt_name; /* Thread's name, set by the app. */
int pt_willpark; /* About to park */
lwpid_t pt_unpark; /* Unpark this when parking */
struct pthread_lock_ops pt_lockops;/* Cached to avoid PIC overhead */
pthread_mutex_t *pt_droplock; /* Drop this lock if cancelled */
pthread_cond_t pt_joiners; /* Threads waiting to join. */
void *(*pt_func)(void *);/* Function to call at start. */
void *pt_arg; /* Argument to pass at start. */
/* Threads to defer waking, usually until pthread_mutex_unlock(). */
lwpid_t pt_waiters[PTHREAD__UNPARK_MAX];
size_t pt_nwaiters;
/* Stack of cancellation cleanup handlers and their arguments */
PTQ_HEAD(, pt_clean_t) pt_cleanup_stack;
/* LWP ID and entry on the list of all threads. */
lwpid_t pt_lid;
rb_node_t pt_alltree;
PTQ_ENTRY(__pthread_st) pt_allq;
PTQ_ENTRY(__pthread_st) pt_deadq;
/*
* General synchronization data. We try to align, as threads
* on other CPUs will access this data frequently.
*/
int pt_dummy1 __aligned(128);
struct lwpctl *pt_lwpctl; /* Kernel/user comms area */
volatile int pt_blocking; /* Blocking in userspace */
volatile int pt_rwlocked; /* Handed rwlock successfully */
volatile int pt_signalled; /* Received pthread_cond_signal() */
volatile int pt_mutexwait; /* Waiting to acquire mutex */
void * volatile pt_mutexnext; /* Next thread in chain */
void * volatile pt_sleepobj; /* Object slept on */
PTQ_ENTRY(__pthread_st) pt_sleep;
void (*pt_early)(void *);
int pt_dummy2 __aligned(128);
/* Thread-specific data. Large so it sits close to the end. */
int pt_havespecific;
struct pt_specific {
void *pts_value;
PTQ_ENTRY(pt_specific) pts_next;
} pt_specific[];
};
/* Thread states */
#define PT_STATE_RUNNING 1
#define PT_STATE_ZOMBIE 5
#define PT_STATE_DEAD 6
/* Flag values */
#define PT_FLAG_DETACHED 0x0001
#define PT_FLAG_CS_DISABLED 0x0004 /* Cancellation disabled */
#define PT_FLAG_CS_ASYNC 0x0008 /* Cancellation is async */
#define PT_FLAG_CS_PENDING 0x0010
#define PT_FLAG_SCOPE_SYSTEM 0x0040
#define PT_FLAG_EXPLICIT_SCHED 0x0080
#define PT_FLAG_SUSPENDED 0x0100 /* In the suspended queue */
#define PT_MAGIC 0x11110001
#define PT_DEAD 0xDEAD0001
#define PT_ATTR_MAGIC 0x22220002
#define PT_ATTR_DEAD 0xDEAD0002
extern size_t pthread__stacksize;
extern size_t pthread__pagesize;
extern int pthread__nspins;
extern int pthread__concurrency;
extern int pthread__osrev;
extern int pthread__unpark_max;
extern int pthread_keys_max;
extern int __uselibcstub;
/* Flag to be used in a ucontext_t's uc_flags indicating that
* the saved register state is "user" state only, not full
* trap state.
*/
#define _UC_USER_BIT 30
#define _UC_USER (1LU << _UC_USER_BIT)
/* Utility functions */
void pthread__unpark_all(pthread_queue_t *, pthread_t, pthread_mutex_t *)
PTHREAD_HIDE;
void pthread__unpark(pthread_queue_t *, pthread_t, pthread_mutex_t *)
PTHREAD_HIDE;
int pthread__park(pthread_t, pthread_mutex_t *, pthread_queue_t *,
const struct timespec *, int, const void *)
PTHREAD_HIDE;
pthread_mutex_t *pthread__hashlock(volatile const void *) PTHREAD_HIDE;
/* Internal locking primitives */
void pthread__lockprim_init(void) PTHREAD_HIDE;
void pthread_lockinit(pthread_spin_t *) PTHREAD_HIDE;
static inline void pthread__spinlock(pthread_t, pthread_spin_t *)
__attribute__((__always_inline__));
static inline void
pthread__spinlock(pthread_t self, pthread_spin_t *lock)
{
if (__predict_true((*self->pt_lockops.plo_try)(lock)))
return;
(*self->pt_lockops.plo_lock)(lock);
}
static inline int pthread__spintrylock(pthread_t, pthread_spin_t *)
__attribute__((__always_inline__));
static inline int
pthread__spintrylock(pthread_t self, pthread_spin_t *lock)
{
return (*self->pt_lockops.plo_try)(lock);
}
static inline void pthread__spinunlock(pthread_t, pthread_spin_t *)
__attribute__((__always_inline__));
static inline void
pthread__spinunlock(pthread_t self, pthread_spin_t *lock)
{
(*self->pt_lockops.plo_unlock)(lock);
}
extern const struct pthread_lock_ops *pthread__lock_ops;
int pthread__simple_locked_p(__cpu_simple_lock_t *) PTHREAD_HIDE;
#define pthread__simple_lock_init(alp) (*pthread__lock_ops->plo_init)(alp)
#define pthread__simple_lock_try(alp) (*pthread__lock_ops->plo_try)(alp)
#define pthread__simple_unlock(alp) (*pthread__lock_ops->plo_unlock)(alp)
void pthread__testcancel(pthread_t) PTHREAD_HIDE;
int pthread__find(pthread_t) PTHREAD_HIDE;
#ifndef PTHREAD_MD_INIT
#define PTHREAD_MD_INIT
#endif
#ifndef _INITCONTEXT_U_MD
#define _INITCONTEXT_U_MD(ucp)
#endif
#define _INITCONTEXT_U(ucp) do { \
(ucp)->uc_flags = _UC_CPU | _UC_STACK; \
_INITCONTEXT_U_MD(ucp) \
} while (/*CONSTCOND*/0)
#if !defined(__HAVE_TLS_VARIANT_I) && !defined(__HAVE_TLS_VARIANT_II)
#error Either __HAVE_TLS_VARIANT_I or __HAVE_TLS_VARIANT_II must be defined
#endif
#ifdef _PTHREAD_GETTCB_EXT
struct tls_tcb *_PTHREAD_GETTCB_EXT(void);
#endif
static inline pthread_t __constfunc
pthread__self(void)
{
#if defined(_PTHREAD_GETTCB_EXT)
struct tls_tcb * const tcb = _PTHREAD_GETTCB_EXT();
#elif defined(__HAVE___LWP_GETTCB_FAST)
struct tls_tcb * const tcb = __lwp_gettcb_fast();
#else
struct tls_tcb * const tcb = __lwp_getprivate_fast();
#endif
return (pthread_t)tcb->tcb_pthread;
}
#define pthread__abort() \
pthread__assertfunc(__FILE__, __LINE__, __func__, "unreachable")
#define pthread__assert(e) do { \
if (__predict_false(!(e))) \
pthread__assertfunc(__FILE__, __LINE__, __func__, #e); \
} while (/*CONSTCOND*/0)
#define pthread__error(err, msg, e) do { \
if (__predict_false(!(e))) { \
pthread__errorfunc(__FILE__, __LINE__, __func__, msg); \
return (err); \
} \
} while (/*CONSTCOND*/0)
void *pthread_tsd_init(size_t *) PTHREAD_HIDE;
void pthread__destroy_tsd(pthread_t) PTHREAD_HIDE;
__dead void pthread__assertfunc(const char *, int, const char *, const char *)
PTHREAD_HIDE;
void pthread__errorfunc(const char *, int, const char *, const char *)
PTHREAD_HIDE;
char *pthread__getenv(const char *) PTHREAD_HIDE;
__dead void pthread__cancelled(void) PTHREAD_HIDE;
void pthread__mutex_deferwake(pthread_t, pthread_mutex_t *) PTHREAD_HIDE;
int pthread__checkpri(int) PTHREAD_HIDE;
int pthread__add_specific(pthread_t, pthread_key_t, const void *) PTHREAD_HIDE;
#ifndef pthread__smt_pause
#define pthread__smt_pause() /* nothing */
#endif
#ifndef pthread__smt_wake
#define pthread__smt_wake() /* nothing */
#endif
/*
* Bits in the owner field of the lock that indicate lock state. If the
* WRITE_LOCKED bit is clear, then the owner field is actually a count of
* the number of readers.
*/
#define RW_HAS_WAITERS 0x01 /* lock has waiters */
#define RW_WRITE_WANTED 0x02 /* >= 1 waiter is a writer */
#define RW_WRITE_LOCKED 0x04 /* lock is currently write locked */
#define RW_UNUSED 0x08 /* currently unused */
#define RW_FLAGMASK 0x0f
#define RW_READ_COUNT_SHIFT 4
#define RW_READ_INCR (1 << RW_READ_COUNT_SHIFT)
#define RW_THREAD ((uintptr_t)-RW_READ_INCR)
#define RW_OWNER(rw) ((rw)->rw_owner & RW_THREAD)
#define RW_COUNT(rw) ((rw)->rw_owner & RW_THREAD)
#define RW_FLAGS(rw) ((rw)->rw_owner & ~RW_THREAD)
#endif /* _LIB_PTHREAD_INT_H */

View File

@@ -0,0 +1,134 @@
.\" $NetBSD: pthread_join.3,v 1.6 2010/07/09 10:55:11 wiz Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_join.3,v 1.13 2002/09/16 19:29:28 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_JOIN 3
.Os
.Sh NAME
.Nm pthread_join
.Nd wait for thread termination
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_join "pthread_t thread" "void **value_ptr"
.Sh DESCRIPTION
The
.Fn pthread_join
function suspends execution of the calling thread until the target
.Fa thread
terminates unless the target
.Fa thread
has already terminated.
.Pp
On return from a successful
.Fn pthread_join
call with a
.Pf non- Dv NULL
.Fa value_ptr
argument, the value passed to
.Fn pthread_exit
by the terminating thread is stored in the location referenced by
.Fa value_ptr .
When a
.Fn pthread_join
returns successfully, the target thread has been terminated.
The results
of multiple simultaneous calls to
.Fn pthread_join
specifying the same target thread are undefined.
If the thread calling
.Fn pthread_join
is cancelled, then the target thread is not detached.
.Pp
A thread that has exited but remains unjoined counts against
.Dv _POSIX_THREAD_THREADS_MAX .
.Sh RETURN VALUES
If successful, the
.Fn pthread_join
function will return zero.
Otherwise an error number will be returned to
indicate the error.
.Sh ERRORS
.Fn pthread_join
shall fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa thread
does not refer to a joinable thread.
.It Bq Er ESRCH
No thread could be found corresponding to that specified by the given
thread ID,
.Fa thread .
.El
.Pp
.Fn pthread_join
may fail if:
.Bl -tag -width Er
.It Bq Er EDEADLK
A deadlock was detected or the value of
.Fa thread
specifies the calling thread.
.El
.Sh SEE ALSO
.Xr wait 2 ,
.Xr pthread_create 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,194 @@
.\" $NetBSD: pthread_key_create.3,v 1.8 2015/05/29 18:00:51 wiz Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_key_create.3,v 1.12 2002/09/16 19:29:28 mini Exp $
.\"
.Dd May 29, 2015
.Dt PTHREAD_KEY_CREATE 3
.Os
.Sh NAME
.Nm pthread_key_create
.Nd thread-specific data
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_key_create "pthread_key_t *key" "void (*destructor)(void *)"
.Ft int
.Fn pthread_key_delete "pthread_key_t key"
.Sh DESCRIPTION
The
.Fn pthread_key_create
function creates a thread-specific data key visible to all threads in the
process.
Key values are opaque objects used to locate thread-specific data.
The same key value may be used by different threads,
but the values bound to the key by
.Fn pthread_setspecific
are maintained on a per-thread basis and
persist for the life of the calling thread.
.Pp
Upon key creation, the value
.Dv NULL
is associated with the new key in all active threads.
Upon thread creation, the value
.Dv NULL
is associated with all
defined keys in the new thread.
.Pp
An optional destructor function may be associated with each key value.
At thread exit, if a key value has a
.Pf non- Dv NULL
destructor pointer, and the thread has a
.Pf non- Dv NULL
value associated with the key, the function pointed
to is called with the current associated value as its sole argument.
The order of destructor calls is unspecified if more
than one destructor exists for a thread when it exits.
.Pp
If, after all the destructors have been called for all
.Pf non- Dv NULL
values with associated destructors, there are still some
.Pf non- Dv NULL
values with associated destructors, then the process is repeated.
If, after at least
.Dv PTHREAD_DESTRUCTOR_ITERATIONS
iterations of destructor calls for outstanding
.Pf non- Dv NULL
values, there are still some
.Pf non- Dv NULL
values with
associated destructors, the implementation stops calling destructors.
.Pp
The
.Fn pthread_key_delete
function deletes a thread-specific data key previously returned by
.Fn pthread_key_create .
The thread-specific data values associated with
.Fa key
need not be
.Dv NULL
at the time of the call.
It is the responsibility of the application to free any
application storage or perform any cleanup actions for data structures
related to the deleted key or associated thread-specific data in any threads;
this cleanup can be done either before or after
.Fn pthread_key_delete
is called.
Any attempt to use
.Fa key
following the call to
.Fn pthread_key_delete
results in undefined behavior.
.Pp
The
.Fn pthread_key_delete
function itself is callable from within destructor functions,
but destructor functions are not invoked by the function.
Any destructor function that may have been associated with
.Fa key
will no longer be called upon thread exit.
.Sh RETURN VALUES
If successful, the
.Fn pthread_key_create
function will store the newly created key value at the location specified by
.Fa key
and returns zero.
Also
.Fn pthread_key_delete
will return zero upon success.
Upon failure both functions return an error number to indicate the cause.
.Sh ENVIRONMENT
.Bl -tag -width PTHREAD_KEYS_MAX
.It Ev PTHREAD_KEYS_MAX
Maximum per-process thread-specific data keys.
This cannot be set below
.Dv _POSIX_THREAD_KEYS_MAX .
.El
.Sh ERRORS
The
.Fn pthread_key_create
may fail if:
.Bl -tag -width Er
.It Bq Er EAGAIN
The system lacked the necessary resources to create another thread-specific
data key, or the system-imposed limit on the total number of keys per-process
.Dv PTHREAD_KEYS_MAX
would be exceeded.
.It Bq Er ENOMEM
Insufficient memory exists to create the key.
.El
.Pp
The
.Fn pthread_key_delete
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The
.Fa key
value is invalid.
.El
.Sh SEE ALSO
.Xr pthread_getspecific 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .
.Sh BUGS
The current specifications are flawed and
do not permit a clean implementation without potential problems.
The current implementation in
.Nx
addresses these problems by not supporting key reuse.

View File

@@ -0,0 +1,102 @@
.\" $NetBSD: pthread_kill.3,v 1.9 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
.\" the first lines of this file unmodified other than the possible
.\" addition of one or more copyright notices.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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: src/lib/libpthread/man/pthread_kill.3,v 1.9 2002/09/16 19:29:28 mini Exp $
.Dd July 9, 2010
.Dt PTHREAD_KILL 3
.Os
.Sh NAME
.Nm pthread_kill
.Nd send a signal to a specified thread
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.In signal.h
.Ft int
.Fn pthread_kill "pthread_t thread" "int sig"
.Sh DESCRIPTION
The
.Fn pthread_kill
function sends a signal, specified by
.Fa sig ,
to a thread, specified by
.Fa thread .
The signal will be handled in the context of
.Fa thread ,
but the signal action may alter the process as a whole.
If
.Fa sig
is 0, error checking is performed, but no signal is actually sent.
.Sh RETURN VALUES
If successful,
.Fn pthread_kill
returns 0.
Otherwise, an error number is returned.
.Sh ERRORS
.Fn pthread_kill
shall fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
.Fa sig
is an invalid or unsupported signal number.
.It Bq Er ESRCH
.Fa thread
is an invalid thread ID.
.El
.Sh SEE ALSO
.Xr kill 2 ,
.Xr sigwait 2 ,
.Xr pthread_self 3 ,
.Xr raise 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,198 @@
/* $NetBSD: pthread_lock.c,v 1.34 2008/04/28 20:23:01 martin Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* libpthread internal spinlock routines.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_lock.c,v 1.34 2008/04/28 20:23:01 martin Exp $");
#include <sys/types.h>
#include <sys/ras.h>
#include <machine/lock.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "pthread.h"
#include "pthread_int.h"
/* How many times to try acquiring spin locks on MP systems. */
#define PTHREAD__NSPINS 64
RAS_DECL(pthread__lock);
static void pthread__spinlock_slow(pthread_spin_t *);
#ifdef PTHREAD__ASM_RASOPS
void pthread__ras_simple_lock_init(__cpu_simple_lock_t *);
int pthread__ras_simple_lock_try(__cpu_simple_lock_t *);
void pthread__ras_simple_unlock(__cpu_simple_lock_t *);
#else
static void
pthread__ras_simple_lock_init(__cpu_simple_lock_t *alp)
{
__cpu_simple_lock_clear(alp);
}
static int
pthread__ras_simple_lock_try(__cpu_simple_lock_t *alp)
{
int locked;
RAS_START(pthread__lock);
locked = __SIMPLELOCK_LOCKED_P(alp);
__cpu_simple_lock_set(alp);
RAS_END(pthread__lock);
return !locked;
}
static void
pthread__ras_simple_unlock(__cpu_simple_lock_t *alp)
{
__cpu_simple_lock_clear(alp);
}
#endif /* PTHREAD__ASM_RASOPS */
static const struct pthread_lock_ops pthread__lock_ops_ras = {
pthread__ras_simple_lock_init,
pthread__ras_simple_lock_try,
pthread__ras_simple_unlock,
pthread__spinlock_slow,
};
static void
pthread__atomic_simple_lock_init(__cpu_simple_lock_t *alp)
{
__cpu_simple_lock_init(alp);
}
static int
pthread__atomic_simple_lock_try(__cpu_simple_lock_t *alp)
{
return (__cpu_simple_lock_try(alp));
}
static void
pthread__atomic_simple_unlock(__cpu_simple_lock_t *alp)
{
__cpu_simple_unlock(alp);
}
static const struct pthread_lock_ops pthread__lock_ops_atomic = {
pthread__atomic_simple_lock_init,
pthread__atomic_simple_lock_try,
pthread__atomic_simple_unlock,
pthread__spinlock_slow,
};
/*
* We default to pointing to the RAS primitives; we might need to use
* locks early, but before main() starts. This is safe, since no other
* threads will be active for the process, so atomicity will not be
* required.
*/
const struct pthread_lock_ops *pthread__lock_ops = &pthread__lock_ops_ras;
/*
* Prevent this routine from being inlined. The common case is no
* contention and it's better to not burden the instruction decoder.
*/
static void
pthread__spinlock_slow(pthread_spin_t *lock)
{
pthread_t self;
int count;
self = pthread__self();
do {
count = pthread__nspins;
while (__SIMPLELOCK_LOCKED_P(lock) && --count > 0)
pthread__smt_pause();
if (count > 0) {
if ((*self->pt_lockops.plo_try)(lock))
break;
continue;
}
sched_yield();
} while (/*CONSTCOND*/ 1);
}
/*
* Initialize the locking primitives. On uniprocessors, we always
* use Restartable Atomic Sequences if they are available. Otherwise,
* we fall back onto machine-dependent atomic lock primitives.
*/
void
pthread__lockprim_init(void)
{
char *p;
if ((p = pthread__getenv("PTHREAD_NSPINS")) != NULL)
pthread__nspins = atoi(p);
else if (pthread__concurrency != 1)
pthread__nspins = PTHREAD__NSPINS;
else
pthread__nspins = 1;
if (pthread__concurrency != 1) {
pthread__lock_ops = &pthread__lock_ops_atomic;
return;
}
if (rasctl(RAS_ADDR(pthread__lock), RAS_SIZE(pthread__lock),
RAS_INSTALL) != 0) {
pthread__lock_ops = &pthread__lock_ops_atomic;
return;
}
}
void
pthread_lockinit(pthread_spin_t *lock)
{
pthread__simple_lock_init(lock);
}

View File

@@ -0,0 +1,46 @@
/* $NetBSD: pthread_makelwp.h,v 1.1 2014/12/16 20:05:54 pooka Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_MAKELWP_H_
#define _LIB_PTHREAD_MAKELWP_H_
#include <sys/param.h>
#include <lwp.h>
/* for PTHREAD_HIDE */
#include <pthread.h>
#include "pthread_int.h"
int pthread__makelwp(void (*)(void *), void *, void *, void *, size_t,
unsigned long, lwpid_t *) PTHREAD_HIDE;
#endif /* _LIB_PTHREAD_MAKELWP_H_ */

View File

@@ -0,0 +1,65 @@
/* $NetBSD: pthread_makelwp_netbsd.c,v 1.2 2014/12/17 01:49:08 pooka Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_makelwp_netbsd.c,v 1.2 2014/12/17 01:49:08 pooka Exp $");
#include <sys/param.h>
#include <lwp.h>
#include <pthread.h>
#include <string.h>
#include "pthread_int.h"
#include "pthread_makelwp.h"
int
pthread__makelwp(void (*start_routine)(void *), void *arg, void *priv,
void *stack_base, size_t stack_size,
unsigned long flag, lwpid_t *newlid)
{
ucontext_t uc;
/*
* XXX: most of the following chunk is these days
* performed also by _lwp_makecontext(), but there may
* be MD differences, so lug everything along for now.
*/
memset(&uc, 0, sizeof(uc));
_INITCONTEXT_U(&uc);
uc.uc_stack.ss_sp = stack_base;
uc.uc_stack.ss_size = stack_size;
uc.uc_stack.ss_flags = 0;
uc.uc_link = NULL;
_lwp_makecontext(&uc, start_routine, arg, priv, stack_base, stack_size);
return _lwp_create(&uc, flag, newlid);
}

View File

@@ -0,0 +1,170 @@
/* $NetBSD: pthread_misc.c,v 1.15 2013/03/21 16:49:12 christos Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_misc.c,v 1.15 2013/03/21 16:49:12 christos Exp $");
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/pset.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <lwp.h>
#include <sched.h>
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
int pthread__sched_yield(void);
int _sys___sigprocmask14(int, const sigset_t *, sigset_t *);
int _sys_sched_yield(void);
__strong_alias(__libc_thr_sigsetmask,pthread_sigmask)
__strong_alias(__sigprocmask14,pthread_sigmask)
__strong_alias(__libc_thr_yield,pthread__sched_yield)
int
pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
{
if (pthread__find(thread) != 0)
return ESRCH;
if (_sched_getparam(getpid(), thread->pt_lid, policy, param) < 0)
return errno;
return 0;
}
int
pthread_setschedparam(pthread_t thread, int policy,
const struct sched_param *param)
{
struct sched_param sp;
if (pthread__find(thread) != 0)
return ESRCH;
memcpy(&sp, param, sizeof(struct sched_param));
if (_sched_setparam(getpid(), thread->pt_lid, policy, &sp) < 0)
return errno;
return 0;
}
int
pthread_getaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
{
if (pthread__find(thread) != 0)
return ESRCH;
if (_sched_getaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
return errno;
return 0;
}
int
pthread_setaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
{
if (pthread__find(thread) != 0)
return ESRCH;
if (_sched_setaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
return errno;
return 0;
}
int
pthread_setschedprio(pthread_t thread, int prio)
{
struct sched_param sp;
if (pthread__find(thread) != 0)
return ESRCH;
sp.sched_priority = prio;
if (_sched_setparam(getpid(), thread->pt_lid, SCHED_NONE, &sp) < 0)
return errno;
return 0;
}
int
pthread_kill(pthread_t thread, int sig)
{
if ((sig < 0) || (sig >= _NSIG))
return EINVAL;
if (pthread__find(thread) != 0)
return ESRCH;
if (_lwp_kill(thread->pt_lid, sig))
return errno;
return 0;
}
int
pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
{
if (_sys___sigprocmask14(how, set, oset))
return errno;
return 0;
}
int
pthread__sched_yield(void)
{
pthread_t self;
int error;
if (__predict_false(__uselibcstub))
return __libc_thr_yield();
self = pthread__self();
/* Memory barrier for unlocked mutex release. */
membar_producer();
self->pt_blocking++;
error = _sys_sched_yield();
self->pt_blocking--;
membar_sync();
return error;
}

View File

@@ -0,0 +1,217 @@
.\" $NetBSD: pthread_mutex.3,v 1.6 2012/11/12 23:11:05 uwe Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
.\" 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.
.\" 3. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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.
.\"
.\" ----------------------------------------------------------------------------
.Dd July 8, 2010
.Dt PTHREAD_MUTEX 3
.Os
.Sh NAME
.Nm pthread_mutex
.Nd mutual exclusion primitives
.Sh LIBRARY
.Lb libpthread
.\" ----------------------------------------------------------------------------
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_mutex_init "pthread_mutex_t * restrict mutex" \
"const pthread_mutexattr_t * restrict attr"
.Vt pthread_mutex_t mutex No = Dv PTHREAD_MUTEX_INITIALIZER;
.Ft int
.Fn pthread_mutex_destroy "pthread_mutex_t *mutex"
.Ft int
.Fn pthread_mutex_lock "pthread_mutex_t *mutex"
.Ft int
.Fn pthread_mutex_trylock "pthread_mutex_t *mutex"
.Ft int
.Fn pthread_mutex_unlock "pthread_mutex_t *mutex"
.\" ----------------------------------------------------------------------------
.Sh DESCRIPTION
The
.Fn pthread_mutex_init
function creates a new mutex, with attributes specified with
.Fa attr .
If
.Fa attr
is
.Dv NULL ,
the default attributes are used.
.Pp
The macro
.Dv PTHREAD_MUTEX_INITIALIZER
can be used to initialize a mutex when the default attributes are
appropriate and the mutex can be statically allocated.
The behavior is similar to
.Fn pthread_mutex_init
with
.Fa attr
specified as
.Dv NULL ,
except that no error checking is done.
.Pp
.\" -----
The
.Fn pthread_mutex_destroy
function frees the resources allocated for
.Fa mutex .
It is possible to reinitialize a destroyed mutex, but undefined
behavior may follow if the destroyed object is otherwise referenced.
.Pp
.\" -----
The
.Fn pthread_mutex_lock
function locks
.Fa mutex .
If the mutex is already locked, the calling thread will block until the
mutex becomes available.
The error conditions may vary depending on the type of the mutex; see
.Xr pthread_mutexattr 3
for additional details.
.Pp
The
.Fn pthread_mutex_trylock
function locks
.Fa mutex .
If the mutex is already locked,
.Fn pthread_mutex_trylock
will not block waiting for the mutex, but will return an error condition.
.Pp
.\" -----
The
.Fn pthread_mutex_unlock
function unlocks an acquired
.Fa mutex .
When operating with the default mutex type,
undefined behavior follows if a thread tries to unlock a mutex
that has not been locked by it, or if a thread tries to release
a mutex that is already unlocked.
.\" ----------------------------------------------------------------------------
.Sh RETURN VALUES
Upon success all described functions return zero.
Otherwise, an error number will be returned to indicate the error.
.Sh ERRORS
.Fn pthread_mutex_init
may fail if:
.Bl -tag -width Er
.It Bq Er EAGAIN
The system lacks the resources to initialize another mutex.
.It Bq Er EINVAL
The value specified by
.Fa attr
is invalid.
.It Bq Er ENOMEM
The process cannot allocate enough memory to initialize another mutex.
.El
.Pp
.\" -----
.Fn pthread_mutex_destroy
may fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
.Fa Mutex
is locked by another thread.
.It Bq Er EINVAL
The value specified by
.Fa mutex
is invalid.
.El
.Pp
.\" -----
.Fn pthread_mutex_lock
may fail if:
.Bl -tag -width Er
.It Bq Er EDEADLK
A deadlock would occur if the thread blocked waiting for
.Fa mutex .
.It Bq Er EINVAL
The value specified by
.Fa mutex
is invalid.
.El
.Pp
.Fn pthread_mutex_trylock
may fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
.Fa Mutex
is already locked.
.It Bq Er EINVAL
The value specified by
.Fa mutex
is invalid.
.El
.Pp
.\" -----
.Fn pthread_mutex_unlock
may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa mutex
is invalid.
.It Bq Er EPERM
The current thread does not hold a lock on
.Fa mutex .
.El
.\" ----------------------------------------------------------------------------
.Sh SEE ALSO
.Xr pthread 3 ,
.Xr pthread_barrier 3 ,
.Xr pthread_cond 3 ,
.Xr pthread_mutexattr 3 ,
.Xr pthread_rwlock 3 ,
.Xr pthread_spin 3
.\" ----------------------------------------------------------------------------
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,659 @@
/* $NetBSD: pthread_mutex.c,v 1.59 2014/02/03 15:51:01 rmind Exp $ */
/*-
* Copyright (c) 2001, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams, by Jason R. Thorpe, and by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* To track threads waiting for mutexes to be released, we use lockless
* lists built on atomic operations and memory barriers.
*
* A simple spinlock would be faster and make the code easier to
* follow, but spinlocks are problematic in userspace. If a thread is
* preempted by the kernel while holding a spinlock, any other thread
* attempting to acquire that spinlock will needlessly busy wait.
*
* There is no good way to know that the holding thread is no longer
* running, nor to request a wake-up once it has begun running again.
* Of more concern, threads in the SCHED_FIFO class do not have a
* limited time quantum and so could spin forever, preventing the
* thread holding the spinlock from getting CPU time: it would never
* be released.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_mutex.c,v 1.59 2014/02/03 15:51:01 rmind Exp $");
#include <sys/types.h>
#include <sys/lwpctl.h>
#include <sys/lock.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
#define MUTEX_WAITERS_BIT ((uintptr_t)0x01)
#define MUTEX_RECURSIVE_BIT ((uintptr_t)0x02)
#define MUTEX_DEFERRED_BIT ((uintptr_t)0x04)
#define MUTEX_THREAD ((uintptr_t)-16L)
#define MUTEX_HAS_WAITERS(x) ((uintptr_t)(x) & MUTEX_WAITERS_BIT)
#define MUTEX_RECURSIVE(x) ((uintptr_t)(x) & MUTEX_RECURSIVE_BIT)
#define MUTEX_OWNER(x) ((uintptr_t)(x) & MUTEX_THREAD)
#if __GNUC_PREREQ__(3, 0)
#define NOINLINE __attribute ((noinline))
#else
#define NOINLINE /* nothing */
#endif
static void pthread__mutex_wakeup(pthread_t, pthread_mutex_t *);
static int pthread__mutex_lock_slow(pthread_mutex_t *);
static int pthread__mutex_unlock_slow(pthread_mutex_t *);
static void pthread__mutex_pause(void);
int _pthread_mutex_held_np(pthread_mutex_t *);
pthread_t _pthread_mutex_owner_np(pthread_mutex_t *);
__weak_alias(pthread_mutex_held_np,_pthread_mutex_held_np)
__weak_alias(pthread_mutex_owner_np,_pthread_mutex_owner_np)
__strong_alias(__libc_mutex_init,pthread_mutex_init)
__strong_alias(__libc_mutex_lock,pthread_mutex_lock)
__strong_alias(__libc_mutex_trylock,pthread_mutex_trylock)
__strong_alias(__libc_mutex_unlock,pthread_mutex_unlock)
__strong_alias(__libc_mutex_destroy,pthread_mutex_destroy)
__strong_alias(__libc_mutexattr_init,pthread_mutexattr_init)
__strong_alias(__libc_mutexattr_destroy,pthread_mutexattr_destroy)
__strong_alias(__libc_mutexattr_settype,pthread_mutexattr_settype)
int
pthread_mutex_init(pthread_mutex_t *ptm, const pthread_mutexattr_t *attr)
{
intptr_t type;
if (__predict_false(__uselibcstub))
return __libc_mutex_init_stub(ptm, attr);
if (attr == NULL)
type = PTHREAD_MUTEX_NORMAL;
else
type = (intptr_t)attr->ptma_private;
switch (type) {
case PTHREAD_MUTEX_ERRORCHECK:
__cpu_simple_lock_set(&ptm->ptm_errorcheck);
ptm->ptm_owner = NULL;
break;
case PTHREAD_MUTEX_RECURSIVE:
__cpu_simple_lock_clear(&ptm->ptm_errorcheck);
ptm->ptm_owner = (void *)MUTEX_RECURSIVE_BIT;
break;
default:
__cpu_simple_lock_clear(&ptm->ptm_errorcheck);
ptm->ptm_owner = NULL;
break;
}
ptm->ptm_magic = _PT_MUTEX_MAGIC;
ptm->ptm_waiters = NULL;
ptm->ptm_recursed = 0;
return 0;
}
int
pthread_mutex_destroy(pthread_mutex_t *ptm)
{
if (__predict_false(__uselibcstub))
return __libc_mutex_destroy_stub(ptm);
pthread__error(EINVAL, "Invalid mutex",
ptm->ptm_magic == _PT_MUTEX_MAGIC);
pthread__error(EBUSY, "Destroying locked mutex",
MUTEX_OWNER(ptm->ptm_owner) == 0);
ptm->ptm_magic = _PT_MUTEX_DEAD;
return 0;
}
int
pthread_mutex_lock(pthread_mutex_t *ptm)
{
pthread_t self;
void *val;
if (__predict_false(__uselibcstub))
return __libc_mutex_lock_stub(ptm);
self = pthread__self();
val = atomic_cas_ptr(&ptm->ptm_owner, NULL, self);
if (__predict_true(val == NULL)) {
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
return pthread__mutex_lock_slow(ptm);
}
/* We want function call overhead. */
NOINLINE static void
pthread__mutex_pause(void)
{
pthread__smt_pause();
}
/*
* Spin while the holder is running. 'lwpctl' gives us the true
* status of the thread. pt_blocking is set by libpthread in order
* to cut out system call and kernel spinlock overhead on remote CPUs
* (could represent many thousands of clock cycles). pt_blocking also
* makes this thread yield if the target is calling sched_yield().
*/
NOINLINE static void *
pthread__mutex_spin(pthread_mutex_t *ptm, pthread_t owner)
{
pthread_t thread;
unsigned int count, i;
for (count = 2;; owner = ptm->ptm_owner) {
thread = (pthread_t)MUTEX_OWNER(owner);
if (thread == NULL)
break;
if (thread->pt_lwpctl->lc_curcpu == LWPCTL_CPU_NONE ||
thread->pt_blocking)
break;
if (count < 128)
count += count;
for (i = count; i != 0; i--)
pthread__mutex_pause();
}
return owner;
}
NOINLINE static void
pthread__mutex_setwaiters(pthread_t self, pthread_mutex_t *ptm)
{
void *new, *owner;
/*
* Note that the mutex can become unlocked before we set
* the waiters bit. If that happens it's not safe to sleep
* as we may never be awoken: we must remove the current
* thread from the waiters list and try again.
*
* Because we are doing this atomically, we can't remove
* one waiter: we must remove all waiters and awken them,
* then sleep in _lwp_park() until we have been awoken.
*
* Issue a memory barrier to ensure that we are reading
* the value of ptm_owner/pt_mutexwait after we have entered
* the waiters list (the CAS itself must be atomic).
*/
again:
membar_consumer();
owner = ptm->ptm_owner;
if (MUTEX_OWNER(owner) == 0) {
pthread__mutex_wakeup(self, ptm);
return;
}
if (!MUTEX_HAS_WAITERS(owner)) {
new = (void *)((uintptr_t)owner | MUTEX_WAITERS_BIT);
if (atomic_cas_ptr(&ptm->ptm_owner, owner, new) != owner) {
goto again;
}
}
/*
* Note that pthread_mutex_unlock() can do a non-interlocked CAS.
* We cannot know if the presence of the waiters bit is stable
* while the holding thread is running. There are many assumptions;
* see sys/kern/kern_mutex.c for details. In short, we must spin if
* we see that the holder is running again.
*/
membar_sync();
pthread__mutex_spin(ptm, owner);
if (membar_consumer(), !MUTEX_HAS_WAITERS(ptm->ptm_owner)) {
goto again;
}
}
NOINLINE static int
pthread__mutex_lock_slow(pthread_mutex_t *ptm)
{
void *waiters, *new, *owner, *next;
pthread_t self;
int serrno;
pthread__error(EINVAL, "Invalid mutex",
ptm->ptm_magic == _PT_MUTEX_MAGIC);
owner = ptm->ptm_owner;
self = pthread__self();
/* Recursive or errorcheck? */
if (MUTEX_OWNER(owner) == (uintptr_t)self) {
if (MUTEX_RECURSIVE(owner)) {
if (ptm->ptm_recursed == INT_MAX)
return EAGAIN;
ptm->ptm_recursed++;
return 0;
}
if (__SIMPLELOCK_LOCKED_P(&ptm->ptm_errorcheck))
return EDEADLK;
}
serrno = errno;
for (;; owner = ptm->ptm_owner) {
/* Spin while the owner is running. */
owner = pthread__mutex_spin(ptm, owner);
/* If it has become free, try to acquire it again. */
if (MUTEX_OWNER(owner) == 0) {
do {
new = (void *)
((uintptr_t)self | (uintptr_t)owner);
next = atomic_cas_ptr(&ptm->ptm_owner, owner,
new);
if (next == owner) {
errno = serrno;
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
owner = next;
} while (MUTEX_OWNER(owner) == 0);
/*
* We have lost the race to acquire the mutex.
* The new owner could be running on another
* CPU, in which case we should spin and avoid
* the overhead of blocking.
*/
continue;
}
/*
* Nope, still held. Add thread to the list of waiters.
* Issue a memory barrier to ensure mutexwait/mutexnext
* are visible before we enter the waiters list.
*/
self->pt_mutexwait = 1;
for (waiters = ptm->ptm_waiters;; waiters = next) {
self->pt_mutexnext = waiters;
membar_producer();
next = atomic_cas_ptr(&ptm->ptm_waiters, waiters, self);
if (next == waiters)
break;
}
/* Set the waiters bit and block. */
pthread__mutex_setwaiters(self, ptm);
/*
* We may have been awoken by the current thread above,
* or will be awoken by the current holder of the mutex.
* The key requirement is that we must not proceed until
* told that we are no longer waiting (via pt_mutexwait
* being set to zero). Otherwise it is unsafe to re-enter
* the thread onto the waiters list.
*/
while (self->pt_mutexwait) {
self->pt_blocking++;
(void)_lwp_park(CLOCK_REALTIME, TIMER_ABSTIME, NULL,
self->pt_unpark, __UNVOLATILE(&ptm->ptm_waiters),
__UNVOLATILE(&ptm->ptm_waiters));
self->pt_unpark = 0;
self->pt_blocking--;
membar_sync();
}
}
}
int
pthread_mutex_trylock(pthread_mutex_t *ptm)
{
pthread_t self;
void *val, *new, *next;
if (__predict_false(__uselibcstub))
return __libc_mutex_trylock_stub(ptm);
self = pthread__self();
val = atomic_cas_ptr(&ptm->ptm_owner, NULL, self);
if (__predict_true(val == NULL)) {
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
if (MUTEX_RECURSIVE(val)) {
if (MUTEX_OWNER(val) == 0) {
new = (void *)((uintptr_t)self | (uintptr_t)val);
next = atomic_cas_ptr(&ptm->ptm_owner, val, new);
if (__predict_true(next == val)) {
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
}
if (MUTEX_OWNER(val) == (uintptr_t)self) {
if (ptm->ptm_recursed == INT_MAX)
return EAGAIN;
ptm->ptm_recursed++;
return 0;
}
}
return EBUSY;
}
int
pthread_mutex_unlock(pthread_mutex_t *ptm)
{
pthread_t self;
void *value;
if (__predict_false(__uselibcstub))
return __libc_mutex_unlock_stub(ptm);
/*
* Note this may be a non-interlocked CAS. See lock_slow()
* above and sys/kern/kern_mutex.c for details.
*/
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_exit();
#endif
self = pthread__self();
value = atomic_cas_ptr_ni(&ptm->ptm_owner, self, NULL);
if (__predict_true(value == self)) {
pthread__smt_wake();
return 0;
}
return pthread__mutex_unlock_slow(ptm);
}
NOINLINE static int
pthread__mutex_unlock_slow(pthread_mutex_t *ptm)
{
pthread_t self, owner, new;
int weown, error, deferred;
pthread__error(EINVAL, "Invalid mutex",
ptm->ptm_magic == _PT_MUTEX_MAGIC);
self = pthread__self();
owner = ptm->ptm_owner;
weown = (MUTEX_OWNER(owner) == (uintptr_t)self);
deferred = (int)((uintptr_t)owner & MUTEX_DEFERRED_BIT);
error = 0;
if (__SIMPLELOCK_LOCKED_P(&ptm->ptm_errorcheck)) {
if (!weown) {
error = EPERM;
new = owner;
} else {
new = NULL;
}
} else if (MUTEX_RECURSIVE(owner)) {
if (!weown) {
error = EPERM;
new = owner;
} else if (ptm->ptm_recursed) {
ptm->ptm_recursed--;
new = owner;
} else {
new = (pthread_t)MUTEX_RECURSIVE_BIT;
}
} else {
pthread__error(EPERM,
"Unlocking unlocked mutex", (owner != NULL));
pthread__error(EPERM,
"Unlocking mutex owned by another thread", weown);
new = NULL;
}
/*
* Release the mutex. If there appear to be waiters, then
* wake them up.
*/
if (new != owner) {
owner = atomic_swap_ptr(&ptm->ptm_owner, new);
if (MUTEX_HAS_WAITERS(owner) != 0) {
pthread__mutex_wakeup(self, ptm);
return 0;
}
}
/*
* There were no waiters, but we may have deferred waking
* other threads until mutex unlock - we must wake them now.
*/
if (!deferred)
return error;
if (self->pt_nwaiters == 1) {
/*
* If the calling thread is about to block, defer
* unparking the target until _lwp_park() is called.
*/
if (self->pt_willpark && self->pt_unpark == 0) {
self->pt_unpark = self->pt_waiters[0];
} else {
(void)_lwp_unpark(self->pt_waiters[0],
__UNVOLATILE(&ptm->ptm_waiters));
}
} else {
(void)_lwp_unpark_all(self->pt_waiters, self->pt_nwaiters,
__UNVOLATILE(&ptm->ptm_waiters));
}
self->pt_nwaiters = 0;
return error;
}
/*
* pthread__mutex_wakeup: unpark threads waiting for us
*
* unpark threads on the ptm->ptm_waiters list and self->pt_waiters.
*/
static void
pthread__mutex_wakeup(pthread_t self, pthread_mutex_t *ptm)
{
pthread_t thread, next;
ssize_t n, rv;
/*
* Take ownership of the current set of waiters. No
* need for a memory barrier following this, all loads
* are dependent upon 'thread'.
*/
thread = atomic_swap_ptr(&ptm->ptm_waiters, NULL);
pthread__smt_wake();
for (;;) {
/*
* Pull waiters from the queue and add to our list.
* Use a memory barrier to ensure that we safely
* read the value of pt_mutexnext before 'thread'
* sees pt_mutexwait being cleared.
*/
for (n = self->pt_nwaiters, self->pt_nwaiters = 0;
n < pthread__unpark_max && thread != NULL;
thread = next) {
next = thread->pt_mutexnext;
if (thread != self) {
self->pt_waiters[n++] = thread->pt_lid;
membar_sync();
}
thread->pt_mutexwait = 0;
/* No longer safe to touch 'thread' */
}
switch (n) {
case 0:
return;
case 1:
/*
* If the calling thread is about to block,
* defer unparking the target until _lwp_park()
* is called.
*/
if (self->pt_willpark && self->pt_unpark == 0) {
self->pt_unpark = self->pt_waiters[0];
return;
}
rv = (ssize_t)_lwp_unpark(self->pt_waiters[0],
__UNVOLATILE(&ptm->ptm_waiters));
if (rv != 0 && errno != EALREADY && errno != EINTR &&
errno != ESRCH) {
pthread__errorfunc(__FILE__, __LINE__,
__func__, "_lwp_unpark failed");
}
return;
default:
rv = _lwp_unpark_all(self->pt_waiters, (size_t)n,
__UNVOLATILE(&ptm->ptm_waiters));
if (rv != 0 && errno != EINTR) {
pthread__errorfunc(__FILE__, __LINE__,
__func__, "_lwp_unpark_all failed");
}
break;
}
}
}
int
pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
if (__predict_false(__uselibcstub))
return __libc_mutexattr_init_stub(attr);
attr->ptma_magic = _PT_MUTEXATTR_MAGIC;
attr->ptma_private = (void *)PTHREAD_MUTEX_DEFAULT;
return 0;
}
int
pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
{
if (__predict_false(__uselibcstub))
return __libc_mutexattr_destroy_stub(attr);
pthread__error(EINVAL, "Invalid mutex attribute",
attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
return 0;
}
int
pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *typep)
{
pthread__error(EINVAL, "Invalid mutex attribute",
attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
*typep = (int)(intptr_t)attr->ptma_private;
return 0;
}
int
pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
{
if (__predict_false(__uselibcstub))
return __libc_mutexattr_settype_stub(attr, type);
pthread__error(EINVAL, "Invalid mutex attribute",
attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
switch (type) {
case PTHREAD_MUTEX_NORMAL:
case PTHREAD_MUTEX_ERRORCHECK:
case PTHREAD_MUTEX_RECURSIVE:
attr->ptma_private = (void *)(intptr_t)type;
return 0;
default:
return EINVAL;
}
}
/*
* pthread__mutex_deferwake: try to defer unparking threads in self->pt_waiters
*
* In order to avoid unnecessary contention on the interlocking mutex,
* we defer waking up threads until we unlock the mutex. The threads will
* be woken up when the calling thread (self) releases the first mutex with
* MUTEX_DEFERRED_BIT set. It likely be the mutex 'ptm', but no problem
* even if it isn't.
*/
void
pthread__mutex_deferwake(pthread_t self, pthread_mutex_t *ptm)
{
if (__predict_false(ptm == NULL ||
MUTEX_OWNER(ptm->ptm_owner) != (uintptr_t)self)) {
(void)_lwp_unpark_all(self->pt_waiters, self->pt_nwaiters,
__UNVOLATILE(&ptm->ptm_waiters));
self->pt_nwaiters = 0;
} else {
atomic_or_ulong((volatile unsigned long *)
(uintptr_t)&ptm->ptm_owner,
(unsigned long)MUTEX_DEFERRED_BIT);
}
}
int
_pthread_mutex_held_np(pthread_mutex_t *ptm)
{
return MUTEX_OWNER(ptm->ptm_owner) == (uintptr_t)pthread__self();
}
pthread_t
_pthread_mutex_owner_np(pthread_mutex_t *ptm)
{
return (pthread_t)MUTEX_OWNER(ptm->ptm_owner);
}

View File

@@ -0,0 +1,246 @@
.\" $NetBSD: pthread_mutexattr.3,v 1.11 2010/07/08 22:46:34 jruoho Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
.\" the first lines of this file unmodified other than the possible
.\" addition of one or more copyright notices.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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: src/lib/libpthread/man/pthread_mutexattr.3,v 1.8 2002/09/16 19:29:29 mini Exp $
.Dd July 9, 2010
.Dt PTHREAD_MUTEXATTR 3
.Os
.Sh NAME
.Nm pthread_mutexattr_init ,
.Nm pthread_mutexattr_destroy ,
.\" .Nm pthread_mutexattr_setprioceiling ,
.\" .Nm pthread_mutexattr_getprioceiling ,
.\" .Nm pthread_mutexattr_setprotocol ,
.\" .Nm pthread_mutexattr_getprotocol ,
.Nm pthread_mutexattr_settype ,
.Nm pthread_mutexattr_gettype
.Nd mutex attribute operations
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_mutexattr_init "pthread_mutexattr_t *attr"
.Ft int
.Fn pthread_mutexattr_destroy "pthread_mutexattr_t *attr"
.\" .Ft int
.\" .Fn pthread_mutexattr_setprioceiling \
.\" "pthread_mutexattr_t *attr" "int prioceiling"
.\" .Ft int
.\" .Fn pthread_mutexattr_getprioceiling \
.\" "pthread_mutexattr_t *attr" "int *prioceiling"
.\" .Ft int
.\" .Fn pthread_mutexattr_setprotocol \
.\" "pthread_mutexattr_t *attr" "int protocol"
.\" .Ft int
.\" .Fn pthread_mutexattr_getprotocol \
.\" "pthread_mutexattr_t *attr" "int *protocol"
.Ft int
.Fn pthread_mutexattr_settype "pthread_mutexattr_t *attr" "int type"
.Ft int
.Fn pthread_mutexattr_gettype \
"pthread_mutexattr_t * restrict attr" "int * restrict type"
.Sh DESCRIPTION
Mutex attributes are used to specify parameters to
.Fn pthread_mutex_init .
Like with thread attributes,
one attribute object can be used in multiple calls to
.Xr pthread_mutex_init 3 ,
with or without modifications between calls.
.Pp
The
.Fn pthread_mutexattr_init
function initializes
.Fa attr
with all the default mutex attributes.
.Pp
The
.Fn pthread_mutexattr_destroy
function destroys
.Fa attr .
.Pp
The
.Fn pthread_mutexattr_settype
functions set the mutex
.Fa type
value of the attribute.
Valid mutex types are:
.Bl -tag -width "XXX" -offset 2n
.It Dv PTHREAD_MUTEX_NORMAL
This type of mutex does not check for usage errors.
It will deadlock if reentered, and result in undefined behavior if a
locked mutex is unlocked by another thread.
Attempts to unlock an already unlocked
.Dv PTHREAD_MUTEX_NORMAL
mutex will result in undefined behavior.
.It Dv PTHREAD_MUTEX_ERRORCHECK
These mutexes do check for usage errors.
If an attempt is made to relock a
.Dv PTHREAD_MUTEX_ERRORCHECK
mutex without first dropping the lock, an error will be returned.
If a thread attempts to unlock a
.Dv PTHREAD_MUTEX_ERRORCHECK
mutex that is locked by another thread, an error will be returned.
If a thread attempts to unlock a
.Dv PTHREAD_MUTEX_ERRORCHECK
thread that is unlocked, an error will be returned.
.It Dv PTHREAD_MUTEX_RECURSIVE
These mutexes allow recursive locking.
An attempt to relock a
.Dv PTHREAD_MUTEX_RECURSIVE
mutex that is already locked by the same thread succeeds.
An equivalent number of
.Xr pthread_mutex_unlock 3
calls are needed before the mutex will wake another thread waiting
on this lock.
If a thread attempts to unlock a
.Dv PTHREAD_MUTEX_RECURSIVE
mutex that is locked by another thread, an error will be returned.
If a thread attempts to unlock a
.Dv PTHREAD_MUTEX_RECURSIVE
thread that is unlocked, an error will be returned.
.Pp
It is advised that
.Dv PTHREAD_MUTEX_RECURSIVE
mutexes are not used with condition variables.
This is because of the implicit unlocking done by
.Xr pthread_cond_wait 3
and
.Xr pthread_cond_timedwait 3 .
.It Dv PTHREAD_MUTEX_DEFAULT
Also this type of mutex will cause undefined behavior if reentered.
Unlocking a
.Dv PTHREAD_MUTEX_DEFAULT
mutex locked by another thread will result in undefined behavior.
Attempts to unlock an already unlocked
.Dv PTHREAD_MUTEX_DEFAULT
mutex will result in undefined behavior.
.Pp
This is the default mutex type for
.Fn pthread_mutexaddr_init .
.El
.Pp
The
.Fn pthread_mutexattr_gettype
functions copy the type value of the attribute to the location
pointed to by the second parameter.
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
The
.Fn pthread_mutexattr_init
function shall fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
Insufficient memory exists to initialize the mutex attributes object.
.El
.Pp
The
.Fn pthread_mutexattr_settype
function shall fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified either by
.Fa type
or
.Fa attr
is invalid.
.El
.Pp
No error numbers are defined for the
.Fn pthread_mutexattr_destroy
and
.Fn pthread_mutexattr_gettype
functions.
.\"
.\" .Pp
.\" .Fn pthread_mutexattr_setprioceiling
.\" may fail if:
.\" .Bl -tag -width Er
.\" .It Bq Er EINVAL
.\" Invalid value for
.\" .Fa attr ,
.\" or invalid value for
.\" .Fa prioceiling .
.\" .El
.\" .Pp
.\" .Fn pthread_mutexattr_getprioceiling
.\" may fail if:
.\" .Bl -tag -width Er
.\" .It Bq Er EINVAL
.\" Invalid value for
.\" .Fa attr .
.\" .El
.\" .Pp
.\" .Fn pthread_mutexattr_setprotocol
.\" may fail if:
.\" .Bl -tag -width Er
.\" .It Bq Er EINVAL
.\" Invalid value for
.\" .Fa attr ,
.\" or invalid value for
.\" .Fa protocol .
.\" .El
.\" .Pp
.\" .Fn pthread_mutexattr_getprotocol
.\" may fail if:
.\" .Bl -tag -width Er
.\" .It Bq Er EINVAL
.\" Invalid value for
.\" .Fa attr .
.\" .El
.\" .Pp
.Sh SEE ALSO
.Xr pthread_mutex_init 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,128 @@
.\" $NetBSD: pthread_once.3,v 1.9 2012/11/12 23:28:11 uwe Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_once.3,v 1.14 2002/09/16 19:29:29 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_ONCE 3
.Os
.Sh NAME
.Nm pthread_once
.Nd dynamic package initialization
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_once "pthread_once_t *once_control" "void (*init_routine)(void)"
.Vt pthread_once_t once_control No = Dv PTHREAD_ONCE_INIT;
.Sh DESCRIPTION
The first call to
.Fn pthread_once
by any thread in a process, with a given
.Fa once_control ,
will call the
.Fa init_routine Ns ()
with no arguments.
Subsequent calls to
.Fn pthread_once
with the same
.Fa once_control
will not call the
.Fa init_routine Ns ().
On return from
.Fn pthread_once ,
it is guaranteed that
.Fa init_routine Ns ()
has completed.
The
.Fa once_control
parameter is used to determine whether the associated initialization
routine has been called.
.Pp
The function
.Fn pthread_once
is not a cancellation point.
However, if
.Fa init_routine Ns ()
is a cancellation point and is cancelled, the effect on
.Fa once_control
is as if
.Fn pthread_once
was never called.
.Pp
The constant
.Dv PTHREAD_ONCE_INIT
initializes the static once synchronization control structure
.Fa once_control
to be used with
.Fn pthread_once .
The behavior of
.Fn pthread_once
is undefined if
.Fa once_control
has automatic storage duration or is not initialized by
.Dv PTHREAD_ONCE_INIT .
.Sh RETURN VALUES
If successful, the
.Fn pthread_once
function will return zero.
Otherwise an error number will be returned to
indicate the error.
.Sh ERRORS
None.
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,72 @@
/* $NetBSD: pthread_once.c,v 1.3 2013/03/21 16:49:12 christos Exp $ */
/*-
* Copyright (c) 2001, 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams, and by Jason R. Thorpe.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_once.c,v 1.3 2013/03/21 16:49:12 christos Exp $");
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
static void
once_cleanup(void *closure)
{
pthread_mutex_unlock((pthread_mutex_t *)closure);
}
int
pthread_once(pthread_once_t *once_control, void (*routine)(void))
{
if (__predict_false(__uselibcstub))
return __libc_thr_once_stub(once_control, routine);
if (once_control->pto_done == 0) {
pthread_mutex_lock(&once_control->pto_mutex);
pthread_cleanup_push(&once_cleanup, &once_control->pto_mutex);
if (once_control->pto_done == 0) {
routine();
once_control->pto_done = 1;
}
pthread_cleanup_pop(1);
}
return 0;
}
__strong_alias(__libc_thr_once,pthread_once)

View File

@@ -0,0 +1,137 @@
/* $NetBSD: pthread_queue.h,v 1.5 2009/10/05 23:33:48 rmind Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_QUEUE_H
#define _LIB_PTHREAD_QUEUE_H
/*
* Definition of a queue interface for the pthread library.
* Style modeled on the sys/queue.h macros; implementation taken from
* the tail queue, with the added property of static initializability
* (and a corresponding extra cost in the _INSERT_TAIL() function.
*/
/*
* Queue definitions.
*/
#define PTQ_HEAD(name, type) \
struct name { \
struct type *ptqh_first;/* first element */ \
struct type **ptqh_last;/* addr of last next element */ \
}
#define PTQ_HEAD_INITIALIZER { NULL, NULL }
#define PTQ_ENTRY(type) \
struct { \
struct type *ptqe_next; /* next element */ \
struct type **ptqe_prev;/* address of previous next element */ \
}
/*
* Queue functions.
*/
#define PTQ_INIT(head) do { \
(head)->ptqh_first = NULL; \
(head)->ptqh_last = &(head)->ptqh_first; \
} while (/*CONSTCOND*/0)
#define PTQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.ptqe_next = (head)->ptqh_first) != NULL) \
(head)->ptqh_first->field.ptqe_prev = \
&(elm)->field.ptqe_next; \
else \
(head)->ptqh_last = &(elm)->field.ptqe_next; \
(head)->ptqh_first = (elm); \
(elm)->field.ptqe_prev = &(head)->ptqh_first; \
} while (/*CONSTCOND*/0)
#define PTQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.ptqe_next = NULL; \
if ((head)->ptqh_last == NULL) \
(head)->ptqh_last = &(head)->ptqh_first; \
(elm)->field.ptqe_prev = (head)->ptqh_last; \
*(head)->ptqh_last = (elm); \
(head)->ptqh_last = &(elm)->field.ptqe_next; \
} while (/*CONSTCOND*/0)
#define PTQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.ptqe_next = (listelm)->field.ptqe_next) != NULL)\
(elm)->field.ptqe_next->field.ptqe_prev = \
&(elm)->field.ptqe_next; \
else \
(head)->ptqh_last = &(elm)->field.ptqe_next; \
(listelm)->field.ptqe_next = (elm); \
(elm)->field.ptqe_prev = &(listelm)->field.ptqe_next; \
} while (/*CONSTCOND*/0)
#define PTQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.ptqe_prev = (listelm)->field.ptqe_prev; \
(elm)->field.ptqe_next = (listelm); \
*(listelm)->field.ptqe_prev = (elm); \
(listelm)->field.ptqe_prev = &(elm)->field.ptqe_next; \
} while (/*CONSTCOND*/0)
#define PTQ_REMOVE(head, elm, field) do { \
if (((elm)->field.ptqe_next) != NULL) \
(elm)->field.ptqe_next->field.ptqe_prev = \
(elm)->field.ptqe_prev; \
else \
(head)->ptqh_last = (elm)->field.ptqe_prev; \
*(elm)->field.ptqe_prev = (elm)->field.ptqe_next; \
} while (/*CONSTCOND*/0)
/*
* Queue access methods.
*/
#define PTQ_EMPTY(head) ((head)->ptqh_first == NULL)
#define PTQ_FIRST(head) ((head)->ptqh_first)
#define PTQ_NEXT(elm, field) ((elm)->field.ptqe_next)
#define PTQ_LAST(head, headname) \
(*(((struct headname *)(void *)((head)->ptqh_last))->ptqh_last))
#define PTQ_PREV(elm, headname, field) \
(*(((struct headname *)(void *)((elm)->field.ptqe_prev))->ptqh_last))
#define PTQ_FOREACH(var, head, field) \
for ((var) = ((head)->ptqh_first); \
(var); \
(var) = ((var)->field.ptqe_next))
#define PTQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = (*(((struct headname *)(void *)((head)->ptqh_last))->ptqh_last)); \
(var); \
(var) = (*(((struct headname *)(void *)((var)->field.ptqe_prev))->ptqh_last)))
#endif /* _LIB_PTHREAD_QUEUE_H */

View File

@@ -0,0 +1,346 @@
.\" $NetBSD: pthread_rwlock.3,v 1.5 2012/11/12 23:34:50 uwe Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1998 Alex Nash
.\" 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.
.\"
.\" ----------------------------------------------------------------------------
.Dd July 8, 2010
.Dt PTHREAD_RWLOCK 3
.Os
.Sh NAME
.Nm pthread_rwlock
.Nd read/write lock interface
.Sh LIBRARY
.Lb libpthread
.\" ----------------------------------------------------------------------------
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_rwlock_init "pthread_rwlock_t * restrict lock" \
"const pthread_rwlockattr_t * restrict attr"
.Vt pthread_rwlock_t lock No = Dv PTHREAD_RWLOCK_INITIALIZER;
.Ft int
.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock"
.Ft int
.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
.Ft int
.Fn pthread_rwlock_timedrdlock "pthread_rwlock_t * restrict lock" \
"const struct timespec * restrict abstime"
.Ft int
.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
.Ft int
.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
.Ft int
.Fn pthread_rwlock_timedwrlock "pthread_rwlock_t * restrict lock" \
"const struct timespec * restrict abstime"
.Ft int
.Fn pthread_rwlock_trywrlock "pthread_rwlock_t *lock"
.Ft int
.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock"
.\" ----------------------------------------------------------------------------
.Sh DESCRIPTION
The
.Fn pthread_rwlock_init
function is used to initialize a read/write lock, with attributes
specified by
.Fa attr .
If
.Fa attr
is
.Dv NULL ,
the default read/write lock attributes are used.
.Pp
The results of calling
.Fn pthread_rwlock_init
with an already initialized lock are undefined.
.Pp
The macro
.Dv PTHREAD_RWLOCK_INITIALIZER
can be used to initialize a read/write lock when the allocation can be done
statically, no error checking is required, and the default attributes are
appropriate.
The behavior is similar to calling
.Fn pthread_rwlock_init
with
.Fa attr
specified as
.Dv NULL .
.Pp
.\" -----
The
.Fn pthread_rwlock_destroy
function is used to destroy a read/write lock previously created with
.Fn pthread_rwlock_init .
.Pp
.\" -----
The
.Fn pthread_rwlock_rdlock
function acquires a read lock on
.Fa lock
provided that
.Fa lock
is not presently held for writing and no writer threads are
presently blocked on the lock.
If the read lock cannot be immediately acquired, the calling thread
blocks until it can acquire the lock.
.Pp
The
.Fn pthread_rwlock_timedrdlock
performs the same action, but will not wait beyond
.Fa abstime
to obtain the lock before returning.
.Pp
The
.Fn pthread_rwlock_tryrdlock
function performs the same action as
.Fn pthread_rwlock_rdlock ,
but does not block if the lock cannot be immediately obtained (i.e.,
the lock is held for writing or there are waiting writers).
.Pp
A thread may hold multiple concurrent read locks.
If so,
.Fn pthread_rwlock_unlock
must be called once for each lock obtained.
.Pp
The results of acquiring a read lock while the calling thread holds
a write lock are undefined.
.Pp
.\" -----
The
.Fn pthread_rwlock_wrlock
function blocks until a write lock can be acquired against
.Fa lock .
.Pp
The
.Fn pthread_rwlock_timedwrlock
performs the same action, but will not wait beyond
.Fa abstime
to obtain the lock before returning.
.Pp
The
.Fn pthread_rwlock_trywrlock
function performs the same action as
.Fn pthread_rwlock_wrlock ,
but does not block if the lock cannot be immediately obtained.
.Pp
The results are undefined if the calling thread already holds the
lock at the time the call is made.
.Pp
.\" -----
The
.Fn pthread_rwlock_unlock
function is used to release the read/write lock previously obtained by
.Fn pthread_rwlock_rdlock ,
.Fn pthread_rwlock_wrlock ,
.Fn pthread_rwlock_tryrdlock ,
or
.Fn pthread_rwlock_trywrlock .
.\" ----------------------------------------------------------------------------
.Sh RETURN VALUES
If successful, the
.Fn pthread_rwlock_init
function will return zero.
Otherwise an error number will be returned to indicate the error.
.Pp
If successful, the
.Fn pthread_rwlock_destroy ,
.Fn pthread_rwlock_rdlock ,
.Fn pthread_rwlock_timedrdlock ,
.Fn pthread_rwlock_tryrdlock ,
.Fn pthread_rwlock_wrlock ,
.Fn pthread_rwlock_timedwrlock ,
.Fn pthread_rwlock_trywrlock ,
and
.Fn pthread_rwlock_unlock
will return zero.
Otherwise an error number will be returned to indicate the error.
.Pp
The results are undefined if
.Fa lock
is not held by the calling thread.
.\" ----------------------------------------------------------------------------
.Sh ERRORS
The
.Fn pthread_rwlock_init
function may fail if:
.Bl -tag -width Er
.It Bq Er EAGAIN
The system lacks the resources to initialize another read-write lock.
.It Bq Er EBUSY
The system has detected an attempt to re-initialize the object
referenced by
.Fa lock ,
a previously initialized but not yet destroyed read/write lock.
.It Bq Er EINVAL
The value specified by
.Fa attr
is invalid.
.It Bq Er ENOMEM
Insufficient memory exists to initialize the read-write lock.
.El
.Pp
.\" -----
The
.Fn pthread_rwlock_destroy
function may fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The system has detected an attempt to destroy the object referenced by
.Fa lock
while it is locked.
.It Bq Er EINVAL
The value specified by
.Fa lock
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_rwlock_tryrdlock
function shall fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The lock could not be acquired because a writer holds the lock or
was blocked on it.
.El
.Pp
The
.Fn pthread_rwlock_timedrdlock
function shall fail if:
.Bl -tag -width Er
.It Bq Er ETIMEDOUT
The time specified by
.Fa abstime
was reached before the lock could be obtained.
.El
.Pp
The
.Fn pthread_rwlock_rdlock ,
.Fn pthread_rwlock_timedrdlock ,
and
.Fn pthread_rwlock_tryrdlock
functions may fail if:
.Bl -tag -width Er
.It Bq Er EAGAIN
The lock could not be acquired because the maximum number of read locks
against
.Fa lock
has been exceeded.
.It Bq Er EDEADLK
The current thread already owns
.Fa lock
for writing.
.It Bq Er EINVAL
The value specified by
.Fa lock
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_rwlock_trywrlock
function shall fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The calling thread is not able to acquire the lock without blocking.
.El
.Pp
The
.Fn pthread_rwlock_timedrdlock
function shall fail if:
.Bl -tag -width Er
.It Bq Er ETIMEDOUT
The time specified by
.Fa abstime
was reached before the lock could be obtained.
.El
.Pp
The
.Fn pthread_rwlock_wrlock ,
.Fn pthread_rwlock_timedwrlock ,
and
.Fn pthread_rwlock_trywrlock
functions may fail if:
.Bl -tag -width Er
.It Bq Er EDEADLK
The calling thread already owns the read/write lock (for reading
or writing).
.It Bq Er EINVAL
The value specified by
.Fa lock
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_rwlock_unlock
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa lock
is invalid.
.It Bq Er EPERM
The current thread does not own the read/write lock.
.El
.\" ----------------------------------------------------------------------------
.Sh SEE ALSO
.Xr pthread 3 ,
.Xr pthread_barrier 3 ,
.Xr pthread_cond 3 ,
.Xr pthread_mutex 3 ,
.Xr pthread_rwlockattr 3 ,
.Xr pthread_spin 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .
.\" ----------------------------------------------------------------------------
.Sh BUGS
The
.Dv PTHREAD_PROCESS_SHARED
attribute is not supported.

View File

@@ -0,0 +1,664 @@
/* $NetBSD: pthread_rwlock.c,v 1.33 2013/03/21 16:49:12 christos Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams, by Jason R. Thorpe, and by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_rwlock.c,v 1.33 2013/03/21 16:49:12 christos Exp $");
#include <sys/types.h>
#include <sys/lwpctl.h>
#include <time.h>
#include <errno.h>
#include <stddef.h>
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
#define _RW_LOCKED 0
#define _RW_WANT_WRITE 1
#define _RW_WANT_READ 2
#if __GNUC_PREREQ__(3, 0)
#define NOINLINE __attribute ((noinline))
#else
#define NOINLINE /* nothing */
#endif
static int pthread__rwlock_wrlock(pthread_rwlock_t *, const struct timespec *);
static int pthread__rwlock_rdlock(pthread_rwlock_t *, const struct timespec *);
static void pthread__rwlock_early(void *);
int _pthread_rwlock_held_np(pthread_rwlock_t *);
int _pthread_rwlock_rdheld_np(pthread_rwlock_t *);
int _pthread_rwlock_wrheld_np(pthread_rwlock_t *);
#ifndef lint
__weak_alias(pthread_rwlock_held_np,_pthread_rwlock_held_np)
__weak_alias(pthread_rwlock_rdheld_np,_pthread_rwlock_rdheld_np)
__weak_alias(pthread_rwlock_wrheld_np,_pthread_rwlock_wrheld_np)
#endif
__strong_alias(__libc_rwlock_init,pthread_rwlock_init)
__strong_alias(__libc_rwlock_rdlock,pthread_rwlock_rdlock)
__strong_alias(__libc_rwlock_wrlock,pthread_rwlock_wrlock)
__strong_alias(__libc_rwlock_tryrdlock,pthread_rwlock_tryrdlock)
__strong_alias(__libc_rwlock_trywrlock,pthread_rwlock_trywrlock)
__strong_alias(__libc_rwlock_unlock,pthread_rwlock_unlock)
__strong_alias(__libc_rwlock_destroy,pthread_rwlock_destroy)
static inline uintptr_t
rw_cas(pthread_rwlock_t *ptr, uintptr_t o, uintptr_t n)
{
return (uintptr_t)atomic_cas_ptr(&ptr->ptr_owner, (void *)o,
(void *)n);
}
int
pthread_rwlock_init(pthread_rwlock_t *ptr,
const pthread_rwlockattr_t *attr)
{
if (__predict_false(__uselibcstub))
return __libc_rwlock_init_stub(ptr, attr);
if (attr && (attr->ptra_magic != _PT_RWLOCKATTR_MAGIC))
return EINVAL;
ptr->ptr_magic = _PT_RWLOCK_MAGIC;
PTQ_INIT(&ptr->ptr_rblocked);
PTQ_INIT(&ptr->ptr_wblocked);
ptr->ptr_nreaders = 0;
ptr->ptr_owner = NULL;
return 0;
}
int
pthread_rwlock_destroy(pthread_rwlock_t *ptr)
{
if (__predict_false(__uselibcstub))
return __libc_rwlock_destroy_stub(ptr);
if ((ptr->ptr_magic != _PT_RWLOCK_MAGIC) ||
(!PTQ_EMPTY(&ptr->ptr_rblocked)) ||
(!PTQ_EMPTY(&ptr->ptr_wblocked)) ||
(ptr->ptr_nreaders != 0) ||
(ptr->ptr_owner != NULL))
return EINVAL;
ptr->ptr_magic = _PT_RWLOCK_DEAD;
return 0;
}
/* We want function call overhead. */
NOINLINE static void
pthread__rwlock_pause(void)
{
pthread__smt_pause();
}
NOINLINE static int
pthread__rwlock_spin(uintptr_t owner)
{
pthread_t thread;
unsigned int i;
thread = (pthread_t)(owner & RW_THREAD);
if (thread == NULL || (owner & ~RW_THREAD) != RW_WRITE_LOCKED)
return 0;
if (thread->pt_lwpctl->lc_curcpu == LWPCTL_CPU_NONE ||
thread->pt_blocking)
return 0;
for (i = 128; i != 0; i--)
pthread__rwlock_pause();
return 1;
}
static int
pthread__rwlock_rdlock(pthread_rwlock_t *ptr, const struct timespec *ts)
{
uintptr_t owner, next;
pthread_mutex_t *interlock;
pthread_t self;
int error;
#ifdef ERRORCHECK
if (ptr->ptr_magic != _PT_RWLOCK_MAGIC)
return EINVAL;
#endif
for (owner = (uintptr_t)ptr->ptr_owner;; owner = next) {
/*
* Read the lock owner field. If the need-to-wait
* indicator is clear, then try to acquire the lock.
*/
if ((owner & (RW_WRITE_LOCKED | RW_WRITE_WANTED)) == 0) {
next = rw_cas(ptr, owner, owner + RW_READ_INCR);
if (owner == next) {
/* Got it! */
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
/*
* Didn't get it -- spin around again (we'll
* probably sleep on the next iteration).
*/
continue;
}
self = pthread__self();
if ((owner & RW_THREAD) == (uintptr_t)self)
return EDEADLK;
/* If held write locked and no waiters, spin. */
if (pthread__rwlock_spin(owner)) {
while (pthread__rwlock_spin(owner)) {
owner = (uintptr_t)ptr->ptr_owner;
}
next = owner;
continue;
}
/*
* Grab the interlock. Once we have that, we
* can adjust the waiter bits and sleep queue.
*/
interlock = pthread__hashlock(ptr);
pthread_mutex_lock(interlock);
/*
* Mark the rwlock as having waiters. If the set fails,
* then we may not need to sleep and should spin again.
*/
next = rw_cas(ptr, owner, owner | RW_HAS_WAITERS);
if (owner != next) {
pthread_mutex_unlock(interlock);
continue;
}
/* The waiters bit is set - it's safe to sleep. */
PTQ_INSERT_HEAD(&ptr->ptr_rblocked, self, pt_sleep);
ptr->ptr_nreaders++;
self->pt_rwlocked = _RW_WANT_READ;
self->pt_sleepobj = &ptr->ptr_rblocked;
self->pt_early = pthread__rwlock_early;
error = pthread__park(self, interlock, &ptr->ptr_rblocked,
ts, 0, &ptr->ptr_rblocked);
/* Did we get the lock? */
if (self->pt_rwlocked == _RW_LOCKED) {
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
if (error != 0)
return error;
pthread__errorfunc(__FILE__, __LINE__, __func__,
"direct handoff failure");
}
}
int
pthread_rwlock_tryrdlock(pthread_rwlock_t *ptr)
{
uintptr_t owner, next;
if (__predict_false(__uselibcstub))
return __libc_rwlock_tryrdlock_stub(ptr);
#ifdef ERRORCHECK
if (ptr->ptr_magic != _PT_RWLOCK_MAGIC)
return EINVAL;
#endif
/*
* Don't get a readlock if there is a writer or if there are waiting
* writers; i.e. prefer writers to readers. This strategy is dictated
* by SUSv3.
*/
for (owner = (uintptr_t)ptr->ptr_owner;; owner = next) {
if ((owner & (RW_WRITE_LOCKED | RW_WRITE_WANTED)) != 0)
return EBUSY;
next = rw_cas(ptr, owner, owner + RW_READ_INCR);
if (owner == next) {
/* Got it! */
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
}
}
static int
pthread__rwlock_wrlock(pthread_rwlock_t *ptr, const struct timespec *ts)
{
uintptr_t owner, next;
pthread_mutex_t *interlock;
pthread_t self;
int error;
self = pthread__self();
#ifdef ERRORCHECK
if (ptr->ptr_magic != _PT_RWLOCK_MAGIC)
return EINVAL;
#endif
for (owner = (uintptr_t)ptr->ptr_owner;; owner = next) {
/*
* Read the lock owner field. If the need-to-wait
* indicator is clear, then try to acquire the lock.
*/
if ((owner & RW_THREAD) == 0) {
next = rw_cas(ptr, owner,
(uintptr_t)self | RW_WRITE_LOCKED);
if (owner == next) {
/* Got it! */
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
/*
* Didn't get it -- spin around again (we'll
* probably sleep on the next iteration).
*/
continue;
}
if ((owner & RW_THREAD) == (uintptr_t)self)
return EDEADLK;
/* If held write locked and no waiters, spin. */
if (pthread__rwlock_spin(owner)) {
while (pthread__rwlock_spin(owner)) {
owner = (uintptr_t)ptr->ptr_owner;
}
next = owner;
continue;
}
/*
* Grab the interlock. Once we have that, we
* can adjust the waiter bits and sleep queue.
*/
interlock = pthread__hashlock(ptr);
pthread_mutex_lock(interlock);
/*
* Mark the rwlock as having waiters. If the set fails,
* then we may not need to sleep and should spin again.
*/
next = rw_cas(ptr, owner,
owner | RW_HAS_WAITERS | RW_WRITE_WANTED);
if (owner != next) {
pthread_mutex_unlock(interlock);
continue;
}
/* The waiters bit is set - it's safe to sleep. */
PTQ_INSERT_TAIL(&ptr->ptr_wblocked, self, pt_sleep);
self->pt_rwlocked = _RW_WANT_WRITE;
self->pt_sleepobj = &ptr->ptr_wblocked;
self->pt_early = pthread__rwlock_early;
error = pthread__park(self, interlock, &ptr->ptr_wblocked,
ts, 0, &ptr->ptr_wblocked);
/* Did we get the lock? */
if (self->pt_rwlocked == _RW_LOCKED) {
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
if (error != 0)
return error;
pthread__errorfunc(__FILE__, __LINE__, __func__,
"direct handoff failure");
}
}
int
pthread_rwlock_trywrlock(pthread_rwlock_t *ptr)
{
uintptr_t owner, next;
pthread_t self;
if (__predict_false(__uselibcstub))
return __libc_rwlock_trywrlock_stub(ptr);
#ifdef ERRORCHECK
if (ptr->ptr_magic != _PT_RWLOCK_MAGIC)
return EINVAL;
#endif
self = pthread__self();
for (owner = (uintptr_t)ptr->ptr_owner;; owner = next) {
if (owner != 0)
return EBUSY;
next = rw_cas(ptr, owner, (uintptr_t)self | RW_WRITE_LOCKED);
if (owner == next) {
/* Got it! */
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif
return 0;
}
}
}
int
pthread_rwlock_rdlock(pthread_rwlock_t *ptr)
{
if (__predict_false(__uselibcstub))
return __libc_rwlock_rdlock_stub(ptr);
return pthread__rwlock_rdlock(ptr, NULL);
}
int
pthread_rwlock_timedrdlock(pthread_rwlock_t *ptr,
const struct timespec *abs_timeout)
{
if (abs_timeout == NULL)
return EINVAL;
if ((abs_timeout->tv_nsec >= 1000000000) ||
(abs_timeout->tv_nsec < 0) ||
(abs_timeout->tv_sec < 0))
return EINVAL;
return pthread__rwlock_rdlock(ptr, abs_timeout);
}
int
pthread_rwlock_wrlock(pthread_rwlock_t *ptr)
{
if (__predict_false(__uselibcstub))
return __libc_rwlock_wrlock_stub(ptr);
return pthread__rwlock_wrlock(ptr, NULL);
}
int
pthread_rwlock_timedwrlock(pthread_rwlock_t *ptr,
const struct timespec *abs_timeout)
{
if (abs_timeout == NULL)
return EINVAL;
if ((abs_timeout->tv_nsec >= 1000000000) ||
(abs_timeout->tv_nsec < 0) ||
(abs_timeout->tv_sec < 0))
return EINVAL;
return pthread__rwlock_wrlock(ptr, abs_timeout);
}
int
pthread_rwlock_unlock(pthread_rwlock_t *ptr)
{
uintptr_t owner, decr, new, next;
pthread_mutex_t *interlock;
pthread_t self, thread;
if (__predict_false(__uselibcstub))
return __libc_rwlock_unlock_stub(ptr);
#ifdef ERRORCHECK
if ((ptr == NULL) || (ptr->ptr_magic != _PT_RWLOCK_MAGIC))
return EINVAL;
#endif
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_exit();
#endif
/*
* Since we used an add operation to set the required lock
* bits, we can use a subtract to clear them, which makes
* the read-release and write-release path similar.
*/
owner = (uintptr_t)ptr->ptr_owner;
if ((owner & RW_WRITE_LOCKED) != 0) {
self = pthread__self();
decr = (uintptr_t)self | RW_WRITE_LOCKED;
if ((owner & RW_THREAD) != (uintptr_t)self) {
return EPERM;
}
} else {
decr = RW_READ_INCR;
if (owner == 0) {
return EPERM;
}
}
for (;; owner = next) {
/*
* Compute what we expect the new value of the lock to be.
* Only proceed to do direct handoff if there are waiters,
* and if the lock would become unowned.
*/
new = (owner - decr);
if ((new & (RW_THREAD | RW_HAS_WAITERS)) != RW_HAS_WAITERS) {
next = rw_cas(ptr, owner, new);
if (owner == next) {
/* Released! */
return 0;
}
continue;
}
/*
* Grab the interlock. Once we have that, we can adjust
* the waiter bits. We must check to see if there are
* still waiters before proceeding.
*/
interlock = pthread__hashlock(ptr);
pthread_mutex_lock(interlock);
owner = (uintptr_t)ptr->ptr_owner;
if ((owner & RW_HAS_WAITERS) == 0) {
pthread_mutex_unlock(interlock);
next = owner;
continue;
}
/*
* Give the lock away. SUSv3 dictates that we must give
* preference to writers.
*/
self = pthread__self();
if ((thread = PTQ_FIRST(&ptr->ptr_wblocked)) != NULL) {
new = (uintptr_t)thread | RW_WRITE_LOCKED;
if (PTQ_NEXT(thread, pt_sleep) != NULL)
new |= RW_HAS_WAITERS | RW_WRITE_WANTED;
else if (ptr->ptr_nreaders != 0)
new |= RW_HAS_WAITERS;
/*
* Set in the new value. The lock becomes owned
* by the writer that we are about to wake.
*/
(void)atomic_swap_ptr(&ptr->ptr_owner, (void *)new);
/* Wake the writer. */
thread->pt_rwlocked = _RW_LOCKED;
pthread__unpark(&ptr->ptr_wblocked, self,
interlock);
} else {
new = 0;
PTQ_FOREACH(thread, &ptr->ptr_rblocked, pt_sleep) {
/*
* May have already been handed the lock,
* since pthread__unpark_all() can release
* our interlock before awakening all
* threads.
*/
if (thread->pt_sleepobj == NULL)
continue;
new += RW_READ_INCR;
thread->pt_rwlocked = _RW_LOCKED;
}
/*
* Set in the new value. The lock becomes owned
* by the readers that we are about to wake.
*/
(void)atomic_swap_ptr(&ptr->ptr_owner, (void *)new);
/* Wake up all sleeping readers. */
ptr->ptr_nreaders = 0;
pthread__unpark_all(&ptr->ptr_rblocked, self,
interlock);
}
pthread_mutex_unlock(interlock);
return 0;
}
}
/*
* Called when a timedlock awakens early to adjust the waiter bits.
* The rwlock's interlock is held on entry, and the caller has been
* removed from the waiters lists.
*/
static void
pthread__rwlock_early(void *obj)
{
uintptr_t owner, set, new, next;
pthread_rwlock_t *ptr;
pthread_t self;
u_int off;
self = pthread__self();
switch (self->pt_rwlocked) {
case _RW_WANT_READ:
off = offsetof(pthread_rwlock_t, ptr_rblocked);
break;
case _RW_WANT_WRITE:
off = offsetof(pthread_rwlock_t, ptr_wblocked);
break;
default:
pthread__errorfunc(__FILE__, __LINE__, __func__,
"bad value of pt_rwlocked");
off = 0;
/* NOTREACHED */
break;
}
/* LINTED mind your own business */
ptr = (pthread_rwlock_t *)((uint8_t *)obj - off);
owner = (uintptr_t)ptr->ptr_owner;
if ((owner & RW_THREAD) == 0) {
pthread__errorfunc(__FILE__, __LINE__, __func__,
"lock not held");
}
if (!PTQ_EMPTY(&ptr->ptr_wblocked))
set = RW_HAS_WAITERS | RW_WRITE_WANTED;
else if (ptr->ptr_nreaders != 0)
set = RW_HAS_WAITERS;
else
set = 0;
for (;; owner = next) {
new = (owner & ~(RW_HAS_WAITERS | RW_WRITE_WANTED)) | set;
next = rw_cas(ptr, owner, new);
if (owner == next)
break;
}
}
int
_pthread_rwlock_held_np(pthread_rwlock_t *ptr)
{
uintptr_t owner = (uintptr_t)ptr->ptr_owner;
if ((owner & RW_WRITE_LOCKED) != 0)
return (owner & RW_THREAD) == (uintptr_t)pthread__self();
return (owner & RW_THREAD) != 0;
}
int
_pthread_rwlock_rdheld_np(pthread_rwlock_t *ptr)
{
uintptr_t owner = (uintptr_t)ptr->ptr_owner;
return (owner & RW_THREAD) != 0 && (owner & RW_WRITE_LOCKED) == 0;
}
int
_pthread_rwlock_wrheld_np(pthread_rwlock_t *ptr)
{
uintptr_t owner = (uintptr_t)ptr->ptr_owner;
return (owner & (RW_THREAD | RW_WRITE_LOCKED)) ==
((uintptr_t)pthread__self() | RW_WRITE_LOCKED);
}
int
pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
{
if (attr == NULL)
return EINVAL;
attr->ptra_magic = _PT_RWLOCKATTR_MAGIC;
return 0;
}
int
pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
{
if ((attr == NULL) ||
(attr->ptra_magic != _PT_RWLOCKATTR_MAGIC))
return EINVAL;
attr->ptra_magic = _PT_RWLOCKATTR_DEAD;
return 0;
}

View File

@@ -0,0 +1,105 @@
.\" $NetBSD: pthread_rwlockattr.3,v 1.8 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1998 Alex Nash
.\" 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: src/lib/libpthread/man/pthread_rwlockattr_init.3,v 1.7 2002/09/16 19:29:29 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_RWLOCKATTR 3
.Os
.Sh NAME
.Nm pthread_rwlockattr_init ,
.Nm pthread_rwlockattr_destroy
.Nd initialize or destroy read/write lock attributes
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
.Ft int
.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
.Sh DESCRIPTION
The
.Fn pthread_rwlockattr_init
function is used to initialize a read/write lock attributes object.
.Pp
The
.Fn pthread_rwlockattr_destroy
function is used to destroy a read/write lock attribute object
previously created with
.Fn pthread_rwlockattr_init .
.Sh RETURN VALUES
If successful, the
.Fn pthread_rwlockattr_init
and
.Fn pthread_rwlockattr_destroy
functions return zero.
Otherwise an error number will be returned to indicate the error.
.Sh ERRORS
.Fn pthread_rwlockattr_init
shall fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
Insufficient memory exists to initialize the read/write lock attributes object.
.El
.Pp
.Fn pthread_rwlockattr_init
and
.Fn pthread_rwlockattr_destroy
may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa attr
is invalid.
.El
.Sh SEE ALSO
.Xr pthread_rwlock_init 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,120 @@
.\" $NetBSD: pthread_schedparam.3,v 1.7 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
.\" the first lines of this file unmodified other than the possible
.\" addition of one or more copyright notices.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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: src/lib/libpthread/man/pthread_schedparam.3,v 1.7 2002/09/16 19:29:29 mini Exp $
.Dd July 9, 2010
.Dt PTHREAD_SCHEDPARAM 3
.Os
.Sh NAME
.Nm pthread_setschedparam ,
.Nm pthread_getschedparam
.Nd thread scheduling parameter manipulation
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_setschedparam "pthread_t thread" "int policy" "const struct sched_param *param"
.Ft int
.Fn pthread_getschedparam "pthread_t thread" "int * restrict policy" "struct sched_param * restrict param"
.Sh DESCRIPTION
The
.Fn pthread_setschedparam
and
.Fn pthread_getschedparam
functions set and get the scheduling parameters of individual threads.
The scheduling policy for a thread can be:
.Bl -tag -width SCHED_OTHER -offset indent
.It Dv SCHED_FIFO
First in, first out.
.It Dv SCHED_RR
Round-robin.
.It Dv SCHED_OTHER
The system default.
.El
.Pp
The thread priority (accessed via
.Va param-\*[Gt]sched_priority )
must be at least
.Dv PTHREAD_MIN_PRIORITY
and no more than
.Dv PTHREAD_MAX_PRIORITY .
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
.Sh ERRORS
.Fn pthread_setschedparam
may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Va policy
is invalid.
.It Bq Er ENOTSUP
Invalid value for scheduling parameters.
.It Bq Er ESRCH
Non-existent thread
.Va thread .
.El
.Pp
.Fn pthread_getschedparam
may fail if:
.Bl -tag -width Er
.It Bq Er ESRCH
Non-existent thread
.Va thread .
.El
.Sh SEE ALSO
.Xr pthread_attr_getschedparam 3 ,
.Xr sched 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,86 @@
.\" $NetBSD: pthread_self.3,v 1.4 2010/07/09 08:51:28 jruoho Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by John Birrell.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: src/lib/libpthread/man/pthread_self.3,v 1.10 2002/09/16 19:29:29 mini Exp $
.\"
.Dd July 9, 2010
.Dt PTHREAD_SELF 3
.Os
.Sh NAME
.Nm pthread_self
.Nd get the calling thread's ID
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft pthread_t
.Fn pthread_self "void"
.Sh DESCRIPTION
The
.Fn pthread_self
function returns the thread
.Tn ID
of the calling thread.
.Sh RETURN VALUES
The return value is the thread
.Tn ID .
.Sh ERRORS
None.
.Sh SEE ALSO
.Xr pthread_create 3 ,
.Xr pthread_equal 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,122 @@
.\" $NetBSD: pthread_sigmask.3,v 1.9 2010/07/09 10:55:11 wiz Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
.\" the first lines of this file unmodified other than the possible
.\" addition of one or more copyright notices.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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: src/lib/libpthread/man/pthread_sigmask.3,v 1.10 2002/09/16 19:29:29 mini Exp $
.Dd July 9, 2010
.Dt PTHREAD_SIGMASK 3
.Os
.Sh NAME
.Nm pthread_sigmask
.Nd examine and/or change a thread's signal mask
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.\" .In pthread.h
.In signal.h
.Ft int
.Fn pthread_sigmask "int how" "const sigset_t * restrict set" "sigset_t * restrict oset"
.Sh DESCRIPTION
The
.Fn pthread_sigmask
function examines and/or changes the calling thread's signal mask.
.Pp
If
.Fa set
is not
.Dv NULL ,
it specifies a set of signals to be modified, and
.Fa how
specifies what to set the signal mask to:
.Bl -tag -width SIG_UNBLOCK
.It Dv SIG_BLOCK
Union of the current mask and
.Fa set .
.It Dv SIG_UNBLOCK
Intersection of the current mask and the complement of
.Fa set .
.It Dv SIG_SETMASK
.Fa set .
.El
.Pp
If
.Fa oset
is not
.Dv NULL ,
the previous signal mask is stored in the location pointed to by
.Fa oset .
.Pp
.Dv SIGKILL
and
.Dv SIGSTOP
cannot be blocked, and will be silently ignored if included in the signal mask.
.Sh RETURN VALUES
If successful,
.Fn pthread_sigmask
returns 0.
Otherwise, an error is returned.
.Sh ERRORS
.Fn pthread_sigmask
shall fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
.Fa how
is not one of the defined values.
.El
.Sh SEE ALSO
.Xr sigaction 2 ,
.Xr sigpending 2 ,
.Xr sigprocmask 2 ,
.Xr sigsuspend 2 ,
.Xr sigwait 2 ,
.Xr sigsetops 3
.Sh STANDARDS
The function conforms to
.St -p1003.1-2001 .

View File

@@ -0,0 +1,115 @@
/* $NetBSD: pthread_specific.c,v 1.26 2013/03/21 16:49:12 christos Exp $ */
/*-
* Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_specific.c,v 1.26 2013/03/21 16:49:12 christos Exp $");
/* Functions and structures dealing with thread-specific data */
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
#include <string.h>
#include <sys/lwpctl.h>
#include "../libc/include/extern.h" /* for _sys_setcontext() */
int pthread_setcontext(const ucontext_t *);
__strong_alias(__libc_thr_setspecific,pthread_setspecific)
__strong_alias(__libc_thr_getspecific,pthread_getspecific)
__strong_alias(__libc_thr_curcpu,pthread_curcpu_np)
__strong_alias(setcontext,pthread_setcontext)
int
pthread_setspecific(pthread_key_t key, const void *value)
{
pthread_t self;
if (__predict_false(__uselibcstub))
return __libc_thr_setspecific_stub(key, value);
self = pthread__self();
/*
* We can't win here on constness. Having been given a
* "const void *", we can only assign it to other const void *,
* and return it from functions that are const void *, without
* generating a warning.
*/
return pthread__add_specific(self, key, value);
}
void *
pthread_getspecific(pthread_key_t key)
{
if (__predict_false(__uselibcstub))
return __libc_thr_getspecific_stub(key);
return pthread__self()->pt_specific[key].pts_value;
}
unsigned int
pthread_curcpu_np(void)
{
if (__predict_false(__uselibcstub))
return __libc_thr_curcpu_stub();
{
const int curcpu = pthread__self()->pt_lwpctl->lc_curcpu;
pthread__assert(curcpu != LWPCTL_CPU_NONE);
pthread__assert(curcpu != LWPCTL_CPU_EXITED);
pthread__assert(curcpu >= 0);
return curcpu;
}
}
/*
* Override setcontext so that pthread private pointer is preserved
*/
int
pthread_setcontext(const ucontext_t *ucp)
{
#ifdef _UC_TLSBASE
ucontext_t uc;
/*
* Only copy and clear _UC_TLSBASE if it is set.
*/
if (ucp->uc_flags & _UC_TLSBASE) {
uc = *ucp;
uc.uc_flags &= ~_UC_TLSBASE;
ucp = &uc;
}
#endif /* _UC_TLSBASE */
return _sys_setcontext(ucp);
}

View File

@@ -0,0 +1,208 @@
.\" $NetBSD: pthread_spin.3,v 1.5 2010/07/09 10:55:11 wiz Exp $
.\"
.\" Copyright (c) 2002, 2008, 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.\" ----------------------------------------------------------------------------
.Dd July 8, 2010
.Dt PTHREAD_SPIN 3
.Os
.Sh NAME
.Nm pthread_spin
.Nd spin lock interface
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_spin_init "pthread_spinlock_t *lock" "int pshared"
.Ft int
.Fn pthread_spin_destroy "pthread_spinlock_t *lock"
.Ft int
.Fn pthread_spin_lock "pthread_spinlock_t *lock"
.Ft int
.Fn pthread_spin_trylock "pthread_spinlock_t *lock"
.Ft int
.Fn pthread_spin_unlock "pthread_spinlock_t *lock"
.\" ----------------------------------------------------------------------------
.Sh DESCRIPTION
The
.Fn pthread_spin_init
function is used to initialize a spin lock.
In the
.Nx
implementation the
.Fa pshared
parameter is currently unused and all spin locks exhibit the
.Dv PTHREAD_PROCESS_SHARED
property, implying that all spin locks may be
accessed by threads of multiple processes.
The results of calling
.Fn pthread_spin_init
with an already initialized lock are undefined.
.Pp
.\" -----
The
.Fn pthread_spin_destroy
function is used to destroy a spin lock previously created with
.Fn pthread_spin_init .
It is undefined what happens if the function is called
when a thread holds the lock, or if the function is called
with an uninitialized spin lock.
.Pp
.\" -----
The
.Fn pthread_spin_lock
function acquires a spin lock on
.Fa lock ,
provided that
.Fa lock
is not presently held.
If the lock cannot be
immediately acquired, the calling thread repeatedly retries until it can
acquire the lock.
Undefined behavior may follow if the calling thread holds
the lock at the time the call is made.
.Pp
The
.Fn pthread_spin_trylock
function performs the same locking action, but does not block if the lock
cannot be immediately obtained; if the lock is held, the call fails.
.Pp
.\" -----
The
.Fn pthread_spin_unlock
function is used to release the read/write lock previously obtained by
.Fn pthread_spin_lock
or
.Fn pthread_spin_trylock .
The results are undefined if the lock is not held by the calling thread.
.\" ----------------------------------------------------------------------------
.Sh RETURN VALUES
If successful, all described functions return zero.
Otherwise an error number will be returned to indicate the error.
.Sh ERRORS
The
.Fn pthread_spin_init
function shall fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
Insufficient memory exists to initialize the lock.
.El
.Pp
The
.Fn pthread_spin_init
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The
.Fa lock
parameter was
.Dv NULL
or the
.Fa pshared
parameter was neither
.Dv PTHREAD_PROCESS_SHARED
nor
.Dv PTHREAD_PROCESS_PRIVATE .
.El
.Pp
.\" -----
The
.Fn pthread_spin_destroy
function may fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The system has detected an attempt to destroy the object referenced by
.Fa lock
while it is locked.
.It Bq Er EINVAL
The value specified by
.Fa lock
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_spin_trylock
function shall fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The lock could not be acquired because a writer holds the lock or
was blocked on it.
.El
.Pp
The
.Fn pthread_spin_lock
function may fail if:
.Bl -tag -width Er
.It Bq Er EDEADLK
The current thread already owns
.Fa lock
for writing.
.El
.Pp
The
.Fn pthread_spin_lock
and
.Fn pthread_spin_trylock
functions may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa lock
is invalid.
.El
.Pp
.\" -----
The
.Fn pthread_spin_unlock
function may fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The value specified by
.Fa lock
is invalid.
.El
.\" ----------------------------------------------------------------------------
.Sh SEE ALSO
.Xr pthread 3 ,
.Xr pthread_barrier 3 ,
.Xr pthread_cond 3 ,
.Xr pthread_mutex 3 ,
.Xr pthread_rwlock 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .
.\" ----------------------------------------------------------------------------
.Sh CAVEATS
Applications using spin locks are vulnerable to the effects of priority
inversion.
Applications using real-time threads
.Pq Dv SCHED_FIFO ,
.Pq Dv SCHED_RR
should not use these interfaces.
Outside carefully controlled environments, priority inversion with spin locks
can lead to system deadlock.
Mutexes are preferable in nearly every possible use case.

View File

@@ -0,0 +1,139 @@
/* $NetBSD: pthread_spin.c,v 1.6 2012/08/16 04:49:47 matt Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams and Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Public (POSIX-specified) spinlocks.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_spin.c,v 1.6 2012/08/16 04:49:47 matt Exp $");
#include <sys/types.h>
#include <sys/ras.h>
#include <machine/lock.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "pthread.h"
#include "pthread_int.h"
int
pthread_spin_init(pthread_spinlock_t *lock, int pshared)
{
#ifdef ERRORCHECK
if (lock == NULL || (pshared != PTHREAD_PROCESS_PRIVATE &&
pshared != PTHREAD_PROCESS_SHARED))
return EINVAL;
#endif
lock->pts_magic = _PT_SPINLOCK_MAGIC;
/*
* We don't actually use the pshared flag for anything;
* CPU simple locks have all the process-shared properties
* that we want anyway.
*/
lock->pts_flags = pshared;
pthread_lockinit(&lock->pts_spin);
return 0;
}
int
pthread_spin_destroy(pthread_spinlock_t *lock)
{
#ifdef ERRORCHECK
if (lock == NULL || lock->pts_magic != _PT_SPINLOCK_MAGIC)
return EINVAL;
if (!__SIMPLELOCK_UNLOCKED_P(&lock->pts_spin))
return EBUSY;
#endif
lock->pts_magic = _PT_SPINLOCK_DEAD;
return 0;
}
int
pthread_spin_lock(pthread_spinlock_t *lock)
{
pthread_t self;
#ifdef ERRORCHECK
if (lock == NULL || lock->pts_magic != _PT_SPINLOCK_MAGIC)
return EINVAL;
#endif
self = pthread__self();
while (pthread__spintrylock(self, &lock->pts_spin) == 0) {
pthread__smt_pause();
}
return 0;
}
int
pthread_spin_trylock(pthread_spinlock_t *lock)
{
pthread_t self;
#ifdef ERRORCHECK
if (lock == NULL || lock->pts_magic != _PT_SPINLOCK_MAGIC)
return EINVAL;
#endif
self = pthread__self();
if (pthread__spintrylock(self, &lock->pts_spin) == 0)
return EBUSY;
return 0;
}
int
pthread_spin_unlock(pthread_spinlock_t *lock)
{
pthread_t self;
#ifdef ERRORCHECK
if (lock == NULL || lock->pts_magic != _PT_SPINLOCK_MAGIC)
return EINVAL;
#endif
self = pthread__self();
pthread__spinunlock(self, &lock->pts_spin);
pthread__smt_wake();
return 0;
}

View File

@@ -0,0 +1,120 @@
.\" $NetBSD: pthread_suspend_np.3,v 1.5 2010/07/09 09:18:45 jruoho Exp $
.\"
.\" Copyright (c) 2003, 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Christos Zoulas.
.\"
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd July 9, 2010
.Dt PTHREAD_SUSPEND_NP 3
.Os
.Sh NAME
.Nm pthread_suspend_np ,
.Nm pthread_resume_np
.Nd suspend/resume the given thread
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_suspend_np "pthread_t thread"
.Ft int
.Fn pthread_resume_np "pthread_t thread"
.Sh DESCRIPTION
The
.Fn pthread_suspend_np
function suspends the
.Fa thread
given as argument.
If
.Fa thread
is the currently running thread as returned by
.Xr pthread_self 3 ,
the function fails and returns
.Er EDEADLK .
Otherwise, it removes the named thread from the running queue, and
adds it to the suspended queue.
The
.Fa thread
will remain blocked until
.Fn pthread_resume_np
is called on it.
In other words,
.Fn pthread_resume_np
resumes the
.Fa thread
given as argument, if it was suspended.
.Sh RETURN VALUES
Both functions return 0 on success and an error number indicating the
reason for the failure.
.Sh COMPATIBILITY
These functions are non-standard extensions.
.Sh ERRORS
The
.Fn pthread_suspend_np
function may fail if:
.Bl -tag -width Er
.It Bq Er EDEADLK
The thread requested to suspend was the currently running thread.
.It Bq Er ESRCH
The supplied
.Fa thread
was invalid.
.El
.Pp
The
.Fn pthread_resume_np
function may fail if:
.Bl -tag -width Er
.It Bq Er ESRCH
The supplied
.Fa thread
was invalid.
.El
.Sh NOTES
Some
.Fn pthread_suspend_np
implementations may allow suspending the current thread.
This is dangerous, because the semantics of the function would then
require the scheduler to schedule another thread, causing a thread
context switch.
Since that context switch can happen in a signal handler by someone
calling
.Fn pthread_suspend_np
in a signal handler, this is currently not allowed.
.Pp
In
.Fn pthread_resume_np
the
.Nx
implementation does not check if the
.Fa thread
argument is not already suspended.
Some implementations might return an error condition if
.Fn pthread_resume_np
is called on a non-suspended thread.
.Sh SEE ALSO
.Xr pthread_attr_setcreatesuspend_np 3 ,
.Xr pthread_self 3

View File

@@ -0,0 +1,271 @@
.\" $NetBSD: pthread_testcancel.3,v 1.9 2014/03/18 18:20:38 riastradh Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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: src/lib/libpthread/man/pthread_testcancel.3,v 1.9 2002/09/16 19:29:29 mini Exp $
.Dd August 6, 2010
.Dt PTHREAD_TESTCANCEL 3
.Os
.Sh NAME
.Nm pthread_setcancelstate ,
.Nm pthread_setcanceltype ,
.Nm pthread_testcancel
.Nd set cancelability state
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
.In pthread.h
.Ft int
.Fn pthread_setcancelstate "int state" "int *oldstate"
.Ft int
.Fn pthread_setcanceltype "int type" "int *oldtype"
.Ft void
.Fn pthread_testcancel "void"
.Sh DESCRIPTION
The
.Fn pthread_setcancelstate
function atomically both sets the calling thread's cancelability state
to the indicated
.Fa state
and, if
.Fa oldstate
is not
.Dv NULL ,
returns the previous cancelability state at the location referenced by
.Fa oldstate .
Legal values for
.Fa state
are
.Dv PTHREAD_CANCEL_ENABLE
and
.Dv PTHREAD_CANCEL_DISABLE .
.Pp
The
.Fn pthread_setcanceltype
function atomically both sets the calling thread's cancelability type
to the indicated
.Fa type
and, if
.Fa oldtype
is not
.Dv NULL ,
returns the previous cancelability type at the location referenced by
.Fa oldtype .
Legal values for
.Fa type
are
.Dv PTHREAD_CANCEL_DEFERRED
and
.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
.Pp
The cancelability state and type of any newly created threads, including the
thread in which
.Fn main
was first invoked, are
.Dv PTHREAD_CANCEL_ENABLE
and
.Dv PTHREAD_CANCEL_DEFERRED
respectively.
.Pp
The
.Fn pthread_testcancel
function creates a cancellation point in the calling thread.
The
.Fn pthread_testcancel
function has no effect if cancelability is disabled.
.Ss Cancelability States
The cancelability state of a thread determines the action taken upon
receipt of a cancellation request.
The thread may control cancellation in
a number of ways.
.Pp
Each thread maintains its own
.Dq cancelability state
which may be encoded in two bits:
.Bl -hang
.It Em Cancelability Enable
When cancelability is
.Dv PTHREAD_CANCEL_DISABLE ,
cancellation requests against the target thread are held pending.
.It Em Cancelability Type
When cancelability is enabled and the cancelability type is
.Dv PTHREAD_CANCEL_ASYNCHRONOUS ,
new or pending cancellation requests may be acted upon at any time.
When cancelability is enabled and the cancelability type is
.Dv PTHREAD_CANCEL_DEFERRED ,
cancellation requests are held pending until a cancellation point (see
below) is reached.
If cancelability is disabled, the setting of the
cancelability type has no immediate effect as all cancellation requests
are held pending; however, once cancelability is enabled again the new
type will be in effect.
.El
.Ss Cancellation Points
Cancellation points will occur when a thread is executing the following
functions:
.Fn accept ,
.Fn aio_suspend ,
.Fn clock_nanosleep ,
.Fn close ,
.Fn connect ,
.Fn creat ,
.Fn fcntl ,
.Fn fdatasync ,
.Fn fsync ,
.Fn fsync_range ,
.\".Fn getmsg ,
.\".Fn getpmsg ,
.Fn kevent ,
.\".Fn lockf ,
.Fn mq_receive ,
.Fn mq_send ,
.Fn mq_timedreceive ,
.Fn mq_timedsend ,
.Fn msgrcv ,
.Fn msgsnd ,
.Fn msync ,
.Fn nanosleep ,
.Fn open ,
.Fn pause ,
.Fn poll ,
.Fn pollts ,
.Fn pread ,
.Fn pselect ,
.Fn pthread_cond_timedwait ,
.Fn pthread_cond_wait ,
.Fn pthread_join ,
.Fn pthread_testcancel ,
.\".Fn putmsg ,
.\".Fn putpmsg ,
.Fn pwrite ,
.Fn read ,
.Fn readv ,
.Fn recv ,
.Fn recvfrom ,
.Fn recvmsg ,
.Fn select ,
.Fn sem_timedwait ,
.Fn sem_wait ,
.Fn send ,
.Fn sendmsg ,
.Fn sendto ,
.Fn sigpause ,
.Fn sigsuspend ,
.Fn sigtimedwait ,
.Fn sigwait ,
.Fn sigwaitinfo ,
.Fn sleep ,
.Fn system ,
.Fn tcdrain ,
.Fn usleep ,
.Fn wait ,
.Fn wait4 ,
.Fn waitid ,
.Fn waitpid ,
.Fn write ,
and
.Fn writev .
.Sh RETURN VALUES
If successful, the
.Fn pthread_setcancelstate
and
.Fn pthread_setcanceltype
functions will return zero.
Otherwise, an error number shall be returned to
indicate the error.
.Pp
The
.Fn pthread_setcancelstate
and
.Fn pthread_setcanceltype
functions are used to control the points at which a thread may be
asynchronously canceled.
For cancellation control to be usable in modular
fashion, some rules must be followed.
.Pp
For purposes of this discussion, consider an object to be a generalization
of a procedure.
It is a set of procedures and global variables written as
a unit and called by clients not known by the object.
Objects may depend
on other objects.
.Pp
First, cancelability should only be disabled on entry to an object, never
explicitly enabled.
On exit from an object, the cancelability state should
always be restored to its value on entry to the object.
.Pp
This follows from a modularity argument: if the client of an object (or the
client of an object that uses that object) has disabled cancelability, it is
because the client doesn't want to have to worry about how to clean up if the
thread is canceled while executing some sequence of actions.
If an object
is called in such a state and it enables cancelability and a cancellation
request is pending for that thread, then the thread will be canceled,
contrary to the wish of the client that disabled.
.Pp
Second, the cancelability type may be explicitly set to either
.Em deferred
or
.Em asynchronous
upon entry to an object.
But as with the cancelability state, on exit from
an object that cancelability type should always be restored to its value on
entry to the object.
.Pp
Finally, only functions that are cancel-safe may be called from a thread that
is asynchronously cancelable.
.Sh ERRORS
The function
.Fn pthread_setcancelstate
may fail with:
.Bl -tag -width Er
.It Bq Er EINVAL
The specified state is not
.Dv PTHREAD_CANCEL_ENABLE
or
.Dv PTHREAD_CANCEL_DISABLE .
.El
.Pp
The function
.Fn pthread_setcanceltype
may fail with:
.Bl -tag -width Er
.It Bq Er EINVAL
The specified state is not
.Dv PTHREAD_CANCEL_DEFERRED
or
.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
.El
.Sh SEE ALSO
.Xr pthread_cancel 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .
.Sh AUTHORS
This man page was written by
.An David Leonard Aq Mt d@openbsd.org
for the
.Ox
implementation of
.Xr pthread_cancel 3 .

View File

@@ -0,0 +1,363 @@
/* $NetBSD: pthread_tsd.c,v 1.15 2015/08/25 13:46:23 pooka Exp $ */
/*-
* Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams, by Andrew Doran, and by Christos Zoulas.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_tsd.c,v 1.15 2015/08/25 13:46:23 pooka Exp $");
/* Functions and structures dealing with thread-specific data */
#include <errno.h>
#include <sys/mman.h>
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
int pthread_keys_max;
static pthread_mutex_t tsd_mutex = PTHREAD_MUTEX_INITIALIZER;
static int nextkey;
PTQ_HEAD(pthread__tsd_list, pt_specific) *pthread__tsd_list = NULL;
void (**pthread__tsd_destructors)(void *) = NULL;
__strong_alias(__libc_thr_keycreate,pthread_key_create)
__strong_alias(__libc_thr_keydelete,pthread_key_delete)
static void
/*ARGSUSED*/
null_destructor(void *p)
{
}
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
void *
pthread_tsd_init(size_t *tlen)
{
char *pkm;
size_t alen;
char *arena;
if ((pkm = pthread__getenv("PTHREAD_KEYS_MAX")) != NULL) {
pthread_keys_max = (int)strtol(pkm, NULL, 0);
if (pthread_keys_max < _POSIX_THREAD_KEYS_MAX)
pthread_keys_max = _POSIX_THREAD_KEYS_MAX;
} else {
pthread_keys_max = PTHREAD_KEYS_MAX;
}
/*
* Can't use malloc here yet, because malloc will use the fake
* libc thread functions to initialize itself, so mmap the space.
*/
*tlen = sizeof(struct __pthread_st)
+ pthread_keys_max * sizeof(struct pt_specific);
alen = *tlen
+ sizeof(*pthread__tsd_list) * pthread_keys_max
+ sizeof(*pthread__tsd_destructors) * pthread_keys_max;
arena = mmap(NULL, alen, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
if (arena == MAP_FAILED) {
pthread_keys_max = 0;
return NULL;
}
pthread__tsd_list = (void *)arena;
arena += sizeof(*pthread__tsd_list) * pthread_keys_max;
pthread__tsd_destructors = (void *)arena;
arena += sizeof(*pthread__tsd_destructors) * pthread_keys_max;
return arena;
}
int
pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
{
int i;
if (__predict_false(__uselibcstub))
return __libc_thr_keycreate_stub(key, destructor);
/* Get a lock on the allocation list */
pthread_mutex_lock(&tsd_mutex);
/* Find an available slot:
* The condition for an available slot is one with the destructor
* not being NULL. If the desired destructor is NULL we set it to
* our own internal destructor to satisfy the non NULL condition.
*/
/* 1. Search from "nextkey" to the end of the list. */
for (i = nextkey; i < pthread_keys_max; i++)
if (pthread__tsd_destructors[i] == NULL)
break;
if (i == pthread_keys_max) {
/* 2. If that didn't work, search from the start
* of the list back to "nextkey".
*/
for (i = 0; i < nextkey; i++)
if (pthread__tsd_destructors[i] == NULL)
break;
if (i == nextkey) {
/* If we didn't find one here, there isn't one
* to be found.
*/
pthread_mutex_unlock(&tsd_mutex);
return EAGAIN;
}
}
/* Got one. */
pthread__assert(PTQ_EMPTY(&pthread__tsd_list[i]));
pthread__tsd_destructors[i] = destructor ? destructor : null_destructor;
nextkey = (i + 1) % pthread_keys_max;
pthread_mutex_unlock(&tsd_mutex);
*key = i;
return 0;
}
/*
* Each thread holds an array of pthread_keys_max pt_specific list
* elements. When an element is used it is inserted into the appropriate
* key bucket of pthread__tsd_list. This means that ptqe_prev == NULL,
* means that the element is not threaded, ptqe_prev != NULL it is
* already part of the list. When we set to a NULL value we delete from the
* list if it was in the list, and when we set to non-NULL value, we insert
* in the list if it was not already there.
*
* We keep this global array of lists of threads that have called
* pthread_set_specific with non-null values, for each key so that
* we don't have to check all threads for non-NULL values in
* pthread_key_destroy
*
* We could keep an accounting of the number of specific used
* entries per thread, so that we can update pt_havespecific when we delete
* the last one, but we don't bother for now
*/
int
pthread__add_specific(pthread_t self, pthread_key_t key, const void *value)
{
struct pt_specific *pt;
pthread__assert(key >= 0 && key < pthread_keys_max);
pthread_mutex_lock(&tsd_mutex);
pthread__assert(pthread__tsd_destructors[key] != NULL);
pt = &self->pt_specific[key];
self->pt_havespecific = 1;
if (value) {
if (pt->pts_next.ptqe_prev == NULL)
PTQ_INSERT_HEAD(&pthread__tsd_list[key], pt, pts_next);
} else {
if (pt->pts_next.ptqe_prev != NULL) {
PTQ_REMOVE(&pthread__tsd_list[key], pt, pts_next);
pt->pts_next.ptqe_prev = NULL;
}
}
pt->pts_value = __UNCONST(value);
pthread_mutex_unlock(&tsd_mutex);
return 0;
}
int
pthread_key_delete(pthread_key_t key)
{
/*
* This is tricky. The standard says of pthread_key_create()
* that new keys have the value NULL associated with them in
* all threads. According to people who were present at the
* standardization meeting, that requirement was written
* before pthread_key_delete() was introduced, and not
* reconsidered when it was.
*
* See David Butenhof's article in comp.programming.threads:
* Subject: Re: TSD key reusing issue
* Message-ID: <u97d8.29$fL6.200@news.cpqcorp.net>
* Date: Thu, 21 Feb 2002 09:06:17 -0500
* http://groups.google.com/groups?\
* hl=en&selm=u97d8.29%24fL6.200%40news.cpqcorp.net
*
* Given:
*
* 1: Applications are not required to clear keys in all
* threads before calling pthread_key_delete().
* 2: Clearing pointers without running destructors is a
* memory leak.
* 3: The pthread_key_delete() function is expressly forbidden
* to run any destructors.
*
* Option 1: Make this function effectively a no-op and
* prohibit key reuse. This is a possible resource-exhaustion
* problem given that we have a static storage area for keys,
* but having a non-static storage area would make
* pthread_setspecific() expensive (might need to realloc the
* TSD array).
*
* Option 2: Ignore the specified behavior of
* pthread_key_create() and leave the old values. If an
* application deletes a key that still has non-NULL values in
* some threads... it's probably a memory leak and hence
* incorrect anyway, and we're within our rights to let the
* application lose. However, it's possible (if unlikely) that
* the application is storing pointers to non-heap data, or
* non-pointers that have been wedged into a void pointer, so
* we can't entirely write off such applications as incorrect.
* This could also lead to running (new) destructors on old
* data that was never supposed to be associated with that
* destructor.
*
* Option 3: Follow the specified behavior of
* pthread_key_create(). Either pthread_key_create() or
* pthread_key_delete() would then have to clear the values in
* every thread's slot for that key. In order to guarantee the
* visibility of the NULL value in other threads, there would
* have to be synchronization operations in both the clearer
* and pthread_getspecific(). Putting synchronization in
* pthread_getspecific() is a big performance lose. But in
* reality, only (buggy) reuse of an old key would require
* this synchronization; for a new key, there has to be a
* memory-visibility propagating event between the call to
* pthread_key_create() and pthread_getspecific() with that
* key, so setting the entries to NULL without synchronization
* will work, subject to problem (2) above. However, it's kind
* of slow.
*
* Note that the argument in option 3 only applies because we
* keep TSD in ordinary memory which follows the pthreads
* visibility rules. The visibility rules are not required by
* the standard to apply to TSD, so the argument doesn't
* apply in general, just to this implementation.
*/
/*
* We do option 3; we find the list of all pt_specific structures
* threaded on the key we are deleting, unthread them, and set the
* pointer to NULL. Finally we unthread the entry, freeing it for
* further use.
*
* We don't call the destructor here, it is the responsibility
* of the application to cleanup the storage:
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/\
* pthread_key_delete.html
*/
struct pt_specific *pt;
if (__predict_false(__uselibcstub))
return __libc_thr_keydelete_stub(key);
pthread__assert(key >= 0 && key < pthread_keys_max);
pthread_mutex_lock(&tsd_mutex);
pthread__assert(pthread__tsd_destructors[key] != NULL);
while ((pt = PTQ_FIRST(&pthread__tsd_list[key])) != NULL) {
PTQ_REMOVE(&pthread__tsd_list[key], pt, pts_next);
pt->pts_value = NULL;
pt->pts_next.ptqe_prev = NULL;
}
pthread__tsd_destructors[key] = NULL;
pthread_mutex_unlock(&tsd_mutex);
return 0;
}
/* Perform thread-exit-time destruction of thread-specific data. */
void
pthread__destroy_tsd(pthread_t self)
{
int i, done, iterations;
void *val;
void (*destructor)(void *);
if (!self->pt_havespecific)
return;
pthread_mutex_unlock(&self->pt_lock);
/* Butenhof, section 5.4.2 (page 167):
*
* ``Also, Pthreads sets the thread-specific data value for a
* key to NULL before calling that key's destructor (passing
* the previous value of the key) when a thread terminates [*].
* ...
* [*] That is, unfortunately, not what the standard
* says. This is one of the problems with formal standards -
* they say what they say, not what they were intended to
* say. Somehow, an error crept in, and the sentence
* specifying that "the implementation clears the
* thread-specific data value before calling the destructor"
* was deleted. Nobody noticed, and the standard was approved
* with the error. So the standard says (by omission) that if
* you want to write a portable application using
* thread-specific data, that will not hang on thread
* termination, you must call pthread_setspecific within your
* destructor function to change the value to NULL. This would
* be silly, and any serious implementation of Pthreads will
* violate the standard in this respect. Of course, the
* standard will be fixed, probably by the 1003.1n amendment
* (assorted corrections to 1003.1c-1995), but that will take
* a while.''
*/
iterations = 4; /* We're not required to try very hard */
do {
done = 1;
for (i = 0; i < pthread_keys_max; i++) {
struct pt_specific *pt = &self->pt_specific[i];
if (pt->pts_next.ptqe_prev == NULL)
continue;
pthread_mutex_lock(&tsd_mutex);
if (pt->pts_next.ptqe_prev != NULL) {
PTQ_REMOVE(&pthread__tsd_list[i], pt, pts_next);
val = pt->pts_value;
pt->pts_value = NULL;
pt->pts_next.ptqe_prev = NULL;
destructor = pthread__tsd_destructors[i];
} else
destructor = NULL;
pthread_mutex_unlock(&tsd_mutex);
if (destructor != NULL) {
done = 0;
(*destructor)(val);
}
}
} while (!done && iterations--);
self->pt_havespecific = 0;
pthread_mutex_lock(&self->pt_lock);
}

View File

@@ -0,0 +1,265 @@
/* $NetBSD: pthread_types.h,v 1.17 2015/08/27 12:30:50 pooka Exp $ */
/*-
* Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nathan J. Williams.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _LIB_PTHREAD_TYPES_H
#define _LIB_PTHREAD_TYPES_H
/*
* We use the "pthread_spin_t" name internally; "pthread_spinlock_t" is the
* POSIX spinlock object.
*
* C++ expects to be using PTHREAD_FOO_INITIALIZER as a member initializer.
* This does not work for volatile types. Since C++ does not touch the guts
* of those types, we do not include volatile in the C++ definitions.
*/
typedef __cpu_simple_lock_t pthread_spin_t;
#ifdef __cplusplus
typedef __cpu_simple_lock_nv_t __pthread_spin_t;
#define __pthread_volatile
#else
typedef pthread_spin_t __pthread_spin_t;
#define __pthread_volatile volatile
#endif
/*
* Copied from PTQ_HEAD in pthread_queue.h
*/
#define _PTQ_HEAD(name, type) \
struct name { \
struct type *ptqh_first;/* first element */ \
struct type **ptqh_last;/* addr of last next element */ \
}
_PTQ_HEAD(pthread_queue_struct_t, __pthread_st);
typedef struct pthread_queue_struct_t pthread_queue_t;
struct __pthread_st;
struct __pthread_attr_st;
struct __pthread_mutex_st;
struct __pthread_mutexattr_st;
struct __pthread_cond_st;
struct __pthread_condattr_st;
struct __pthread_spin_st;
struct __pthread_rwlock_st;
struct __pthread_rwlockattr_st;
struct __pthread_barrier_st;
struct __pthread_barrierattr_st;
typedef struct __pthread_st *pthread_t;
typedef struct __pthread_attr_st pthread_attr_t;
typedef struct __pthread_mutex_st pthread_mutex_t;
typedef struct __pthread_mutexattr_st pthread_mutexattr_t;
typedef struct __pthread_cond_st pthread_cond_t;
typedef struct __pthread_condattr_st pthread_condattr_t;
typedef struct __pthread_once_st pthread_once_t;
typedef struct __pthread_spinlock_st pthread_spinlock_t;
typedef struct __pthread_rwlock_st pthread_rwlock_t;
typedef struct __pthread_rwlockattr_st pthread_rwlockattr_t;
typedef struct __pthread_barrier_st pthread_barrier_t;
typedef struct __pthread_barrierattr_st pthread_barrierattr_t;
typedef int pthread_key_t;
struct __pthread_attr_st {
unsigned int pta_magic;
int pta_flags;
void *pta_private;
};
/*
* ptm_owner is the actual lock field which is locked via CAS operation.
* This structure's layout is designed to compatible with the previous
* version used in SA pthreads.
*/
#ifdef __CPU_SIMPLE_LOCK_PAD
/*
* If __SIMPLE_UNLOCKED != 0 and we have to pad, we have to worry about
* endianness. Currently that isn't an issue but put in a check in case
* something changes in the future.
*/
#if __SIMPLELOCK_UNLOCKED != 0
#error __CPU_SIMPLE_LOCK_PAD incompatible with __SIMPLELOCK_UNLOCKED == 0
#endif
#endif
struct __pthread_mutex_st {
unsigned int ptm_magic;
__pthread_spin_t ptm_errorcheck;
#ifdef __CPU_SIMPLE_LOCK_PAD
uint8_t ptm_pad1[3];
#endif
__pthread_spin_t ptm_interlock; /* unused - backwards compat */
#ifdef __CPU_SIMPLE_LOCK_PAD
uint8_t ptm_pad2[3];
#endif
__pthread_volatile pthread_t ptm_owner;
pthread_t * __pthread_volatile ptm_waiters;
unsigned int ptm_recursed;
void *ptm_spare2; /* unused - backwards compat */
};
#define _PT_MUTEX_MAGIC 0x33330003
#define _PT_MUTEX_DEAD 0xDEAD0003
#ifdef __CPU_SIMPLE_LOCK_PAD
#define _PTHREAD_MUTEX_INITIALIZER { _PT_MUTEX_MAGIC, \
__SIMPLELOCK_UNLOCKED, { 0, 0, 0 }, \
__SIMPLELOCK_UNLOCKED, { 0, 0, 0 }, \
NULL, NULL, 0, NULL \
}
#else
#define _PTHREAD_MUTEX_INITIALIZER { _PT_MUTEX_MAGIC, \
__SIMPLELOCK_UNLOCKED, \
__SIMPLELOCK_UNLOCKED, \
NULL, NULL, 0, NULL \
}
#endif /* __CPU_SIMPLE_LOCK_PAD */
struct __pthread_mutexattr_st {
unsigned int ptma_magic;
void *ptma_private;
};
#define _PT_MUTEXATTR_MAGIC 0x44440004
#define _PT_MUTEXATTR_DEAD 0xDEAD0004
struct __pthread_cond_st {
unsigned int ptc_magic;
/* Protects the queue of waiters */
__pthread_spin_t ptc_lock;
pthread_queue_t ptc_waiters;
pthread_mutex_t *ptc_mutex; /* Current mutex */
void *ptc_private;
};
#define _PT_COND_MAGIC 0x55550005
#define _PT_COND_DEAD 0xDEAD0005
#define _PTHREAD_COND_INITIALIZER { _PT_COND_MAGIC, \
__SIMPLELOCK_UNLOCKED, \
{NULL, NULL}, \
NULL, \
NULL \
}
struct __pthread_condattr_st {
unsigned int ptca_magic;
void *ptca_private;
};
#define _PT_CONDATTR_MAGIC 0x66660006
#define _PT_CONDATTR_DEAD 0xDEAD0006
struct __pthread_once_st {
pthread_mutex_t pto_mutex;
int pto_done;
};
#define _PTHREAD_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, 0 }
struct __pthread_spinlock_st {
unsigned int pts_magic;
__pthread_spin_t pts_spin;
int pts_flags;
};
#define _PT_SPINLOCK_MAGIC 0x77770007
#define _PT_SPINLOCK_DEAD 0xDEAD0007
#define _PT_SPINLOCK_PSHARED 0x00000001
/* PTHREAD_SPINLOCK_INITIALIZER is an extension not specified by POSIX. */
#define _PTHREAD_SPINLOCK_INITIALIZER { _PT_SPINLOCK_MAGIC, \
__SIMPLELOCK_UNLOCKED, \
0 \
}
struct __pthread_rwlock_st {
unsigned int ptr_magic;
/* Protects data below */
__pthread_spin_t ptr_interlock;
pthread_queue_t ptr_rblocked;
pthread_queue_t ptr_wblocked;
unsigned int ptr_nreaders;
__pthread_volatile pthread_t ptr_owner;
void *ptr_private;
};
#define _PT_RWLOCK_MAGIC 0x99990009
#define _PT_RWLOCK_DEAD 0xDEAD0009
#define _PTHREAD_RWLOCK_INITIALIZER { _PT_RWLOCK_MAGIC, \
__SIMPLELOCK_UNLOCKED, \
{NULL, NULL}, \
{NULL, NULL}, \
0, \
NULL, \
NULL, \
}
struct __pthread_rwlockattr_st {
unsigned int ptra_magic;
void *ptra_private;
};
#define _PT_RWLOCKATTR_MAGIC 0x99990909
#define _PT_RWLOCKATTR_DEAD 0xDEAD0909
struct __pthread_barrier_st {
unsigned int ptb_magic;
/* Protects data below */
pthread_spin_t ptb_lock;
pthread_queue_t ptb_waiters;
unsigned int ptb_initcount;
unsigned int ptb_curcount;
unsigned int ptb_generation;
void *ptb_private;
};
#define _PT_BARRIER_MAGIC 0x88880008
#define _PT_BARRIER_DEAD 0xDEAD0008
struct __pthread_barrierattr_st {
unsigned int ptba_magic;
void *ptba_private;
};
#define _PT_BARRIERATTR_MAGIC 0x88880808
#define _PT_BARRIERATTR_DEAD 0xDEAD0808
#endif /* _LIB_PTHREAD_TYPES_H */

136
lib/libpthread/res_state.c Normal file
View File

@@ -0,0 +1,136 @@
/* $NetBSD: res_state.c,v 1.6 2008/04/28 20:23:02 martin Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: res_state.c,v 1.6 2008/04/28 20:23:02 martin Exp $");
#endif
#include <sys/types.h>
#include <sys/queue.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <stdlib.h>
#include <unistd.h>
#include <resolv.h>
#include <netdb.h>
#include "pthread.h"
#include "pthread_int.h"
static SLIST_HEAD(, _res_st) res_list = LIST_HEAD_INITIALIZER(&res_list);
struct _res_st {
/* __res_put_state() assumes st_res is the first member. */
struct __res_state st_res;
SLIST_ENTRY(_res_st) st_list;
};
static pthread_mutex_t res_mtx = PTHREAD_MUTEX_INITIALIZER;
res_state __res_state(void);
res_state __res_get_state(void);
void __res_put_state(res_state);
#ifdef RES_STATE_DEBUG
static void
res_state_debug(const char *msg, void *p)
{
char buf[512];
pthread_t self = pthread__self();
int len = snprintf(buf, sizeof(buf), "%p: %s %p\n", self, msg, p);
(void)write(STDOUT_FILENO, buf, (size_t)len);
}
#else
#define res_state_debug(a, b)
#endif
res_state
__res_get_state(void)
{
res_state res;
struct _res_st *st;
pthread_mutex_lock(&res_mtx);
st = SLIST_FIRST(&res_list);
if (st != NULL) {
SLIST_REMOVE_HEAD(&res_list, st_list);
pthread_mutex_unlock(&res_mtx);
res = &st->st_res;
res_state_debug("checkout from list", st);
} else {
pthread_mutex_unlock(&res_mtx);
st = malloc(sizeof(*st));
if (st == NULL) {
h_errno = NETDB_INTERNAL;
return NULL;
}
res = &st->st_res;
res->options = 0;
res_state_debug("alloc new", res);
}
if ((res->options & RES_INIT) == 0) {
if (res_ninit(res) == -1) {
h_errno = NETDB_INTERNAL;
free(st);
return NULL;
}
}
return res;
}
void
/*ARGSUSED*/
__res_put_state(res_state res)
{
struct _res_st *st = (struct _res_st *)(void *)res;
res_state_debug("free", res);
pthread_mutex_lock(&res_mtx);
SLIST_INSERT_HEAD(&res_list, st, st_list);
pthread_mutex_unlock(&res_mtx);
}
/*
* This is aliased via a macro to _res; don't allow multi-threaded programs
* to use it.
*/
res_state
__res_state(void)
{
static const char res[] = "_res is not supported for multi-threaded"
" programs.\n";
(void)write(STDERR_FILENO, res, sizeof(res) - 1);
abort();
return NULL;
}

316
lib/libpthread/sem.c Normal file
View File

@@ -0,0 +1,316 @@
/* $NetBSD: sem.c,v 1.24 2012/03/10 18:01:10 joerg Exp $ */
/*-
* Copyright (c) 2003, 2006, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as
* the first lines of this file unmodified other than the possible
* addition of one or more copyright notices.
* 2. Redistributions in binary form must reproduce the above copyright
* notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: sem.c,v 1.24 2012/03/10 18:01:10 joerg Exp $");
#include <sys/types.h>
#include <sys/ksem.h>
#include <sys/queue.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdarg.h>
#include "pthread.h"
struct _sem_st {
unsigned int ksem_magic;
#define KSEM_MAGIC 0x90af0421U
LIST_ENTRY(_sem_st) ksem_list;
intptr_t ksem_semid; /* 0 -> user (non-shared) */
sem_t *ksem_identity;
};
static int sem_alloc(unsigned int value, intptr_t semid, sem_t *semp);
static void sem_free(sem_t sem);
static LIST_HEAD(, _sem_st) named_sems = LIST_HEAD_INITIALIZER(&named_sems);
static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER;
static void
sem_free(sem_t sem)
{
sem->ksem_magic = 0;
free(sem);
}
static int
sem_alloc(unsigned int value, intptr_t semid, sem_t *semp)
{
sem_t sem;
if (value > SEM_VALUE_MAX)
return (EINVAL);
if ((sem = malloc(sizeof(struct _sem_st))) == NULL)
return (ENOSPC);
sem->ksem_magic = KSEM_MAGIC;
sem->ksem_semid = semid;
*semp = sem;
return (0);
}
/* ARGSUSED */
int
sem_init(sem_t *sem, int pshared, unsigned int value)
{
intptr_t semid;
int error;
if (_ksem_init(value, &semid) == -1)
return (-1);
if ((error = sem_alloc(value, semid, sem)) != 0) {
_ksem_destroy(semid);
errno = error;
return (-1);
}
return (0);
}
int
sem_destroy(sem_t *sem)
{
int error, save_errno;
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
errno = EINVAL;
return (-1);
}
#endif
error = _ksem_destroy((*sem)->ksem_semid);
save_errno = errno;
sem_free(*sem);
errno = save_errno;
return error;
}
sem_t *
sem_open(const char *name, int oflag, ...)
{
sem_t *sem, s;
intptr_t semid;
mode_t mode;
unsigned int value;
int error;
va_list ap;
mode = 0;
value = 0;
if (oflag & O_CREAT) {
va_start(ap, oflag);
mode = va_arg(ap, int);
value = va_arg(ap, unsigned int);
va_end(ap);
}
/*
* We can be lazy and let the kernel handle the oflag,
* we'll just merge duplicate IDs into our list.
*/
if (_ksem_open(name, oflag, mode, value, &semid) == -1)
return (SEM_FAILED);
/*
* Search for a duplicate ID, we must return the same sem_t *
* if we locate one.
*/
pthread_mutex_lock(&named_sems_mtx);
LIST_FOREACH(s, &named_sems, ksem_list) {
if (s->ksem_semid == semid) {
pthread_mutex_unlock(&named_sems_mtx);
return (s->ksem_identity);
}
}
if ((sem = malloc(sizeof(*sem))) == NULL) {
error = ENOSPC;
goto bad;
}
if ((error = sem_alloc(value, semid, sem)) != 0)
goto bad;
LIST_INSERT_HEAD(&named_sems, *sem, ksem_list);
pthread_mutex_unlock(&named_sems_mtx);
(*sem)->ksem_identity = sem;
return (sem);
bad:
pthread_mutex_unlock(&named_sems_mtx);
_ksem_close(semid);
if (sem != NULL) {
if (*sem != NULL)
sem_free(*sem);
free(sem);
}
errno = error;
return (SEM_FAILED);
}
int
sem_close(sem_t *sem)
{
int error, save_errno;
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
errno = EINVAL;
return (-1);
}
#endif
pthread_mutex_lock(&named_sems_mtx);
error = _ksem_close((*sem)->ksem_semid);
LIST_REMOVE((*sem), ksem_list);
save_errno = errno;
pthread_mutex_unlock(&named_sems_mtx);
sem_free(*sem);
free(sem);
errno = save_errno;
return error;
}
int
sem_unlink(const char *name)
{
return (_ksem_unlink(name));
}
int
sem_wait(sem_t *sem)
{
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
errno = EINVAL;
return (-1);
}
#endif
return (_ksem_wait((*sem)->ksem_semid));
}
int
sem_timedwait(sem_t *sem, const struct timespec * __restrict abstime)
{
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
errno = EINVAL;
return (-1);
}
#endif
return (_ksem_timedwait((*sem)->ksem_semid, abstime));
}
int
sem_trywait(sem_t *sem)
{
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
errno = EINVAL;
return (-1);
}
#endif
return (_ksem_trywait((*sem)->ksem_semid));
}
int
sem_post(sem_t *sem)
{
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
errno = EINVAL;
return (-1);
}
#endif
return (_ksem_post((*sem)->ksem_semid));
}
int
sem_getvalue(sem_t * __restrict sem, int * __restrict sval)
{
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
errno = EINVAL;
return (-1);
}
#endif
return (_ksem_getvalue((*sem)->ksem_semid, sval));
}

View File

@@ -0,0 +1,19 @@
# $NetBSD: shlib_version,v 1.16 2013/04/03 15:45:21 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# Things to do when bumping major version:
#
# - pthread_foo_t:
#
# clean out unused and abused members.
#
# add spare members.
#
# add members to deal with inter-process synch and priority inheritance.
#
# make objects same size and layout on 32/64 bit, so kernel can
# inspect them for priority inheritance / inter-process synch,
# without compat_netbsd32 shims??
#
major=1
minor=2