pthread yet again
This commit is contained in:
245
lib/libpthread/Makefile
Normal file
245
lib/libpthread/Makefile
Normal 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
9
lib/libpthread/README
Normal 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
12
lib/libpthread/TODO
Normal 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
140
lib/libpthread/affinity.3
Normal 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
|
||||
57
lib/libpthread/arch/aarch64/pthread_md.h
Normal file
57
lib/libpthread/arch/aarch64/pthread_md.h
Normal 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 */
|
||||
57
lib/libpthread/arch/alpha/pthread_md.S
Normal file
57
lib/libpthread/arch/alpha/pthread_md.S
Normal 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)
|
||||
57
lib/libpthread/arch/alpha/pthread_md.h
Normal file
57
lib/libpthread/arch/alpha/pthread_md.h
Normal 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 */
|
||||
80
lib/libpthread/arch/arm/pthread_md.h
Normal file
80
lib/libpthread/arch/arm/pthread_md.h
Normal 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 */
|
||||
67
lib/libpthread/arch/hppa/pthread_md.S
Normal file
67
lib/libpthread/arch/hppa/pthread_md.S
Normal 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)
|
||||
64
lib/libpthread/arch/hppa/pthread_md.h
Normal file
64
lib/libpthread/arch/hppa/pthread_md.h
Normal 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 */
|
||||
94
lib/libpthread/arch/i386/pthread_md.h
Normal file
94
lib/libpthread/arch/i386/pthread_md.h
Normal 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 */
|
||||
45
lib/libpthread/arch/ia64/pthread_md.h
Normal file
45
lib/libpthread/arch/ia64/pthread_md.h
Normal 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 */
|
||||
49
lib/libpthread/arch/m68k/pthread_md.h
Normal file
49
lib/libpthread/arch/m68k/pthread_md.h
Normal 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 */
|
||||
47
lib/libpthread/arch/mips/pthread_md.h
Normal file
47
lib/libpthread/arch/mips/pthread_md.h
Normal 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 */
|
||||
47
lib/libpthread/arch/or1k/pthread_md.h
Normal file
47
lib/libpthread/arch/or1k/pthread_md.h
Normal 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 */
|
||||
61
lib/libpthread/arch/powerpc/pthread_md.h
Normal file
61
lib/libpthread/arch/powerpc/pthread_md.h
Normal 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 */
|
||||
47
lib/libpthread/arch/riscv/pthread_md.h
Normal file
47
lib/libpthread/arch/riscv/pthread_md.h
Normal 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 */
|
||||
62
lib/libpthread/arch/sh3/pthread_md.h
Normal file
62
lib/libpthread/arch/sh3/pthread_md.h
Normal 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 */
|
||||
50
lib/libpthread/arch/sparc/pthread_md.h
Normal file
50
lib/libpthread/arch/sparc/pthread_md.h
Normal 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 */
|
||||
47
lib/libpthread/arch/sparc64/pthread_md.h
Normal file
47
lib/libpthread/arch/sparc64/pthread_md.h
Normal 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 */
|
||||
58
lib/libpthread/arch/vax/pthread_md.h
Normal file
58
lib/libpthread/arch/vax/pthread_md.h
Normal 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 */
|
||||
97
lib/libpthread/arch/x86_64/pthread_md.h
Normal file
97
lib/libpthread/arch/x86_64/pthread_md.h
Normal 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
178
lib/libpthread/pthread.3
Normal 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
1396
lib/libpthread/pthread.c
Normal file
File diff suppressed because it is too large
Load Diff
384
lib/libpthread/pthread.h
Normal file
384
lib/libpthread/pthread.h
Normal 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 */
|
||||
155
lib/libpthread/pthread_attr.3
Normal file
155
lib/libpthread/pthread_attr.3
Normal 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 .
|
||||
464
lib/libpthread/pthread_attr.c
Normal file
464
lib/libpthread/pthread_attr.c
Normal 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;
|
||||
}
|
||||
121
lib/libpthread/pthread_attr_get_np.3
Normal file
121
lib/libpthread/pthread_attr_get_np.3
Normal 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
|
||||
119
lib/libpthread/pthread_attr_getdetachstate.3
Normal file
119
lib/libpthread/pthread_attr_getdetachstate.3
Normal 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 .
|
||||
124
lib/libpthread/pthread_attr_getguardsize.3
Normal file
124
lib/libpthread/pthread_attr_getguardsize.3
Normal 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 .
|
||||
112
lib/libpthread/pthread_attr_getinheritsched.3
Normal file
112
lib/libpthread/pthread_attr_getinheritsched.3
Normal 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 .
|
||||
109
lib/libpthread/pthread_attr_getname_np.3
Normal file
109
lib/libpthread/pthread_attr_getname_np.3
Normal 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
|
||||
124
lib/libpthread/pthread_attr_getschedparam.3
Normal file
124
lib/libpthread/pthread_attr_getschedparam.3
Normal 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 .
|
||||
99
lib/libpthread/pthread_attr_getscope.3
Normal file
99
lib/libpthread/pthread_attr_getscope.3
Normal 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 .
|
||||
175
lib/libpthread/pthread_attr_getstack.3
Normal file
175
lib/libpthread/pthread_attr_getstack.3
Normal 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.
|
||||
66
lib/libpthread/pthread_attr_setcreatesuspend_np.3
Normal file
66
lib/libpthread/pthread_attr_setcreatesuspend_np.3
Normal 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
|
||||
162
lib/libpthread/pthread_barrier.3
Normal file
162
lib/libpthread/pthread_barrier.3
Normal 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 .
|
||||
137
lib/libpthread/pthread_barrier.c
Normal file
137
lib/libpthread/pthread_barrier.c
Normal 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;
|
||||
}
|
||||
77
lib/libpthread/pthread_barrierattr.3
Normal file
77
lib/libpthread/pthread_barrierattr.3
Normal 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 .
|
||||
134
lib/libpthread/pthread_cancel.3
Normal file
134
lib/libpthread/pthread_cancel.3
Normal 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 .
|
||||
641
lib/libpthread/pthread_cancelstub.c
Normal file
641
lib/libpthread/pthread_cancelstub.c
Normal 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 */
|
||||
118
lib/libpthread/pthread_cleanup_push.3
Normal file
118
lib/libpthread/pthread_cleanup_push.3
Normal 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 .
|
||||
208
lib/libpthread/pthread_compat.c
Normal file
208
lib/libpthread/pthread_compat.c
Normal 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);
|
||||
}
|
||||
275
lib/libpthread/pthread_cond.3
Normal file
275
lib/libpthread/pthread_cond.3
Normal 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 .
|
||||
418
lib/libpthread/pthread_cond.c
Normal file
418
lib/libpthread/pthread_cond.c
Normal 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;
|
||||
}
|
||||
117
lib/libpthread/pthread_condattr.3
Normal file
117
lib/libpthread/pthread_condattr.3
Normal 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.
|
||||
157
lib/libpthread/pthread_create.3
Normal file
157
lib/libpthread/pthread_create.3
Normal 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 .
|
||||
66
lib/libpthread/pthread_curcpu_np.3
Normal file
66
lib/libpthread/pthread_curcpu_np.3
Normal 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
|
||||
108
lib/libpthread/pthread_detach.3
Normal file
108
lib/libpthread/pthread_detach.3
Normal 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 .
|
||||
92
lib/libpthread/pthread_equal.3
Normal file
92
lib/libpthread/pthread_equal.3
Normal 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 .
|
||||
129
lib/libpthread/pthread_exit.3
Normal file
129
lib/libpthread/pthread_exit.3
Normal 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 .
|
||||
107
lib/libpthread/pthread_getname_np.3
Normal file
107
lib/libpthread/pthread_getname_np.3
Normal 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
|
||||
123
lib/libpthread/pthread_getspecific.3
Normal file
123
lib/libpthread/pthread_getspecific.3
Normal 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 .
|
||||
333
lib/libpthread/pthread_int.h
Normal file
333
lib/libpthread/pthread_int.h
Normal 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 */
|
||||
134
lib/libpthread/pthread_join.3
Normal file
134
lib/libpthread/pthread_join.3
Normal 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 .
|
||||
194
lib/libpthread/pthread_key_create.3
Normal file
194
lib/libpthread/pthread_key_create.3
Normal 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.
|
||||
102
lib/libpthread/pthread_kill.3
Normal file
102
lib/libpthread/pthread_kill.3
Normal 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 .
|
||||
198
lib/libpthread/pthread_lock.c
Normal file
198
lib/libpthread/pthread_lock.c
Normal 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);
|
||||
}
|
||||
46
lib/libpthread/pthread_makelwp.h
Normal file
46
lib/libpthread/pthread_makelwp.h
Normal 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_ */
|
||||
65
lib/libpthread/pthread_makelwp_netbsd.c
Normal file
65
lib/libpthread/pthread_makelwp_netbsd.c
Normal 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);
|
||||
}
|
||||
170
lib/libpthread/pthread_misc.c
Normal file
170
lib/libpthread/pthread_misc.c
Normal 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;
|
||||
}
|
||||
217
lib/libpthread/pthread_mutex.3
Normal file
217
lib/libpthread/pthread_mutex.3
Normal 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 .
|
||||
659
lib/libpthread/pthread_mutex.c
Normal file
659
lib/libpthread/pthread_mutex.c
Normal 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);
|
||||
}
|
||||
246
lib/libpthread/pthread_mutexattr.3
Normal file
246
lib/libpthread/pthread_mutexattr.3
Normal 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 .
|
||||
128
lib/libpthread/pthread_once.3
Normal file
128
lib/libpthread/pthread_once.3
Normal 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 .
|
||||
72
lib/libpthread/pthread_once.c
Normal file
72
lib/libpthread/pthread_once.c
Normal 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)
|
||||
137
lib/libpthread/pthread_queue.h
Normal file
137
lib/libpthread/pthread_queue.h
Normal 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 */
|
||||
346
lib/libpthread/pthread_rwlock.3
Normal file
346
lib/libpthread/pthread_rwlock.3
Normal 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.
|
||||
664
lib/libpthread/pthread_rwlock.c
Normal file
664
lib/libpthread/pthread_rwlock.c
Normal 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;
|
||||
}
|
||||
105
lib/libpthread/pthread_rwlockattr.3
Normal file
105
lib/libpthread/pthread_rwlockattr.3
Normal 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 .
|
||||
120
lib/libpthread/pthread_schedparam.3
Normal file
120
lib/libpthread/pthread_schedparam.3
Normal 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 .
|
||||
86
lib/libpthread/pthread_self.3
Normal file
86
lib/libpthread/pthread_self.3
Normal 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 .
|
||||
122
lib/libpthread/pthread_sigmask.3
Normal file
122
lib/libpthread/pthread_sigmask.3
Normal 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 .
|
||||
115
lib/libpthread/pthread_specific.c
Normal file
115
lib/libpthread/pthread_specific.c
Normal 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);
|
||||
}
|
||||
208
lib/libpthread/pthread_spin.3
Normal file
208
lib/libpthread/pthread_spin.3
Normal 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.
|
||||
139
lib/libpthread/pthread_spin.c
Normal file
139
lib/libpthread/pthread_spin.c
Normal 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;
|
||||
}
|
||||
120
lib/libpthread/pthread_suspend_np.3
Normal file
120
lib/libpthread/pthread_suspend_np.3
Normal 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
|
||||
271
lib/libpthread/pthread_testcancel.3
Normal file
271
lib/libpthread/pthread_testcancel.3
Normal 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 .
|
||||
363
lib/libpthread/pthread_tsd.c
Normal file
363
lib/libpthread/pthread_tsd.c
Normal 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);
|
||||
}
|
||||
265
lib/libpthread/pthread_types.h
Normal file
265
lib/libpthread/pthread_types.h
Normal 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
136
lib/libpthread/res_state.c
Normal 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
316
lib/libpthread/sem.c
Normal 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));
|
||||
}
|
||||
19
lib/libpthread/shlib_version
Normal file
19
lib/libpthread/shlib_version
Normal 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
|
||||
Reference in New Issue
Block a user