Remove the libkse directory. It was unhooked from the build and kernel
support removed in 2008 (prior to 8.0). Approved by: deischen, imp MFC after: 3 days
This commit is contained in:
parent
21fced0602
commit
4739008eab
@ -1,48 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# All library objects contain FreeBSD revision strings by default; they may be
|
||||
# excluded as a space-saving measure. To produce a library that does
|
||||
# not contain these strings, add -DSTRIP_FBSDID (see <sys/cdefs.h>) to CFLAGS
|
||||
# below. Note, there are no IDs for syscall stubs whose sources are generated.
|
||||
# To included legacy CSRG sccsid strings, add -DLIBC_SCCS and -DSYSLIBC_SCCS
|
||||
# (for system call stubs) to CFLAGS below. -DSYSLIBC_SCCS affects just the
|
||||
# system call stubs.
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SHLIB=kse
|
||||
SHLIB_MAJOR= 4
|
||||
CFLAGS+=-DPTHREAD_KERNEL
|
||||
CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \
|
||||
-I${.CURDIR}/../../include
|
||||
CFLAGS+=-I${.CURDIR}/arch/${MACHINE_CPUARCH}/include
|
||||
CFLAGS+=-I${.CURDIR}/sys
|
||||
CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf
|
||||
CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf/${MACHINE_CPUARCH}
|
||||
CFLAGS+=-fno-builtin
|
||||
|
||||
# Uncomment this if you want libkse to contain debug information for
|
||||
# thread locking.
|
||||
CFLAGS+=-D_LOCK_DEBUG
|
||||
WARNS?=3
|
||||
|
||||
# Uncomment this if you want to build a 1:1 threading mode library
|
||||
# however it is no longer strictly conformed to POSIX
|
||||
# CFLAGS+=-DSYSTEM_SCOPE_ONLY
|
||||
|
||||
# Enable extra internal consistancy checks.
|
||||
CFLAGS+=-D_PTHREADS_INVARIANTS -Wall
|
||||
|
||||
VERSION_DEF=${.CURDIR}/../libc/Versions.def
|
||||
SYMBOL_MAPS=${.CURDIR}/kse.map
|
||||
|
||||
PRECIOUSLIB=
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_CPUARCH}/${MACHINE_CPUARCH}
|
||||
|
||||
.include "${.CURDIR}/arch/${MACHINE_CPUARCH}/Makefile.inc"
|
||||
.include "${.CURDIR}/support/Makefile.inc"
|
||||
.include "${.CURDIR}/sys/Makefile.inc"
|
||||
.include "${.CURDIR}/thread/Makefile.inc"
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -1,3 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SRCS+= context.S enter_uts.S pthread_md.c
|
@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* The following notes ("cheat sheet") was provided by Peter Wemm.
|
||||
*
|
||||
* scratch:
|
||||
* rax (1st return)
|
||||
* rcx (4th arg)
|
||||
* rdx (3rd arg, 2nd return)
|
||||
* rsi (2nd arg)
|
||||
* rdi (1st arg)
|
||||
* r8 (5th arg)
|
||||
* r9 (6th arg)
|
||||
* r10 (temp, static chain?)
|
||||
* r11 (temp)
|
||||
*
|
||||
* preserved:
|
||||
* rbx (base pointer)
|
||||
* rsp (stack)
|
||||
* rbp (frame)
|
||||
* r12-r15 (general)
|
||||
*
|
||||
* calls:
|
||||
* rdi 1
|
||||
* rsi 2
|
||||
* rdx 3
|
||||
* rcx 4
|
||||
* r8 5
|
||||
* r9 6
|
||||
*
|
||||
* return:
|
||||
* rax 1
|
||||
* rdx 2
|
||||
*
|
||||
* This means:
|
||||
* arg1 goes in %rdi, arg2 in %rsi, etc. return value is %rax (and
|
||||
* secondary return, eg: pipe(2), in %rdx) %rcx,%rsi,%rdi etc are
|
||||
* trashed by making a call to something. %rbx,%rbp,%r12-15 are the
|
||||
* only registers preserved across a call. Note that unlike i386,
|
||||
* %rsi and %rdi are scratch rather than preserved. FPU is
|
||||
* different, args are in SSE registers rather than the x87 stack.
|
||||
*
|
||||
* Aside from the register calling conventions, amd64 can be treated
|
||||
* very much like i386. Things like setjmp/longjmp etc were literal
|
||||
* translations from i386 but with the register names updated, etc.
|
||||
* The main gotcha is that FPU save/restore is in SSE format, which
|
||||
* means a sparse 512 byte FPU context.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Where do we define these?
|
||||
*/
|
||||
#define MC_SIZE 800 /* sizeof mcontext_t */
|
||||
#define MC_LEN_OFFSET (25*8) /* offset to mc_len from mcontext */
|
||||
#define MC_FPFMT_OFFSET (26*8) /* offset to mc_fpformat from mcontext */
|
||||
#define MC_FPFMT_NODEV 0x10000
|
||||
#define MC_OWNEDFP_OFFSET (27*8) /* offset to mc_ownedfp from mcontext */
|
||||
#define MC_OWNEDFP_NONE 0x20000
|
||||
#define MC_OWNEDFP_FPU 0x20001
|
||||
#define MC_OWNEDFP_PCB 0x20002
|
||||
#define MC_FPREGS_OFFSET (28*8) /* offset to FP registers */
|
||||
#define MC_FP_CW_OFFSET (28*8) /* offset to FP control word */
|
||||
|
||||
#define MC_RDI (1 * 8)
|
||||
#define MC_RSI (2 * 8)
|
||||
#define MC_RDX (3 * 8)
|
||||
#define MC_RCX (4 * 8)
|
||||
#define MC_R8 (5 * 8)
|
||||
#define MC_R9 (6 * 8)
|
||||
#define MC_RAX (7 * 8)
|
||||
#define MC_RBX (8 * 8)
|
||||
#define MC_RBP (9 * 8)
|
||||
#define MC_R10 (10 * 8)
|
||||
#define MC_R11 (11 * 8)
|
||||
#define MC_R12 (12 * 8)
|
||||
#define MC_R13 (13 * 8)
|
||||
#define MC_R14 (14 * 8)
|
||||
#define MC_R15 (15 * 8)
|
||||
#define MC_FLAGS (18 * 8)
|
||||
#define MC_RIP (20 * 8)
|
||||
#define MC_CS (21 * 8)
|
||||
#define MC_RFLAGS (22 * 8)
|
||||
#define MC_RSP (23 * 8)
|
||||
#define MC_SS (24 * 8)
|
||||
|
||||
#define REDZONE 128 /* size of the red zone */
|
||||
|
||||
/*
|
||||
* _amd64_ctx_save(mcontext_t *mcp)
|
||||
*
|
||||
* No values are saved to mc_trapno, mc_addr, mc_err and mc_cs.
|
||||
* For the FPU state, only the floating point control word is stored.
|
||||
*/
|
||||
ENTRY(_amd64_save_context)
|
||||
cmpq $0, %rdi /* check for null pointer */
|
||||
jne 1f
|
||||
movq $-1, %rax
|
||||
jmp 2f
|
||||
1: movq %rdi, MC_RDI(%rdi)
|
||||
movq %rsi, MC_RSI(%rdi)
|
||||
movq %rdx, MC_RDX(%rdi)
|
||||
movq %rcx, MC_RCX(%rdi)
|
||||
movq %r8, MC_R8(%rdi)
|
||||
movq %r9, MC_R9(%rdi)
|
||||
movq $1, MC_RAX(%rdi) /* return 1 when restored */
|
||||
movq %rbx, MC_RBX(%rdi)
|
||||
movq %rbp, MC_RBP(%rdi)
|
||||
movq %r10, MC_R10(%rdi)
|
||||
movq %r11, MC_R11(%rdi)
|
||||
movq %r12, MC_R12(%rdi)
|
||||
movq %r13, MC_R13(%rdi)
|
||||
movq %r14, MC_R14(%rdi)
|
||||
movq %r15, MC_R15(%rdi)
|
||||
movq (%rsp), %rax /* get return address */
|
||||
movq %rax, MC_RIP(%rdi) /* save return address (%rip) */
|
||||
pushfq /* get flags */
|
||||
popq %rax
|
||||
movq %rax, MC_RFLAGS(%rdi) /* save flags */
|
||||
movq %rsp, %rax /* setcontext pushes the return */
|
||||
addq $8, %rax /* address onto the stack; */
|
||||
movq %rax, MC_RSP(%rdi) /* account for this -- ???. */
|
||||
movw %ss, MC_SS(%rdi)
|
||||
fnstcw MC_FP_CW_OFFSET(%rdi) /* save FPU control word */
|
||||
movq $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%rdi) /* no FP */
|
||||
movq $MC_FPFMT_NODEV, MC_FPFMT_OFFSET(%rdi)
|
||||
movq $MC_SIZE, MC_LEN_OFFSET(%rdi)
|
||||
xorq %rax, %rax /* return 0 */
|
||||
2: ret
|
||||
|
||||
/*
|
||||
* _amd64_ctx_restore(mcontext_t *mcp, intptr_t val, intptr_t *loc);
|
||||
*/
|
||||
ENTRY(_amd64_restore_context)
|
||||
cmpq $0, %rdi /* check for null pointer */
|
||||
jne 1f
|
||||
movq $-1, %rax
|
||||
jmp 2f
|
||||
1: cmpq $MC_SIZE, MC_LEN_OFFSET(%rdi) /* is context valid? */
|
||||
je 2f
|
||||
movq $-1, %rax /* bzzzt, invalid context */
|
||||
ret
|
||||
2: movq MC_RCX(%rdi), %rcx
|
||||
movq MC_R8(%rdi), %r8
|
||||
movq MC_R9(%rdi), %r9
|
||||
movq MC_RBX(%rdi), %rbx
|
||||
movq MC_RBP(%rdi), %rbp
|
||||
movq MC_R10(%rdi), %r10
|
||||
movq MC_R11(%rdi), %r11
|
||||
movq MC_R12(%rdi), %r12
|
||||
movq MC_R13(%rdi), %r13
|
||||
movq MC_R14(%rdi), %r14
|
||||
movq MC_R15(%rdi), %r15
|
||||
/*
|
||||
* if (mc_fpowned == MC_OWNEDFP_FPU || mc_fpowned == MC_OWNEDFP_PCB)
|
||||
* restore XMM/SSE FP register format
|
||||
*/
|
||||
cmpq $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%rdi)
|
||||
je 4f
|
||||
cmpq $MC_OWNEDFP_PCB, MC_OWNEDFP_OFFSET(%rdi)
|
||||
je 3f
|
||||
cmpq $MC_OWNEDFP_FPU, MC_OWNEDFP_OFFSET(%rdi)
|
||||
jne 4f
|
||||
3: fxrstor MC_FPREGS_OFFSET(%rdi) /* restore XMM FP regs */
|
||||
jmp 5f
|
||||
4: fninit
|
||||
fldcw MC_FP_CW_OFFSET(%rdi)
|
||||
5: movq MC_RSP(%rdi), %rsp /* switch to context stack */
|
||||
subq $REDZONE, %rsp
|
||||
movq MC_RIP(%rdi), %rax /* return address on stack */
|
||||
pushq %rax
|
||||
movq MC_RDI(%rdi), %rax /* rdi on stack */
|
||||
pushq %rax
|
||||
movq MC_RDX(%rdi), %rax /* rdx on stack */
|
||||
pushq %rax
|
||||
movq MC_RSI(%rdi), %rax /* rsi on stack */
|
||||
pushq %rax
|
||||
movq MC_RFLAGS(%rdi), %rax /* flags on stack*/
|
||||
pushq %rax
|
||||
movq MC_RAX(%rdi), %rax /* restore rax */
|
||||
/* At this point we're done with the context. */
|
||||
cmpq $0, %rdx /* set *loc to val */
|
||||
je 6f
|
||||
movq %rsi, (%rdx)
|
||||
6: popfq /* restore flags */
|
||||
popq %rsi /* restore rsi, rdx, and rdi */
|
||||
popq %rdx
|
||||
popq %rdi
|
||||
ret $REDZONE
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
/*
|
||||
* _amd64_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
* size_t stacksz);
|
||||
*/
|
||||
ENTRY(_amd64_enter_uts)
|
||||
addq %rcx, %rdx /* get stack base */
|
||||
andq $~0xf, %rdx /* align to 16 bytes */
|
||||
movq %rdx, %rsp /* switch to UTS stack */
|
||||
movq %rdx, %rbp /* set frame */
|
||||
callq *%rsi
|
||||
ret
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *oldtls;
|
||||
|
||||
if (initial) {
|
||||
__asm __volatile("movq %%fs:0, %0" : "=r" (oldtls));
|
||||
} else {
|
||||
oldtls = NULL;
|
||||
}
|
||||
|
||||
tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
|
||||
if (tcb) {
|
||||
tcb->tcb_thread = thread;
|
||||
bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx));
|
||||
}
|
||||
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 16);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_self = kcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap64(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap64(volatile intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
__asm __volatile(
|
||||
"xchgq %2, %1; movq %2, %0"
|
||||
: "=m" (*res) : "m" (*dst), "r" (val) : "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
atomic_swap_int(volatile int *dst, int val, int *res)
|
||||
{
|
||||
__asm __volatile(
|
||||
"xchgl %2, %1; movl %2, %0"
|
||||
: "=m" (*res) : "m" (*dst), "r" (val) : "memory");
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap64((volatile intptr_t *)(d), (intptr_t)(v), (intptr_t *)(r))
|
||||
|
||||
#endif
|
@ -1,268 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 David Xu <davidxu@freebsd.org>
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 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$
|
||||
*/
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kse.h>
|
||||
#include <machine/sysarch.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
#define DTV_OFFSET offsetof(struct tcb, tcb_dtv)
|
||||
|
||||
#define THR_GETCONTEXT(ucp) \
|
||||
(void)_amd64_save_context(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) \
|
||||
(void)_amd64_restore_context(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_KSE
|
||||
#undef PER_THREAD
|
||||
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tdv;
|
||||
|
||||
/*
|
||||
* %fs points to a struct kcb.
|
||||
*/
|
||||
struct kcb {
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kcb *kcb_self; /* self reference */
|
||||
struct kse *kcb_kse;
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tcb *tcb_self; /* required by rtld */
|
||||
void *tcb_dtv; /* required by rtld */
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_spare[1]; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Evaluates to the byte offset of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_offset(name) __offsetof(struct kcb, name)
|
||||
|
||||
/*
|
||||
* Evaluates to the type of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_type(name) __typeof(((struct kcb *)0)->name)
|
||||
|
||||
/*
|
||||
* Evaluates to the value of the per-kse variable name.
|
||||
*/
|
||||
#define KCB_GET64(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
u_long __i; \
|
||||
__asm __volatile("movq %%fs:%1, %0" \
|
||||
: "=r" (__i) \
|
||||
: "m" (*(u_long *)(__kcb_offset(name)))); \
|
||||
__result = (__kcb_type(name))__i; \
|
||||
\
|
||||
__result; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Sets the value of the per-kse variable name to value val.
|
||||
*/
|
||||
#define KCB_SET64(name, val) ({ \
|
||||
__kcb_type(name) __val = (val); \
|
||||
\
|
||||
u_long __i; \
|
||||
__i = (u_long)__val; \
|
||||
__asm __volatile("movq %1,%%fs:%0" \
|
||||
: "=m" (*(u_long *)(__kcb_offset(name))) \
|
||||
: "r" (__i)); \
|
||||
})
|
||||
|
||||
static __inline u_long
|
||||
__kcb_readandclear64(volatile u_long *addr)
|
||||
{
|
||||
u_long result;
|
||||
|
||||
__asm __volatile (
|
||||
" xorq %0, %0;"
|
||||
" xchgq %%fs:%1, %0;"
|
||||
"# __kcb_readandclear64"
|
||||
: "=&r" (result)
|
||||
: "m" (*addr));
|
||||
return (result);
|
||||
}
|
||||
|
||||
#define KCB_READANDCLEAR64(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
__result = (__kcb_type(name)) \
|
||||
__kcb_readandclear64((u_long *)__kcb_offset(name)); \
|
||||
__result; \
|
||||
})
|
||||
|
||||
|
||||
#define _kcb_curkcb() KCB_GET64(kcb_self)
|
||||
#define _kcb_curtcb() KCB_GET64(kcb_curtcb)
|
||||
#define _kcb_curkse() ((struct kse *)KCB_GET64(kcb_kmbx.km_udata))
|
||||
#define _kcb_get_tmbx() KCB_GET64(kcb_kmbx.km_curthread)
|
||||
#define _kcb_set_tmbx(value) KCB_SET64(kcb_kmbx.km_curthread, (void *)value)
|
||||
#define _kcb_readandclear_tmbx() KCB_READANDCLEAR64(kcb_kmbx.km_curthread)
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
amd64_set_fsbase(kcb);
|
||||
}
|
||||
|
||||
/* Get the current kcb. */
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_kcb_curkcb());
|
||||
}
|
||||
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
|
||||
crit = _kcb_readandclear_tmbx();
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
_kcb_set_tmbx(crit);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
return (_kcb_get_tmbx() == NULL);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
kcb->kcb_curtcb = tcb;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_kcb_curtcb());
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = _kcb_curtcb();
|
||||
if (tcb != NULL)
|
||||
return (tcb->tcb_thread);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return ((struct kse *)_kcb_curkse());
|
||||
}
|
||||
|
||||
void _amd64_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
size_t stacksz);
|
||||
int _amd64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc);
|
||||
int _amd64_save_context(mcontext_t *mc);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _amd64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext);
|
||||
if (ret == 0) {
|
||||
_amd64_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
else if (ret < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
extern int _libkse_debug;
|
||||
|
||||
if ((kcb == NULL) || (tcb == NULL))
|
||||
return (-1);
|
||||
kcb->kcb_curtcb = tcb;
|
||||
|
||||
if (_libkse_debug == 0) {
|
||||
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
|
||||
if (setmbox != 0)
|
||||
_amd64_restore_context(
|
||||
&tcb->tcb_tmbx.tm_context.uc_mcontext,
|
||||
(intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_amd64_restore_context(
|
||||
&tcb->tcb_tmbx.tm_context.uc_mcontext,
|
||||
0, NULL);
|
||||
/* We should not reach here. */
|
||||
} else {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
CFLAGS+=-DSYSTEM_SCOPE_ONLY
|
||||
|
||||
SRCS+= pthread_md.c context.S
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Olivier Houchard
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* int thr_setcontext(mcontext_t *mcp, intptr_t val, intptr_t *loc)
|
||||
*
|
||||
* Restores the context in mcp.
|
||||
*
|
||||
* Returns 0 if there are no errors; -1 otherwise
|
||||
*/
|
||||
|
||||
.weak _C_LABEL(_thr_setcontext)
|
||||
.set _C_LABEL(_thr_setcontext), _C_LABEL(__thr_setcontext)
|
||||
|
||||
ENTRY(__thr_setcontext)
|
||||
/* Check for NULL pointer. */
|
||||
cmp r0, #0
|
||||
moveq r0, #-1
|
||||
moveq pc, lr
|
||||
cmp r2, #0
|
||||
strne r1, [r2]
|
||||
ldr r1, [r0, #(16 * 4)] /* CPSR */
|
||||
msr cpsr, r1
|
||||
ldmia r0, {r0-r15}
|
||||
mov pc, lr
|
||||
/* XXX: FP bits ? */
|
||||
|
||||
/*
|
||||
* int thr_getcontext(mcontext_t *mcp);
|
||||
*
|
||||
* Returns -1 if there is an error, 0 no errors; 1 upon return
|
||||
* from a setcontext().
|
||||
*/
|
||||
.weak _C_LABEL(_thr_getcontext)
|
||||
.set _C_LABEL(_thr_getcontext), _C_LABEL(__thr_getcontext)
|
||||
|
||||
ENTRY(__thr_getcontext)
|
||||
/* Check for NULL pointer. */
|
||||
cmp r0, #0
|
||||
moveq r0, #-1
|
||||
moveq pc, lr
|
||||
stmia r0, {r1-r14}
|
||||
mov r1, #1
|
||||
str r1, [r0] /* Return 1 from setcontext */
|
||||
str lr, [r0, #(15 * 4)] /* PC */
|
||||
mrs r1, cpsr
|
||||
str r1, [r0, #(16 * 4)] /* CPSR */
|
||||
mov r0, #0 /* Return 0. */
|
||||
mov pc, lr
|
||||
|
||||
ENTRY(_arm_enter_uts)
|
||||
add sp, r2, r3 /* Stack addr + size. */
|
||||
mov pc, r1
|
@ -1,86 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* Copyright (C) 2003 David Xu <davidxu@freebsd.org>
|
||||
* Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include <machine/sysarch.h>
|
||||
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct arm_tp **arm_tp = (struct arm_tp **)ARM_TP_ADDRESS;
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
if ((tcb = malloc(sizeof(struct tcb)))) {
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
|
||||
free(tcb);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include "thr_private.h"
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap32(volatile intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
*res = __swp(val, dst);
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
|
||||
#define atomic_swap_int(d, v, r) \
|
||||
atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
#endif
|
||||
|
@ -1,257 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <jake@freebsd.org>.
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_tdv)
|
||||
|
||||
int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
int _thr_getcontext(mcontext_t *);
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv; /* We don't know what this is yet? */
|
||||
|
||||
|
||||
/*
|
||||
* %r6 points to one of these. We define the static TLS as an array
|
||||
* of long double to enforce 16-byte alignment of the TLS memory.
|
||||
*
|
||||
* XXX - Both static and dynamic allocation of any of these structures
|
||||
* will result in a valid, well-aligned thread pointer???
|
||||
*/
|
||||
struct arm_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct pthread *tcb_thread;
|
||||
struct kcb *tcb_curkcb;
|
||||
uint32_t tcb_isfake;
|
||||
struct kse_thr_mailbox tcb_tmbx; /* needs 32-byte alignment */
|
||||
struct arm_tp tcb_tp;
|
||||
};
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
extern struct arm_tp **arm_tp;
|
||||
#define _tp (*arm_tp)
|
||||
|
||||
#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
static __inline uint32_t
|
||||
__kcb_swp(uint32_t val, void *ptr)
|
||||
{
|
||||
|
||||
__asm __volatile("swp %0, %1, [%2]"
|
||||
: "=r" (val) : "r" (val) , "r" (ptr) : "memory");
|
||||
return (val);
|
||||
}
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
__kcb_swp((uint32_t)&kcb->kcb_faketcb.tcb_tp, &_tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
|
||||
if (_tcb->tcb_isfake)
|
||||
return (NULL);
|
||||
crit = (struct kse_thr_mailbox *)__kcb_swp((uint32_t)NULL,
|
||||
&_tcb->tcb_curkcb->kcb_kmbx.km_curthread);
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
__kcb_swp((uint32_t)crit,
|
||||
&_tcb->tcb_curkcb->kcb_kmbx.km_curthread);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
return (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
__kcb_swp((uint32_t)&tcb->tcb_tp, &_tp);
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
void _arm_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
size_t stacksz);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = _thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext))
|
||||
== 0) {
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
__kcb_swp((int)&kcb->kcb_faketcb.tcb_tp, &_tp);
|
||||
_arm_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
} else if (ret < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
extern int _libkse_debug;
|
||||
mcontext_t *mc;
|
||||
|
||||
if (!tcb || !kcb)
|
||||
return (-1);
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
if (_libkse_debug == 0) {
|
||||
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
|
||||
if (setmbox)
|
||||
_thr_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_thr_setcontext(mc, 0, NULL);
|
||||
} else {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
}
|
||||
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
@ -1,3 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SRCS+= thr_enter_uts.S thr_getcontext.S pthread_md.c
|
@ -1,100 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 David Xu <davidxu@freebsd.org>
|
||||
* Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/sysarch.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *oldtls;
|
||||
|
||||
if (initial) {
|
||||
__asm __volatile("movl %%gs:0, %0" : "=r" (oldtls));
|
||||
} else {
|
||||
oldtls = NULL;
|
||||
}
|
||||
|
||||
tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
|
||||
if (tcb) {
|
||||
tcb->tcb_thread = thread;
|
||||
tcb->tcb_spare = 0;
|
||||
bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx));
|
||||
}
|
||||
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize KSD. This also includes setting up the LDT.
|
||||
*/
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_self = kcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
||||
|
||||
int
|
||||
i386_set_gsbase(void *addr)
|
||||
{
|
||||
|
||||
return (sysarch(I386_SET_GSBASE, &addr));
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>.
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
/*
|
||||
* _i386_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
* long stacksz);
|
||||
* +4 = km, +8 = uts, +12 = stack, +16 = size
|
||||
*/
|
||||
ENTRY(_i386_enter_uts)
|
||||
movl %esp, %edx /* save stack */
|
||||
movl 12(%edx), %eax /* get bottom of stack */
|
||||
addl 16(%edx), %eax /* add length */
|
||||
movl %eax, %esp /* switch to uts stack */
|
||||
pushl 4(%edx) /* push the address of the mailbox */
|
||||
call *8(%edx)
|
||||
ret
|
@ -1,154 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Where do we define these?
|
||||
*/
|
||||
#define MC_LEN_OFFSET 80 /* offset to mc_len from mcontext */
|
||||
#define MC_LEN 640 /* mc_len <machine/ucontext.h> */
|
||||
#define MC_FPFMT_OFFSET 84
|
||||
#define MC_FPFMT_NODEV 0x10000
|
||||
#define MC_FPFMT_387 0x10001
|
||||
#define MC_FPFMT_XMM 0x10002
|
||||
#define MC_OWNEDFP_OFFSET 88
|
||||
#define MC_OWNEDFP_NONE 0x20000
|
||||
#define MC_OWNEDFP_FPU 0x20001
|
||||
#define MC_OWNEDFP_PCB 0x20002
|
||||
#define MC_FPREGS_OFFSET 96 /* offset to FP regs from mcontext */
|
||||
#define MC_FP_CW_OFFSET 96 /* offset to FP control word */
|
||||
|
||||
/*
|
||||
* int thr_setcontext(mcontext_t *mcp, intptr_t val, intptr_t *loc)
|
||||
*
|
||||
* Restores the context in mcp.
|
||||
*
|
||||
* Returns 0 if there are no errors; -1 otherwise
|
||||
*/
|
||||
WEAK_REFERENCE(__thr_setcontext, _thr_setcontext)
|
||||
ENTRY(__thr_setcontext)
|
||||
movl 4(%esp), %edx /* get address of mcontext */
|
||||
cmpl $0, %edx /* check for null pointer */
|
||||
jne 1f
|
||||
movl $-1, %eax
|
||||
jmp 8f
|
||||
1: cmpl $MC_LEN, MC_LEN_OFFSET(%edx) /* is context valid? */
|
||||
je 2f
|
||||
movl $-1, %eax /* bzzzt, invalid context */
|
||||
jmp 8f
|
||||
2: /*movl 4(%edx), %gs*/ /* we don't touch %gs */
|
||||
movw 8(%edx), %fs
|
||||
movw 12(%edx), %es
|
||||
movw 16(%edx), %ds
|
||||
movw 76(%edx), %ss
|
||||
movl 20(%edx), %edi
|
||||
movl 24(%edx), %esi
|
||||
movl 28(%edx), %ebp
|
||||
movl %esp, %ecx /* save current stack in ecx */
|
||||
movl 72(%edx), %esp /* switch to context defined stack */
|
||||
pushl 60(%edx) /* push return address on stack */
|
||||
pushl 44(%edx) /* push ecx on stack */
|
||||
pushl 48(%edx) /* push eax on stack */
|
||||
/*
|
||||
* if (mc_fpowned == MC_OWNEDFP_FPU || mc_fpowned == MC_OWNEDFP_PCB) {
|
||||
* if (mc_fpformat == MC_FPFMT_387)
|
||||
* restore 387 FP register format
|
||||
* else if (mc_fpformat == MC_FPFMT_XMM)
|
||||
* restore XMM/SSE FP register format
|
||||
* }
|
||||
*/
|
||||
cmpl $MC_OWNEDFP_FPU, MC_OWNEDFP_OFFSET(%edx)
|
||||
je 3f
|
||||
cmpl $MC_OWNEDFP_PCB, MC_OWNEDFP_OFFSET(%edx)
|
||||
jne 5f
|
||||
3: cmpl $MC_FPFMT_387, MC_FPFMT_OFFSET(%edx)
|
||||
jne 4f
|
||||
frstor MC_FPREGS_OFFSET(%edx) /* restore 387 FP regs */
|
||||
jmp 6f
|
||||
4: cmpl $MC_FPFMT_XMM, MC_FPFMT_OFFSET(%edx)
|
||||
jne 5f
|
||||
fxrstor MC_FPREGS_OFFSET(%edx) /* restore XMM FP regs */
|
||||
jmp 6f
|
||||
5: fninit
|
||||
fldcw MC_FP_CW_OFFSET(%edx)
|
||||
6: pushl 68(%edx) /* push flags register on stack*/
|
||||
movl 36(%edx), %ebx /* restore ebx and edx */
|
||||
movl 40(%edx), %edx
|
||||
movl 12(%ecx), %eax /* get 3rd arg (loc) */
|
||||
cmpl $0, %eax /* do nothing if loc == null */
|
||||
je 7f
|
||||
movl 8(%ecx), %ecx /* get 2nd arg (val) */
|
||||
movl %ecx, (%eax) /* set loc = val */
|
||||
7: popfl /* restore flags after test */
|
||||
popl %eax /* restore eax and ecx last */
|
||||
popl %ecx
|
||||
8: ret
|
||||
|
||||
/*
|
||||
* int thr_getcontext(mcontext_t *mcp);
|
||||
*
|
||||
* Returns -1 if there is an error, 0 no errors; 1 upon return
|
||||
* from a setcontext().
|
||||
*/
|
||||
WEAK_REFERENCE(__thr_getcontext, _thr_getcontext)
|
||||
ENTRY(__thr_getcontext)
|
||||
pushl %edx /* save edx */
|
||||
movl 8(%esp), %edx /* get address of mcontext */
|
||||
cmpl $0, %edx /* check for null pointer */
|
||||
jne 1f
|
||||
popl %edx /* restore edx and stack */
|
||||
movl $-1, %eax
|
||||
jmp 2f
|
||||
1: /*movw %gs, 4(%edx)*/ /* we don't touch %gs */
|
||||
movw %fs, 8(%edx)
|
||||
movw %es, 12(%edx)
|
||||
movw %ds, 16(%edx)
|
||||
movw %ss, 76(%edx)
|
||||
movl %edi, 20(%edx)
|
||||
movl %esi, 24(%edx)
|
||||
movl %ebp, 28(%edx)
|
||||
movl %ebx, 36(%edx)
|
||||
movl $1, 48(%edx) /* store successful return in eax */
|
||||
popl %eax /* get saved value of edx */
|
||||
movl %eax, 40(%edx) /* save edx */
|
||||
movl %ecx, 44(%edx)
|
||||
movl (%esp), %eax /* get return address */
|
||||
movl %eax, 60(%edx) /* save return address */
|
||||
fnstcw MC_FP_CW_OFFSET(%edx)
|
||||
movl $MC_LEN, MC_LEN_OFFSET(%edx)
|
||||
movl $MC_FPFMT_NODEV, MC_FPFMT_OFFSET(%edx) /* no FP */
|
||||
movl $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%edx) /* no FP */
|
||||
pushfl
|
||||
popl %eax /* get eflags */
|
||||
movl %eax, 68(%edx) /* store eflags */
|
||||
movl %esp, %eax /* setcontext pushes the return */
|
||||
addl $4, %eax /* address onto the top of the */
|
||||
movl %eax, 72(%edx) /* stack; account for this */
|
||||
movl 40(%edx), %edx /* restore edx -- is this needed? */
|
||||
xorl %eax, %eax /* return 0 */
|
||||
2: ret
|
@ -1,51 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap32(volatile intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
__asm __volatile(
|
||||
"xchgl %2, %1; movl %2, %0"
|
||||
: "=m" (*res) : "m" (*dst), "r" (val) : "memory");
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
|
||||
#define atomic_swap_int(d, v, r) \
|
||||
atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
#endif
|
@ -1,264 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2002 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kse.h>
|
||||
#include <machine/sysarch.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
extern int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
extern int _thr_getcontext(mcontext_t *);
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
#define DTV_OFFSET offsetof(struct tcb, tcb_dtv)
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_KSE
|
||||
#undef PER_THREAD
|
||||
|
||||
struct kse;
|
||||
struct pthread;
|
||||
|
||||
/*
|
||||
* %gs points to a struct kcb.
|
||||
*/
|
||||
struct kcb {
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kcb *kcb_self; /* self reference */
|
||||
struct kse *kcb_kse;
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tcb *tcb_self; /* required by rtld */
|
||||
void *tcb_dtv; /* required by rtld */
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_spare; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Evaluates to the byte offset of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_offset(name) __offsetof(struct kcb, name)
|
||||
|
||||
/*
|
||||
* Evaluates to the type of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_type(name) __typeof(((struct kcb *)0)->name)
|
||||
|
||||
/*
|
||||
* Evaluates to the value of the per-kse variable name.
|
||||
*/
|
||||
#define KCB_GET32(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
u_int __i; \
|
||||
__asm __volatile("movl %%gs:%1, %0" \
|
||||
: "=r" (__i) \
|
||||
: "m" (*(u_int *)(__kcb_offset(name)))); \
|
||||
__result = (__kcb_type(name))__i; \
|
||||
\
|
||||
__result; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Sets the value of the per-kse variable name to value val.
|
||||
*/
|
||||
#define KCB_SET32(name, val) ({ \
|
||||
__kcb_type(name) __val = (val); \
|
||||
\
|
||||
u_int __i; \
|
||||
__i = (u_int)__val; \
|
||||
__asm __volatile("movl %1,%%gs:%0" \
|
||||
: "=m" (*(u_int *)(__kcb_offset(name))) \
|
||||
: "r" (__i)); \
|
||||
})
|
||||
|
||||
static __inline u_long
|
||||
__kcb_readandclear32(volatile u_long *addr)
|
||||
{
|
||||
u_long result;
|
||||
|
||||
__asm __volatile (
|
||||
" xorl %0, %0;"
|
||||
" xchgl %%gs:%1, %0;"
|
||||
"# __kcb_readandclear32"
|
||||
: "=&r" (result)
|
||||
: "m" (*addr));
|
||||
return (result);
|
||||
}
|
||||
|
||||
#define KCB_READANDCLEAR32(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
__result = (__kcb_type(name)) \
|
||||
__kcb_readandclear32((u_long *)__kcb_offset(name)); \
|
||||
__result; \
|
||||
})
|
||||
|
||||
|
||||
#define _kcb_curkcb() KCB_GET32(kcb_self)
|
||||
#define _kcb_curtcb() KCB_GET32(kcb_curtcb)
|
||||
#define _kcb_curkse() ((struct kse *)KCB_GET32(kcb_kmbx.km_udata))
|
||||
#define _kcb_get_tmbx() KCB_GET32(kcb_kmbx.km_curthread)
|
||||
#define _kcb_set_tmbx(value) KCB_SET32(kcb_kmbx.km_curthread, (void *)value)
|
||||
#define _kcb_readandclear_tmbx() KCB_READANDCLEAR32(kcb_kmbx.km_curthread)
|
||||
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
i386_set_gsbase(kcb);
|
||||
}
|
||||
|
||||
/* Get the current kcb. */
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_kcb_curkcb());
|
||||
}
|
||||
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
|
||||
crit = _kcb_readandclear_tmbx();
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
_kcb_set_tmbx(crit);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
return (_kcb_get_tmbx() == NULL);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
kcb->kcb_curtcb = tcb;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_kcb_curtcb());
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = _kcb_curtcb();
|
||||
if (tcb != NULL)
|
||||
return (tcb->tcb_thread);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return ((struct kse *)_kcb_curkse());
|
||||
}
|
||||
|
||||
void _i386_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
size_t stacksz);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext);
|
||||
if (ret == 0) {
|
||||
_i386_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
else if (ret < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
extern int _libkse_debug;
|
||||
|
||||
if ((kcb == NULL) || (tcb == NULL))
|
||||
return (-1);
|
||||
kcb->kcb_curtcb = tcb;
|
||||
if (_libkse_debug == 0) {
|
||||
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
|
||||
if (setmbox != 0)
|
||||
_thr_setcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext,
|
||||
(intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_thr_setcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext,
|
||||
0, NULL);
|
||||
} else {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
}
|
||||
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,3 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SRCS+= context.S enter_uts.S pthread_md.c
|
@ -1,351 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define SIZEOF_SPECIAL (18*8)
|
||||
|
||||
/*
|
||||
* int _ia64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc);
|
||||
*/
|
||||
ENTRY(_ia64_restore_context, 3)
|
||||
{ .mmi
|
||||
invala
|
||||
mov ar.rsc=0xc
|
||||
add r32=16,r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
loadrs
|
||||
ld8 r12=[r32] // sp
|
||||
add r31=8,r32
|
||||
;;
|
||||
}
|
||||
{ .mii
|
||||
ld8 r16=[r31],16 // unat (before)
|
||||
add r30=16,r32
|
||||
add r14=SIZEOF_SPECIAL,r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r17=[r30],16 // rp
|
||||
ld8 r18=[r31],16 // pr
|
||||
mov r2=r33
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r19=[r30],16 // pfs
|
||||
ld8 r20=[r31],32 // bspstore
|
||||
mov rp=r17
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r21=[r30],32 // rnat
|
||||
ld8 r22=[r31],16 // rsc
|
||||
mov pr=r18,0x1fffe
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r23=[r30] // fpsr
|
||||
ld8 r24=[r31] // psr -- not used
|
||||
mov r3=r34
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r17=[r14],8 // unat (after)
|
||||
mov ar.bspstore=r20
|
||||
cmp.ne p15,p0=r0,r3
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov ar.rnat=r21
|
||||
mov ar.unat=r17
|
||||
add r15=8,r14
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8.fill r4=[r14],16 // r4
|
||||
ld8.fill r5=[r15],16 // r5
|
||||
mov ar.pfs=r19
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8.fill r6=[r14],16 // r6
|
||||
ld8.fill r7=[r15],16 // r7
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov ar.unat=r16
|
||||
mov ar.rsc=r22
|
||||
nop 0
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r17=[r14],16 // b1
|
||||
ld8 r18=[r15],16 // b2
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r19=[r14],16 // b3
|
||||
ld8 r20=[r15],16 // b4
|
||||
mov b1=r17
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r16=[r14],24 // b5
|
||||
ld8 r17=[r15],32 // lc
|
||||
mov b2=r18
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f2=[r14],32
|
||||
ldf.fill f3=[r15],32
|
||||
mov b3=r19
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f4=[r14],32
|
||||
ldf.fill f5=[r15],32
|
||||
mov b4=r20
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f16=[r14],32
|
||||
ldf.fill f17=[r15],32
|
||||
mov b5=r16
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f18=[r14],32
|
||||
ldf.fill f19=[r15],32
|
||||
mov ar.lc=r17
|
||||
;;
|
||||
}
|
||||
ldf.fill f20=[r14],32
|
||||
ldf.fill f21=[r15],32
|
||||
;;
|
||||
ldf.fill f22=[r14],32
|
||||
ldf.fill f23=[r15],32
|
||||
;;
|
||||
ldf.fill f24=[r14],32
|
||||
ldf.fill f25=[r15],32
|
||||
;;
|
||||
ldf.fill f26=[r14],32
|
||||
ldf.fill f27=[r15],32
|
||||
;;
|
||||
ldf.fill f28=[r14],32
|
||||
ldf.fill f29=[r15],32
|
||||
;;
|
||||
ldf.fill f30=[r14],32+24
|
||||
ldf.fill f31=[r15],24+24
|
||||
;;
|
||||
ld8 r8=[r14],16
|
||||
ld8 r9=[r15],16
|
||||
;;
|
||||
ld8 r10=[r14]
|
||||
ld8 r11=[r15]
|
||||
;;
|
||||
{ .mmb
|
||||
(p15) st8 [r3]=r2
|
||||
mov ar.fpsr=r23
|
||||
br.ret.sptk rp
|
||||
;;
|
||||
}
|
||||
END(_ia64_restore_context)
|
||||
|
||||
/*
|
||||
* int _ia64_save_context(mcontext_t *mc);
|
||||
*/
|
||||
ENTRY(_ia64_save_context, 1)
|
||||
{ .mmi
|
||||
mov r14=ar.rsc
|
||||
mov r15=ar.fpsr
|
||||
add r31=8,r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r0,16
|
||||
st8 [r31]=r0,16
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov ar.rsc=0xc
|
||||
mov r16=ar.unat
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
flushrs
|
||||
st8 [r32]=sp,16 // sp
|
||||
mov r17=rp
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r16,16 // unat (before)
|
||||
st8 [r32]=r17,16 // rp
|
||||
mov r16=pr
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r16,16 // pr
|
||||
mov r17=ar.bsp
|
||||
mov r16=ar.pfs
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r16,16 // pfs
|
||||
st8 [r31]=r17,16 // bspstore
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov r16=ar.rnat
|
||||
mov ar.rsc=r14
|
||||
add r30=SIZEOF_SPECIAL-(6*8),r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r16,16 // rnat
|
||||
st8 [r31]=r0,16 // __spare
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r13,16 // tp -- not used
|
||||
st8 [r31]=r14,16 // rsc
|
||||
mov r16=b1
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r15,10*8 // fpr
|
||||
st8 [r31]=r0,8*8 // psr
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
/* callee_saved */
|
||||
{ .mmi
|
||||
.mem.offset 8,0
|
||||
st8.spill [r31]=r4,16 // r4
|
||||
.mem.offset 16,0
|
||||
st8.spill [r32]=r5,16 // r5
|
||||
mov r17=b2
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
.mem.offset 24,0
|
||||
st8.spill [r31]=r6,16 // r6
|
||||
.mem.offset 32,0
|
||||
st8.spill [r32]=r7,16 // r7
|
||||
mov r18=b3
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r16,16 // b1
|
||||
mov r16=ar.unat
|
||||
mov r19=b4
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r30]=r16 // unat (after)
|
||||
st8 [r32]=r17,16 // b2
|
||||
mov r16=b5
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r18,16 // b3
|
||||
st8 [r32]=r19,16 // b4
|
||||
mov r17=ar.lc
|
||||
;;
|
||||
}
|
||||
st8 [r31]=r16,16 // b5
|
||||
st8 [r32]=r17,16 // lc
|
||||
;;
|
||||
st8 [r31]=r0,24 // __spare
|
||||
stf.spill [r32]=f2,32
|
||||
;;
|
||||
stf.spill [r31]=f3,32
|
||||
stf.spill [r32]=f4,32
|
||||
;;
|
||||
stf.spill [r31]=f5,32
|
||||
stf.spill [r32]=f16,32
|
||||
;;
|
||||
stf.spill [r31]=f17,32
|
||||
stf.spill [r32]=f18,32
|
||||
;;
|
||||
stf.spill [r31]=f19,32
|
||||
stf.spill [r32]=f20,32
|
||||
;;
|
||||
stf.spill [r31]=f21,32
|
||||
stf.spill [r32]=f22,32
|
||||
;;
|
||||
stf.spill [r31]=f23,32
|
||||
stf.spill [r32]=f24,32
|
||||
;;
|
||||
stf.spill [r31]=f25,32
|
||||
stf.spill [r32]=f26,32
|
||||
;;
|
||||
stf.spill [r31]=f27,32
|
||||
stf.spill [r32]=f28,32
|
||||
;;
|
||||
{ .mmi
|
||||
stf.spill [r31]=f29,32
|
||||
stf.spill [r32]=f30,32+24
|
||||
add r14=1,r0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
stf.spill [r31]=f31,24+24
|
||||
st8 [r32]=r14,16 // r8
|
||||
add r8=0,r0
|
||||
;;
|
||||
}
|
||||
st8 [r31]=r0,16 // r9
|
||||
st8 [r32]=r0 // r10
|
||||
;;
|
||||
{ .mmb
|
||||
st8 [r31]=r0 // r11
|
||||
mf
|
||||
br.ret.sptk rp
|
||||
;;
|
||||
}
|
||||
END(_ia64_save_context)
|
||||
|
||||
/*
|
||||
* void _ia64_break_setcontext(mcontext_t *mc);
|
||||
*/
|
||||
ENTRY(_ia64_break_setcontext, 1)
|
||||
{ .mmi
|
||||
mov r8=r32
|
||||
break 0x180000
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
END(_ia64_break_setcontext)
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
* size_t stacksz);
|
||||
*/
|
||||
ENTRY(_ia64_enter_uts, 4)
|
||||
{ .mmi
|
||||
ld8 r14=[in0],8
|
||||
mov ar.rsc=0xc
|
||||
add r15=in2,in3
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
flushrs
|
||||
ld8 r1=[in0]
|
||||
mov b7=r14
|
||||
;;
|
||||
}
|
||||
{ .mii
|
||||
mov ar.bspstore=in2
|
||||
add sp=-16,r15
|
||||
mov rp=r14
|
||||
;;
|
||||
}
|
||||
{ .mib
|
||||
mov ar.rsc=0xf
|
||||
mov in0=in1
|
||||
br.cond.sptk b7
|
||||
;;
|
||||
}
|
||||
1: br.cond.sptk 1b
|
||||
END(_ia64_enter_uts)
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* Copyright (c) 2006 Marcel Moolenaar
|
||||
* 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. Neither the name of the author 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 AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
register char *tp __asm("%r13");
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = _rtld_allocate_tls((initial) ? tp : NULL,
|
||||
sizeof(struct tcb), 16);
|
||||
if (tcb == NULL)
|
||||
return (NULL);
|
||||
tcb->tcb_thread = thread;
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 16);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb == NULL)
|
||||
return (NULL);
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_kse = kse;
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
static inline void
|
||||
atomic_swap_int(volatile int *dst, int val, int *res)
|
||||
{
|
||||
__asm("xchg4 %0=[%2],%1" : "=r"(*res) : "r"(val), "r"(dst));
|
||||
}
|
||||
|
||||
static inline void
|
||||
atomic_swap_long(volatile long *dst, long val, long *res)
|
||||
{
|
||||
__asm("xchg8 %0=[%2],%1" : "=r"(*res) : "r"(val), "r"(dst));
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d,v,r) \
|
||||
atomic_swap_long((volatile long *)d, (long)v, (long *)r)
|
||||
|
||||
#endif /* _ATOMIC_OPS_H_ */
|
@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2006 Marcel Moolenaar
|
||||
* 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_dtv)
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _ia64_save_context(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) PANIC("THR_SETCONTEXT() now in use!\n")
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
|
||||
/*
|
||||
* tp points to one of these. We define the TLS structure as a union
|
||||
* containing a long double to enforce 16-byte alignment. This makes
|
||||
* sure that there will not be any padding in struct tcb after the
|
||||
* TLS structure.
|
||||
*/
|
||||
union ia64_tp {
|
||||
void *tp_dtv;
|
||||
long double _align_;
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
struct pthread *tcb_thread;
|
||||
struct kcb *tcb_curkcb;
|
||||
long tcb_isfake;
|
||||
union ia64_tp tcb_tp;
|
||||
};
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct kse *kcb_kse;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct tcb kcb_faketcb;
|
||||
};
|
||||
|
||||
static __inline struct tcb *
|
||||
ia64_get_tcb(void)
|
||||
{
|
||||
register char *tp __asm("%r13");
|
||||
|
||||
return ((struct tcb *)(tp - offsetof(struct tcb, tcb_tp)));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ia64_set_tcb(struct tcb *tcb)
|
||||
{
|
||||
register char *tp __asm("%r13");
|
||||
|
||||
__asm __volatile("mov %0 = %1;;" : "=r"(tp) : "r"(&tcb->tcb_tp));
|
||||
}
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
ia64_set_tcb(&kcb->kcb_faketcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (ia64_get_tcb()->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
tcb = ia64_get_tcb();
|
||||
if (tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = tcb->tcb_tmbx.tm_flags;
|
||||
tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = ia64_get_tcb();
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (tcb->tcb_isfake == 0)
|
||||
tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
tcb = ia64_get_tcb();
|
||||
if (tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = tcb->tcb_tmbx.tm_flags;
|
||||
tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
ia64_set_tcb(tcb);
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (ia64_get_tcb());
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (ia64_get_tcb()->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (ia64_get_tcb()->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
void _ia64_break_setcontext(mcontext_t *mc);
|
||||
void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
size_t stacksz);
|
||||
int _ia64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc);
|
||||
int _ia64_save_context(mcontext_t *mc);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_ia64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
ia64_set_tcb(&kcb->kcb_faketcb);
|
||||
_ia64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
if (mc->mc_flags & _MC_FLAGS_ASYNC_CONTEXT) {
|
||||
if (setmbox) {
|
||||
mc->mc_flags |= _MC_FLAGS_KSE_SET_MBOX;
|
||||
mc->mc_special.ifa =
|
||||
(intptr_t)&kcb->kcb_kmbx.km_curthread;
|
||||
mc->mc_special.isr = (intptr_t)&tcb->tcb_tmbx;
|
||||
}
|
||||
_ia64_break_setcontext(mc);
|
||||
} else if (mc->mc_flags & _MC_FLAGS_SYSCALL_CONTEXT) {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
} else {
|
||||
if (setmbox)
|
||||
_ia64_restore_context(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_ia64_restore_context(mc, 0, NULL);
|
||||
}
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
@ -1,6 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# XXX temporary
|
||||
CFLAGS+=-DSYSTEM_SCOPE_ONLY
|
||||
|
||||
SRCS+= enter_uts.S context.S pthread_md.c
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004 by Peter Grehan. 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap32(volatile intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = 0; /* should be a better way to quieten cc1... */
|
||||
#ifdef __GNUC__
|
||||
__asm __volatile(
|
||||
"1: lwarx %0, 0, %4\n" /* load with reservation */
|
||||
" stwcx. %3, 0, %4\n" /* attempt to store val */
|
||||
" bne- 1b\n" /* interrupted? retry */
|
||||
" stw %0, %1\n" /* else, *dst -> *res */
|
||||
: "=&r" (tmp), "=m" (*res), "+m" (*dst)
|
||||
: "r" (val), "r" (dst)
|
||||
: "cc", "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
|
||||
#define atomic_swap_int(d, v, r) \
|
||||
atomic_swap32((volatile intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
#endif
|
@ -1,292 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004 by Peter Grehan.
|
||||
* Copyright 2006 Marcel Moolenaar
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
extern void _ppc32_enter_uts(struct kse_mailbox *, kse_func_t, void *, size_t);
|
||||
extern int _ppc32_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
extern int _ppc32_getcontext(mcontext_t *);
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_dtv)
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _ppc32_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _ppc32_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
|
||||
/*
|
||||
* %r2 points to the following.
|
||||
*/
|
||||
struct ppc32_tp {
|
||||
void *tp_dtv; /* dynamic thread vector */
|
||||
uint32_t _reserved_;
|
||||
double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
struct pthread *tcb_thread;
|
||||
struct kcb *tcb_curkcb;
|
||||
long tcb_isfake;
|
||||
long tcb_spare[3];
|
||||
struct ppc32_tp tcb_tp;
|
||||
};
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct kse *kcb_kse;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct tcb kcb_faketcb;
|
||||
};
|
||||
|
||||
/*
|
||||
* From the PowerPC32 TLS spec:
|
||||
*
|
||||
* "r2 is the thread pointer, and points 0x7000 past the end of the
|
||||
* thread control block." Or, 0x7008 past the start of the 8-byte tcb
|
||||
*/
|
||||
#define TP_OFFSET 0x7008
|
||||
|
||||
static __inline char *
|
||||
ppc_get_tp(void)
|
||||
{
|
||||
register char *r2 __asm__("%r2");
|
||||
|
||||
return (r2 - TP_OFFSET);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ppc_set_tp(char *tp)
|
||||
{
|
||||
register char *r2 __asm__("%r2");
|
||||
__asm __volatile("mr %0,%1" : "=r"(r2) : "r"(tp + TP_OFFSET));
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
ppc_get_tcb(void)
|
||||
{
|
||||
return ((struct tcb *)(ppc_get_tp() - offsetof(struct tcb, tcb_tp)));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ppc_set_tcb(struct tcb *tcb)
|
||||
{
|
||||
ppc_set_tp((char*)&tcb->tcb_tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
ppc_set_tcb(&kcb->kcb_faketcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (ppc_get_tcb()->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
struct tcb *tcb;
|
||||
uint32_t flags;
|
||||
|
||||
tcb = ppc_get_tcb();
|
||||
if (tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = tcb->tcb_tmbx.tm_flags;
|
||||
tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = ppc_get_tcb();
|
||||
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (tcb->tcb_isfake == 0)
|
||||
tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
tcb = ppc_get_tcb();
|
||||
if (tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = tcb->tcb_tmbx.tm_flags;
|
||||
tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
ppc_set_tcb(tcb);
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (ppc_get_tcb());
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (ppc_get_tcb()->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (ppc_get_tcb()->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_ppc32_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
ppc_set_tcb(&kcb->kcb_faketcb);
|
||||
_ppc32_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size - 32);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
extern int _libkse_debug;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
|
||||
/*
|
||||
* A full context needs a system call to restore, so use
|
||||
* kse_switchin. Otherwise, the partial context can be
|
||||
* restored with _ppc32_setcontext
|
||||
*/
|
||||
if (mc->mc_vers != _MC_VERSION_KSE && _libkse_debug != 0) {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
} else {
|
||||
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
|
||||
if (setmbox)
|
||||
_ppc32_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_ppc32_setcontext(mc, 0, NULL);
|
||||
}
|
||||
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
/* Used to generate mcontext_t offsets */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/assym.h>
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
ASSYM(_MC_VERSION, _MC_VERSION);
|
||||
ASSYM(_MC_VERSION_KSE, _MC_VERSION_KSE);
|
||||
ASSYM(_MC_FP_VALID, _MC_FP_VALID);
|
||||
|
||||
ASSYM(_MC_VERS, offsetof(mcontext_t, mc_vers));
|
||||
ASSYM(_MC_FLAGS, offsetof(mcontext_t, mc_flags));
|
||||
|
||||
ASSYM(_MC_R0, offsetof(mcontext_t, mc_frame[0]));
|
||||
ASSYM(_MC_R1, offsetof(mcontext_t, mc_frame[1]));
|
||||
ASSYM(_MC_R2, offsetof(mcontext_t, mc_frame[2]));
|
||||
ASSYM(_MC_R3, offsetof(mcontext_t, mc_frame[3]));
|
||||
ASSYM(_MC_R4, offsetof(mcontext_t, mc_frame[4]));
|
||||
ASSYM(_MC_R5, offsetof(mcontext_t, mc_frame[5]));
|
||||
ASSYM(_MC_R6, offsetof(mcontext_t, mc_frame[6]));
|
||||
ASSYM(_MC_R7, offsetof(mcontext_t, mc_frame[7]));
|
||||
ASSYM(_MC_R8, offsetof(mcontext_t, mc_frame[8]));
|
||||
ASSYM(_MC_R9, offsetof(mcontext_t, mc_frame[9]));
|
||||
ASSYM(_MC_R10, offsetof(mcontext_t, mc_frame[10]));
|
||||
ASSYM(_MC_R11, offsetof(mcontext_t, mc_frame[11]));
|
||||
ASSYM(_MC_R12, offsetof(mcontext_t, mc_frame[12]));
|
||||
ASSYM(_MC_R13, offsetof(mcontext_t, mc_frame[13]));
|
||||
ASSYM(_MC_R14, offsetof(mcontext_t, mc_frame[14]));
|
||||
ASSYM(_MC_R15, offsetof(mcontext_t, mc_frame[15]));
|
||||
ASSYM(_MC_R16, offsetof(mcontext_t, mc_frame[16]));
|
||||
ASSYM(_MC_R17, offsetof(mcontext_t, mc_frame[17]));
|
||||
ASSYM(_MC_R18, offsetof(mcontext_t, mc_frame[18]));
|
||||
ASSYM(_MC_R19, offsetof(mcontext_t, mc_frame[19]));
|
||||
ASSYM(_MC_R20, offsetof(mcontext_t, mc_frame[20]));
|
||||
ASSYM(_MC_R21, offsetof(mcontext_t, mc_frame[21]));
|
||||
ASSYM(_MC_R22, offsetof(mcontext_t, mc_frame[22]));
|
||||
ASSYM(_MC_R23, offsetof(mcontext_t, mc_frame[23]));
|
||||
ASSYM(_MC_R24, offsetof(mcontext_t, mc_frame[24]));
|
||||
ASSYM(_MC_R25, offsetof(mcontext_t, mc_frame[25]));
|
||||
ASSYM(_MC_R26, offsetof(mcontext_t, mc_frame[26]));
|
||||
ASSYM(_MC_R27, offsetof(mcontext_t, mc_frame[27]));
|
||||
ASSYM(_MC_R28, offsetof(mcontext_t, mc_frame[28]));
|
||||
ASSYM(_MC_R29, offsetof(mcontext_t, mc_frame[29]));
|
||||
ASSYM(_MC_R30, offsetof(mcontext_t, mc_frame[30]));
|
||||
ASSYM(_MC_R31, offsetof(mcontext_t, mc_frame[31]));
|
||||
ASSYM(_MC_LR, offsetof(mcontext_t, mc_frame[32]));
|
||||
ASSYM(_MC_CR, offsetof(mcontext_t, mc_frame[33]));
|
||||
ASSYM(_MC_XER, offsetof(mcontext_t, mc_frame[34]));
|
||||
ASSYM(_MC_CTR, offsetof(mcontext_t, mc_frame[35]));
|
||||
|
||||
ASSYM(_MC_FPSCR, offsetof(mcontext_t, mc_fpreg[32]));
|
||||
ASSYM(_MC_F0, offsetof(mcontext_t, mc_fpreg[0]));
|
||||
ASSYM(_MC_F1, offsetof(mcontext_t, mc_fpreg[1]));
|
||||
ASSYM(_MC_F2, offsetof(mcontext_t, mc_fpreg[2]));
|
||||
ASSYM(_MC_F3, offsetof(mcontext_t, mc_fpreg[3]));
|
||||
ASSYM(_MC_F4, offsetof(mcontext_t, mc_fpreg[4]));
|
||||
ASSYM(_MC_F5, offsetof(mcontext_t, mc_fpreg[5]));
|
||||
ASSYM(_MC_F6, offsetof(mcontext_t, mc_fpreg[6]));
|
||||
ASSYM(_MC_F7, offsetof(mcontext_t, mc_fpreg[7]));
|
||||
ASSYM(_MC_F8, offsetof(mcontext_t, mc_fpreg[8]));
|
||||
ASSYM(_MC_F9, offsetof(mcontext_t, mc_fpreg[9]));
|
||||
ASSYM(_MC_F10, offsetof(mcontext_t, mc_fpreg[10]));
|
||||
ASSYM(_MC_F11, offsetof(mcontext_t, mc_fpreg[11]));
|
||||
ASSYM(_MC_F12, offsetof(mcontext_t, mc_fpreg[12]));
|
||||
ASSYM(_MC_F13, offsetof(mcontext_t, mc_fpreg[13]));
|
||||
ASSYM(_MC_F14, offsetof(mcontext_t, mc_fpreg[14]));
|
||||
ASSYM(_MC_F15, offsetof(mcontext_t, mc_fpreg[15]));
|
||||
ASSYM(_MC_F16, offsetof(mcontext_t, mc_fpreg[16]));
|
||||
ASSYM(_MC_F17, offsetof(mcontext_t, mc_fpreg[17]));
|
||||
ASSYM(_MC_F18, offsetof(mcontext_t, mc_fpreg[18]));
|
||||
ASSYM(_MC_F19, offsetof(mcontext_t, mc_fpreg[19]));
|
||||
ASSYM(_MC_F20, offsetof(mcontext_t, mc_fpreg[20]));
|
||||
ASSYM(_MC_F21, offsetof(mcontext_t, mc_fpreg[21]));
|
||||
ASSYM(_MC_F22, offsetof(mcontext_t, mc_fpreg[22]));
|
||||
ASSYM(_MC_F23, offsetof(mcontext_t, mc_fpreg[23]));
|
||||
ASSYM(_MC_F24, offsetof(mcontext_t, mc_fpreg[24]));
|
||||
ASSYM(_MC_F25, offsetof(mcontext_t, mc_fpreg[25]));
|
||||
ASSYM(_MC_F26, offsetof(mcontext_t, mc_fpreg[26]));
|
||||
ASSYM(_MC_F27, offsetof(mcontext_t, mc_fpreg[27]));
|
||||
ASSYM(_MC_F28, offsetof(mcontext_t, mc_fpreg[28]));
|
||||
ASSYM(_MC_F29, offsetof(mcontext_t, mc_fpreg[29]));
|
||||
ASSYM(_MC_F30, offsetof(mcontext_t, mc_fpreg[30]));
|
||||
ASSYM(_MC_F31, offsetof(mcontext_t, mc_fpreg[31]));
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Struct offsets for version 0x1 of the mcontext struct.
|
||||
* Generated with
|
||||
* cc -c assym.c
|
||||
* ${SYSSRC}/kern/genassym.sh assym.o > assym_syms.s
|
||||
* hand-edit output
|
||||
*/
|
||||
#define _MC_VERSION 0x1
|
||||
#define _MC_VERSION_KSE 0xee
|
||||
#define _MC_FP_VALID 0x1
|
||||
|
||||
#define _MC_VERS 0x0
|
||||
#define _MC_FLAGS 0x4
|
||||
|
||||
#define _MC_R0 0x298
|
||||
#define _MC_R1 0x21c
|
||||
#define _MC_R2 0x220
|
||||
#define _MC_R3 0x224
|
||||
#define _MC_R4 0x228
|
||||
#define _MC_R5 0x22c
|
||||
#define _MC_R6 0x230
|
||||
#define _MC_R7 0x234
|
||||
#define _MC_R8 0x238
|
||||
#define _MC_R9 0x23c
|
||||
#define _MC_R10 0x240
|
||||
#define _MC_R11 0x244
|
||||
#define _MC_R12 0x248
|
||||
#define _MC_R13 0x24c
|
||||
#define _MC_R14 0x250
|
||||
#define _MC_R15 0x254
|
||||
#define _MC_R16 0x258
|
||||
#define _MC_R17 0x25c
|
||||
#define _MC_R18 0x260
|
||||
#define _MC_R19 0x264
|
||||
#define _MC_R20 0x268
|
||||
#define _MC_R21 0x26c
|
||||
#define _MC_R22 0x270
|
||||
#define _MC_R23 0x274
|
||||
#define _MC_R24 0x278
|
||||
#define _MC_R25 0x27c
|
||||
#define _MC_R26 0x280
|
||||
#define _MC_R27 0x284
|
||||
#define _MC_R28 0x288
|
||||
#define _MC_R29 0x28c
|
||||
#define _MC_R30 0x290
|
||||
#define _MC_R31 0x294
|
||||
#define _MC_LR 0x298
|
||||
#define _MC_CR 0x29c
|
||||
#define _MC_XER 0x2a0
|
||||
#define _MC_CTR 0x2a4
|
||||
|
||||
#define _MC_FPSCR 0x3c0
|
||||
#define _MC_F0 0x2c0
|
||||
#define _MC_F1 0x2c8
|
||||
#define _MC_F2 0x2d0
|
||||
#define _MC_F3 0x2d8
|
||||
#define _MC_F4 0x2e0
|
||||
#define _MC_F5 0x2e8
|
||||
#define _MC_F6 0x2f0
|
||||
#define _MC_F7 0x2f8
|
||||
#define _MC_F8 0x300
|
||||
#define _MC_F9 0x308
|
||||
#define _MC_F10 0x310
|
||||
#define _MC_F11 0x318
|
||||
#define _MC_F12 0x320
|
||||
#define _MC_F13 0x328
|
||||
#define _MC_F14 0x330
|
||||
#define _MC_F15 0x338
|
||||
#define _MC_F16 0x340
|
||||
#define _MC_F17 0x348
|
||||
#define _MC_F18 0x350
|
||||
#define _MC_F19 0x358
|
||||
#define _MC_F20 0x360
|
||||
#define _MC_F21 0x368
|
||||
#define _MC_F22 0x370
|
||||
#define _MC_F23 0x378
|
||||
#define _MC_F24 0x380
|
||||
#define _MC_F25 0x388
|
||||
#define _MC_F26 0x390
|
||||
#define _MC_F27 0x398
|
||||
#define _MC_F28 0x3a0
|
||||
#define _MC_F29 0x3a8
|
||||
#define _MC_F30 0x3b0
|
||||
#define _MC_F31 0x3b8
|
||||
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
/*
|
||||
* int _ppc32_getcontext(mcontext_t *mcp)
|
||||
*
|
||||
* Save register state from a voluntary context switch.
|
||||
* Only volatile registers, and those needed to complete
|
||||
* a setcontext call, need to be saved.
|
||||
*
|
||||
* r1
|
||||
* r14-31
|
||||
* f14-31 XXX
|
||||
* lr
|
||||
*
|
||||
* Return 0 for this call, and set up the context so it will return
|
||||
* 1 when restored with _ppc32_setcontext().
|
||||
*
|
||||
* XXX XXX
|
||||
* Floating-point is a big issue. Since there's no way to determine
|
||||
* if the caller has used FP, all volatile register need to be saved.
|
||||
* If FP hasn't been used, this results in a lazy FP exception in
|
||||
* the kernel and from that point on FP is always switched in/out
|
||||
* for the thread, which may be a big performance drag for the system.
|
||||
* An alternative is to use a system call to get the context, which
|
||||
* will do the right thing for floating point, but will save all
|
||||
* registers rather than the caller-saved subset, and has the overhead
|
||||
* of a syscall.
|
||||
* Maybe another option would be to give a light-weight way for a
|
||||
* thread to determine if FP is in used: perhaps a syscall that
|
||||
* returns in the asm traphandler, or an OSX-style read-only page
|
||||
* with a flag to indicate FP state.
|
||||
*
|
||||
* For now, punt the issue ala Alpha 1:1 model and fix in the future.
|
||||
*/
|
||||
ENTRY(_ppc32_getcontext)
|
||||
stw %r1, _MC_R1(%r3)
|
||||
stw %r13, _MC_R13(%r3)
|
||||
stw %r14, _MC_R14(%r3)
|
||||
stw %r15, _MC_R15(%r3)
|
||||
stw %r16, _MC_R16(%r3)
|
||||
stw %r17, _MC_R17(%r3)
|
||||
stw %r18, _MC_R18(%r3)
|
||||
stw %r19, _MC_R19(%r3)
|
||||
stw %r20, _MC_R20(%r3)
|
||||
stw %r21, _MC_R21(%r3)
|
||||
stw %r22, _MC_R22(%r3)
|
||||
stw %r23, _MC_R23(%r3)
|
||||
stw %r24, _MC_R24(%r3)
|
||||
stw %r25, _MC_R25(%r3)
|
||||
stw %r26, _MC_R26(%r3)
|
||||
stw %r27, _MC_R27(%r3)
|
||||
stw %r28, _MC_R28(%r3)
|
||||
stw %r29, _MC_R28(%r3)
|
||||
stw %r30, _MC_R30(%r3)
|
||||
stw %r31, _MC_R31(%r3)
|
||||
mflr %r4
|
||||
stw %r4, _MC_LR(%r3)
|
||||
mfcr %r4
|
||||
stw %r4, _MC_CR(%r3)
|
||||
|
||||
/* XXX f14-31 ? */
|
||||
|
||||
li %r4, _MC_VERSION_KSE /* partial ucontext version */
|
||||
stw %r4, _MC_VERS(%r3)
|
||||
|
||||
/* Return 0 */
|
||||
li %r3, 0
|
||||
blr
|
||||
|
||||
/*
|
||||
* int _ppc32_setcontext(const mcontext_t *mcp, intptr_t val,
|
||||
* intptr_t *loc);
|
||||
*
|
||||
* Should only be called for partial KSE contexts. The full context
|
||||
* case is handled by kse_switchin() in _thread_switch()
|
||||
*
|
||||
* Returns -1 on error and 1 for return from a saved context
|
||||
*/
|
||||
|
||||
ENTRY(_ppc32_setcontext)
|
||||
lwz %r6, _MC_VERS(%r3)
|
||||
cmpwi %r6, _MC_VERSION_KSE /* KSE partial context ? */
|
||||
beq 1f
|
||||
li %r3, -1 /* invalid context type, return -1 */
|
||||
blr
|
||||
|
||||
1: /* partial format, callee-saved regs assumed */
|
||||
lwz %r1, _MC_R1(%r3)
|
||||
lwz %r13, _MC_R13(%r3)
|
||||
lwz %r14, _MC_R14(%r3)
|
||||
lwz %r15, _MC_R15(%r3)
|
||||
lwz %r16, _MC_R16(%r3)
|
||||
lwz %r17, _MC_R17(%r3)
|
||||
lwz %r18, _MC_R18(%r3)
|
||||
lwz %r19, _MC_R19(%r3)
|
||||
lwz %r20, _MC_R20(%r3)
|
||||
lwz %r21, _MC_R21(%r3)
|
||||
lwz %r22, _MC_R22(%r3)
|
||||
lwz %r23, _MC_R23(%r3)
|
||||
lwz %r24, _MC_R24(%r3)
|
||||
lwz %r25, _MC_R25(%r3)
|
||||
lwz %r26, _MC_R26(%r3)
|
||||
lwz %r27, _MC_R27(%r3)
|
||||
lwz %r28, _MC_R28(%r3)
|
||||
lwz %r29, _MC_R28(%r3)
|
||||
lwz %r30, _MC_R30(%r3)
|
||||
lwz %r31, _MC_R31(%r3)
|
||||
lwz %r6, _MC_LR(%r3)
|
||||
mtlr %r6
|
||||
lwz %r6, _MC_CR(%r3)
|
||||
mtcr %r6
|
||||
|
||||
/* XXX f14-31 ? */
|
||||
|
||||
/* if (loc != NULL) *loc = val */
|
||||
cmpwi %r5, 0
|
||||
beq 2f
|
||||
stw %r4, 0(%r5)
|
||||
|
||||
/* Return 1 */
|
||||
2: li %r3, 1
|
||||
blr
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* _ppc32_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
* long stacksz);
|
||||
*
|
||||
* Call (*uts)(km) on the requested stack. This function doesn't
|
||||
* return. The km parameter stays in %r3.
|
||||
*/
|
||||
ENTRY(_ppc32_enter_uts)
|
||||
add %r1,%r5,%r6 /* new stack = stack + stacksz */
|
||||
mtlr %r4 /* link register = uts */
|
||||
blrl /* (*uts)(km) */
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* Copyright (c) 2006 Marcel Moolenaar
|
||||
* 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. Neither the name of the author 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 AUTHOR ``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 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>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = _rtld_allocate_tls((initial) ? ppc_get_tp() : NULL,
|
||||
sizeof(struct tcb), 8);
|
||||
if (tcb == NULL)
|
||||
return (NULL);
|
||||
tcb->tcb_thread = thread;
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 8);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb == NULL)
|
||||
return (NULL);
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_kse = kse;
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SRCS+= pthread_md.c thr_getcontext.S
|
@ -1,75 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <jake@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
#include <machine/atomic.h>
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap_long(long *dst, long val, long *res);
|
||||
*/
|
||||
static __inline void
|
||||
atomic_swap_long(volatile long *dst, long val, long *res)
|
||||
{
|
||||
long tmp;
|
||||
long r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_64(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_swap_int(volatile int *dst, int val, int *res)
|
||||
{
|
||||
int tmp;
|
||||
int r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_32(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(dst, val, res) \
|
||||
atomic_swap_long((volatile long *)dst, (long)val, (long *)res)
|
||||
|
||||
#endif
|
@ -1,254 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <jake@freebsd.org>.
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_tdv)
|
||||
|
||||
int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
int _thr_getcontext(mcontext_t *);
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv; /* We don't know what this is yet? */
|
||||
|
||||
|
||||
/*
|
||||
* %g6 points to one of these. We define the static TLS as an array
|
||||
* of long double to enforce 16-byte alignment of the TLS memory.
|
||||
*
|
||||
* XXX - Both static and dynamic allocation of any of these structures
|
||||
* will result in a valid, well-aligned thread pointer???
|
||||
*/
|
||||
struct sparc64_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
uint64_t _reserved_;
|
||||
long double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_addr; /* allocated tcb address */
|
||||
struct kcb *tcb_curkcb;
|
||||
uint64_t tcb_isfake;
|
||||
uint64_t tcb_spare[4];
|
||||
struct kse_thr_mailbox tcb_tmbx; /* needs 64-byte alignment */
|
||||
struct sparc64_tp tcb_tp;
|
||||
} __aligned(64);
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
register struct sparc64_tp *_tp __asm("%g6");
|
||||
|
||||
#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
_tp = &tcb->tcb_tp;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
void _sparc64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
size_t stacksz);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
_sparc64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
extern int _libkse_debug;
|
||||
mcontext_t *mc;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
if (_libkse_debug == 0) {
|
||||
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
|
||||
if (setmbox)
|
||||
_thr_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)(void *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_thr_setcontext(mc, 0, NULL);
|
||||
} else {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
}
|
||||
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Offsets into structures used from asm. Must be kept in sync with
|
||||
* appropriate headers.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define UC_MCONTEXT 0x40
|
||||
|
||||
#define MC_FLAGS 0x0
|
||||
#define MC_VALID_FLAGS 0x1
|
||||
#define MC_GLOBAL 0x0
|
||||
#define MC_OUT 0x40
|
||||
#define MC_TPC 0xc8
|
||||
#define MC_TNPC 0xc0
|
@ -1,91 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* Copyright (C) 2003 David Xu <davidxu@freebsd.org>
|
||||
* Copyright (c) 2001,2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
|
||||
addr = malloc(sizeof(struct tcb) + 63);
|
||||
if (addr == NULL)
|
||||
tcb = NULL;
|
||||
else {
|
||||
tcb = (struct tcb *)(((uintptr_t)(addr) + 63) & ~63);
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_addr = addr;
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
addr = tcb->tcb_addr;
|
||||
tcb->tcb_addr = NULL;
|
||||
free(addr);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
.weak CNAME(_thr_getcontext)
|
||||
.set CNAME(_thr_getcontext),CNAME(__thr_getcontext)
|
||||
ENTRY(__thr_getcontext)
|
||||
add %o7, 8, %o1
|
||||
add %o1, 4, %o2
|
||||
stx %sp, [%o0 + MC_OUT + (6 * 8)]
|
||||
stx %o1, [%o0 + MC_TPC]
|
||||
stx %o2, [%o0 + MC_TNPC]
|
||||
mov MC_VALID_FLAGS, %l0 /* Validate the context. */
|
||||
stx %l0, [%o0 + MC_FLAGS]
|
||||
mov 1, %l0
|
||||
stx %l0, [%o0 + MC_OUT + (0 * 8)] /* return 1 when resumed */
|
||||
retl
|
||||
mov 0, %o0 /* return 0 */
|
||||
END(__thr_getcontext)
|
||||
|
||||
.weak CNAME(_thr_setcontext)
|
||||
.set CNAME(_thr_setcontext),CNAME(__thr_setcontext)
|
||||
ENTRY(__thr_setcontext)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
mov %i0, %l0
|
||||
mov %i1, %l1
|
||||
mov %i2, %l2
|
||||
ldx [%l0 + MC_GLOBAL + (1 * 8)], %g1
|
||||
ldx [%l0 + MC_GLOBAL + (2 * 8)], %g2
|
||||
ldx [%l0 + MC_GLOBAL + (3 * 8)], %g3
|
||||
ldx [%l0 + MC_GLOBAL + (4 * 8)], %g4
|
||||
ldx [%l0 + MC_GLOBAL + (5 * 8)], %g5
|
||||
ldx [%l0 + MC_GLOBAL + (6 * 8)], %g6
|
||||
ldx [%l0 + MC_GLOBAL + (7 * 8)], %g7
|
||||
ldx [%l0 + MC_OUT + (0 * 8)], %i0
|
||||
ldx [%l0 + MC_OUT + (1 * 8)], %i1
|
||||
ldx [%l0 + MC_OUT + (2 * 8)], %i2
|
||||
ldx [%l0 + MC_OUT + (3 * 8)], %i3
|
||||
ldx [%l0 + MC_OUT + (4 * 8)], %i4
|
||||
ldx [%l0 + MC_OUT + (5 * 8)], %i5
|
||||
ldx [%l0 + MC_OUT + (6 * 8)], %i6
|
||||
ldx [%l0 + MC_OUT + (7 * 8)], %i7
|
||||
ldx [%l0 + MC_TPC], %l4
|
||||
ldx [%l0 + MC_TNPC], %l3
|
||||
brz %l2, 1f
|
||||
nop
|
||||
stx %l1, [%l2]
|
||||
1: jmpl %l3, %g0
|
||||
return %l4
|
||||
END(__thr_setcontext)
|
||||
|
||||
ENTRY(_sparc64_enter_uts)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
add %i2, %i3, %i2
|
||||
sub %i2, SPOFF + CCFSZ, %sp
|
||||
jmpl %i0, %g0
|
||||
mov %i1, %o0
|
||||
END(_sparc64_enter_uts)
|
@ -1,367 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Use the same naming scheme as libc.
|
||||
*/
|
||||
FBSD_1.0 {
|
||||
__error;
|
||||
accept;
|
||||
aio_suspend;
|
||||
close;
|
||||
connect;
|
||||
creat;
|
||||
execve;
|
||||
fcntl;
|
||||
fork;
|
||||
fsync;
|
||||
msync;
|
||||
nanosleep;
|
||||
open;
|
||||
pause;
|
||||
poll;
|
||||
pselect;
|
||||
pthread_atfork;
|
||||
pthread_barrier_destroy;
|
||||
pthread_barrier_init;
|
||||
pthread_barrier_wait;
|
||||
pthread_barrierattr_destroy;
|
||||
pthread_barrierattr_getpshared;
|
||||
pthread_barrierattr_init;
|
||||
pthread_barrierattr_setpshared;
|
||||
pthread_attr_destroy;
|
||||
pthread_attr_get_np;
|
||||
pthread_attr_getdetachstate;
|
||||
pthread_attr_getguardsize;
|
||||
pthread_attr_getinheritsched;
|
||||
pthread_attr_getschedparam;
|
||||
pthread_attr_getschedpolicy;
|
||||
pthread_attr_getscope;
|
||||
pthread_attr_getstack;
|
||||
pthread_attr_getstackaddr;
|
||||
pthread_attr_getstacksize;
|
||||
pthread_attr_init;
|
||||
pthread_attr_setcreatesuspend_np;
|
||||
pthread_attr_setdetachstate;
|
||||
pthread_attr_setguardsize;
|
||||
pthread_attr_setinheritsched;
|
||||
pthread_attr_setschedparam;
|
||||
pthread_attr_setschedpolicy;
|
||||
pthread_attr_setscope;
|
||||
pthread_attr_setstack;
|
||||
pthread_attr_setstackaddr;
|
||||
pthread_attr_setstacksize;
|
||||
pthread_cancel;
|
||||
pthread_cleanup_pop;
|
||||
pthread_cleanup_push;
|
||||
pthread_cond_broadcast;
|
||||
pthread_cond_destroy;
|
||||
pthread_cond_init;
|
||||
pthread_cond_signal;
|
||||
pthread_cond_timedwait;
|
||||
pthread_cond_wait;
|
||||
pthread_condattr_destroy;
|
||||
pthread_condattr_init;
|
||||
pthread_create;
|
||||
pthread_detach;
|
||||
pthread_equal;
|
||||
pthread_exit;
|
||||
pthread_getconcurrency;
|
||||
pthread_getprio;
|
||||
pthread_getschedparam;
|
||||
pthread_getspecific;
|
||||
pthread_join;
|
||||
pthread_key_create;
|
||||
pthread_key_delete;
|
||||
pthread_kill;
|
||||
pthread_main_np;
|
||||
pthread_multi_np;
|
||||
pthread_mutex_destroy;
|
||||
pthread_mutex_getprioceiling;
|
||||
pthread_mutex_init;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_setprioceiling;
|
||||
pthread_mutex_timedlock;
|
||||
pthread_mutex_trylock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_mutexattr_destroy;
|
||||
pthread_mutexattr_getkind_np;
|
||||
pthread_mutexattr_getprioceiling;
|
||||
pthread_mutexattr_getprotocol;
|
||||
pthread_mutexattr_gettype;
|
||||
pthread_mutexattr_init;
|
||||
pthread_mutexattr_setkind_np;
|
||||
pthread_mutexattr_setprioceiling;
|
||||
pthread_mutexattr_setprotocol;
|
||||
pthread_mutexattr_settype;
|
||||
pthread_once;
|
||||
pthread_resume_all_np;
|
||||
pthread_resume_np;
|
||||
pthread_rwlock_destroy;
|
||||
pthread_rwlock_init;
|
||||
pthread_rwlock_rdlock;
|
||||
pthread_rwlock_timedrdlock;
|
||||
pthread_rwlock_timedwrlock;
|
||||
pthread_rwlock_tryrdlock;
|
||||
pthread_rwlock_trywrlock;
|
||||
pthread_rwlock_unlock;
|
||||
pthread_rwlock_wrlock;
|
||||
pthread_rwlockattr_destroy;
|
||||
pthread_rwlockattr_getpshared;
|
||||
pthread_rwlockattr_init;
|
||||
pthread_rwlockattr_setpshared;
|
||||
pthread_self;
|
||||
pthread_set_name_np;
|
||||
pthread_setcancelstate;
|
||||
pthread_setcanceltype;
|
||||
pthread_setconcurrency;
|
||||
pthread_setprio;
|
||||
pthread_setschedparam;
|
||||
pthread_setspecific;
|
||||
pthread_sigmask;
|
||||
pthread_single_np;
|
||||
pthread_spin_destroy;
|
||||
pthread_spin_init;
|
||||
pthread_spin_lock;
|
||||
pthread_spin_trylock;
|
||||
pthread_spin_unlock;
|
||||
pthread_suspend_all_np;
|
||||
pthread_suspend_np;
|
||||
pthread_switch_add_np;
|
||||
pthread_switch_delete_np;
|
||||
pthread_testcancel;
|
||||
pthread_yield;
|
||||
raise;
|
||||
read;
|
||||
readv;
|
||||
sched_yield;
|
||||
select;
|
||||
sem_init;
|
||||
sem_post;
|
||||
sem_timedwait;
|
||||
sem_wait;
|
||||
sigaction;
|
||||
sigaltstack;
|
||||
sigpending;
|
||||
sigprocmask;
|
||||
sigsuspend;
|
||||
sigwait;
|
||||
sigwaitinfo;
|
||||
sigtimedwait;
|
||||
sleep;
|
||||
system;
|
||||
tcdrain;
|
||||
usleep;
|
||||
vfork;
|
||||
wait4;
|
||||
wait;
|
||||
waitpid;
|
||||
write;
|
||||
writev;
|
||||
};
|
||||
|
||||
/*
|
||||
* List the private interfaces reserved for use in FreeBSD libraries.
|
||||
* These are not part of our application ABI.
|
||||
*/
|
||||
FBSDprivate_1.0 {
|
||||
___creat;
|
||||
__accept;
|
||||
__close;
|
||||
__connect;
|
||||
__fcntl;
|
||||
__fsync;
|
||||
__msync;
|
||||
__nanosleep;
|
||||
__open;
|
||||
__poll;
|
||||
__pthread_cond_timedwait;
|
||||
__pthread_cond_wait;
|
||||
__pthread_mutex_init;
|
||||
__pthread_mutex_lock;
|
||||
__pthread_mutex_trylock;
|
||||
__pthread_mutex_timedlock;
|
||||
__read;
|
||||
__readv;
|
||||
__select;
|
||||
__sigsuspend;
|
||||
__sigtimedwait;
|
||||
__sigwait;
|
||||
__sigwaitinfo;
|
||||
__wait4;
|
||||
__write;
|
||||
__writev;
|
||||
_aio_suspend;
|
||||
_execve;
|
||||
_fork;
|
||||
_nanosleep;
|
||||
_pause;
|
||||
_pselect;
|
||||
_pthread_atfork;
|
||||
_pthread_barrier_destroy;
|
||||
_pthread_barrier_init;
|
||||
_pthread_barrier_wait;
|
||||
_pthread_barrierattr_destroy;
|
||||
_pthread_barrierattr_getpshared;
|
||||
_pthread_barrierattr_init;
|
||||
_pthread_barrierattr_setpshared;
|
||||
_pthread_attr_destroy;
|
||||
_pthread_attr_get_np;
|
||||
_pthread_attr_getdetachstate;
|
||||
_pthread_attr_getguardsize;
|
||||
_pthread_attr_getinheritsched;
|
||||
_pthread_attr_getschedparam;
|
||||
_pthread_attr_getschedpolicy;
|
||||
_pthread_attr_getscope;
|
||||
_pthread_attr_getstack;
|
||||
_pthread_attr_getstackaddr;
|
||||
_pthread_attr_getstacksize;
|
||||
_pthread_attr_init;
|
||||
_pthread_attr_setcreatesuspend_np;
|
||||
_pthread_attr_setdetachstate;
|
||||
_pthread_attr_setguardsize;
|
||||
_pthread_attr_setinheritsched;
|
||||
_pthread_attr_setschedparam;
|
||||
_pthread_attr_setschedpolicy;
|
||||
_pthread_attr_setscope;
|
||||
_pthread_attr_setstack;
|
||||
_pthread_attr_setstackaddr;
|
||||
_pthread_attr_setstacksize;
|
||||
_pthread_cancel;
|
||||
_pthread_cleanup_pop;
|
||||
_pthread_cleanup_push;
|
||||
_pthread_cond_broadcast;
|
||||
_pthread_cond_destroy;
|
||||
_pthread_cond_init;
|
||||
_pthread_cond_signal;
|
||||
_pthread_cond_timedwait;
|
||||
_pthread_cond_wait;
|
||||
_pthread_condattr_default;
|
||||
_pthread_condattr_destroy;
|
||||
_pthread_condattr_init;
|
||||
_pthread_create;
|
||||
_pthread_detach;
|
||||
_pthread_equal;
|
||||
_pthread_exit;
|
||||
_pthread_getconcurrency;
|
||||
_pthread_getprio;
|
||||
_pthread_getschedparam;
|
||||
_pthread_getspecific;
|
||||
_pthread_join;
|
||||
_pthread_key_create;
|
||||
_pthread_key_delete;
|
||||
_pthread_kill;
|
||||
_pthread_main_np;
|
||||
_pthread_multi_np;
|
||||
_pthread_mutex_destroy;
|
||||
_pthread_mutex_getprioceiling;
|
||||
_pthread_mutex_init;
|
||||
_pthread_mutex_init_calloc_cb;
|
||||
_pthread_mutex_isowned_np;
|
||||
_pthread_mutex_lock;
|
||||
_pthread_mutex_setprioceiling;
|
||||
_pthread_mutex_timedlock;
|
||||
_pthread_mutex_trylock;
|
||||
_pthread_mutex_unlock;
|
||||
_pthread_mutexattr_default;
|
||||
_pthread_mutexattr_destroy;
|
||||
_pthread_mutexattr_getkind_np;
|
||||
_pthread_mutexattr_getprioceiling;
|
||||
_pthread_mutexattr_getprotocol;
|
||||
_pthread_mutexattr_gettype;
|
||||
_pthread_mutexattr_init;
|
||||
_pthread_mutexattr_setkind_np;
|
||||
_pthread_mutexattr_setprioceiling;
|
||||
_pthread_mutexattr_setprotocol;
|
||||
_pthread_mutexattr_settype;
|
||||
_pthread_once;
|
||||
_pthread_resume_all_np;
|
||||
_pthread_resume_np;
|
||||
_pthread_rwlock_destroy;
|
||||
_pthread_rwlock_init;
|
||||
_pthread_rwlock_rdlock;
|
||||
_pthread_rwlock_timedrdlock;
|
||||
_pthread_rwlock_timedwrlock;
|
||||
_pthread_rwlock_tryrdlock;
|
||||
_pthread_rwlock_trywrlock;
|
||||
_pthread_rwlock_unlock;
|
||||
_pthread_rwlock_wrlock;
|
||||
_pthread_rwlockattr_destroy;
|
||||
_pthread_rwlockattr_getpshared;
|
||||
_pthread_rwlockattr_init;
|
||||
_pthread_rwlockattr_setpshared;
|
||||
_pthread_self;
|
||||
_pthread_set_name_np;
|
||||
_pthread_setcancelstate;
|
||||
_pthread_setcanceltype;
|
||||
_pthread_setconcurrency;
|
||||
_pthread_setprio;
|
||||
_pthread_setschedparam;
|
||||
_pthread_setspecific;
|
||||
_pthread_sigmask;
|
||||
_pthread_single_np;
|
||||
_pthread_spin_destroy;
|
||||
_pthread_spin_init;
|
||||
_pthread_spin_lock;
|
||||
_pthread_spin_trylock;
|
||||
_pthread_spin_unlock;
|
||||
_pthread_suspend_all_np;
|
||||
_pthread_suspend_np;
|
||||
_pthread_switch_add_np;
|
||||
_pthread_switch_delete_np;
|
||||
_pthread_testcancel;
|
||||
_pthread_yield;
|
||||
_raise;
|
||||
_sched_yield;
|
||||
_sem_init;
|
||||
_sem_post;
|
||||
_sem_timedwait;
|
||||
_sem_wait;
|
||||
_sigaction;
|
||||
_sigaltstack;
|
||||
_sigpending;
|
||||
_sigprocmask;
|
||||
_sigsuspend;
|
||||
_sigtimedwait;
|
||||
_sigwait;
|
||||
_sigwaitinfo;
|
||||
_sleep;
|
||||
_spinlock;
|
||||
_spinlock_debug;
|
||||
_spinunlock;
|
||||
_system;
|
||||
_tcdrain;
|
||||
_usleep;
|
||||
_vfork;
|
||||
_wait;
|
||||
_waitpid;
|
||||
|
||||
/* Debugger needs these. */
|
||||
_libkse_debug;
|
||||
_thread_activated;
|
||||
_thread_active_threads;
|
||||
_thread_keytable;
|
||||
_thread_list;
|
||||
_thread_max_keys;
|
||||
_thread_off_attr_flags;
|
||||
_thread_off_dtv;
|
||||
_thread_off_linkmap;
|
||||
_thread_off_next;
|
||||
_thread_off_tcb;
|
||||
_thread_off_tmbx;
|
||||
_thread_off_key_allocated;
|
||||
_thread_off_key_destructor;
|
||||
_thread_off_kse;
|
||||
_thread_off_kse_locklevel;
|
||||
_thread_off_sigmask;
|
||||
_thread_off_sigpend;
|
||||
_thread_off_state;
|
||||
_thread_off_thr_locklevel;
|
||||
_thread_off_tlsindex;
|
||||
_thread_size_key;
|
||||
_thread_state_running;
|
||||
_thread_state_zoombie;
|
||||
};
|
||||
|
||||
FBSD_1.1 {
|
||||
pthread_mutex_isowned_np;
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/support ${.CURDIR}/../libc/gen ${.CURDIR}/../libc/string
|
||||
.PATH: ${.CURDIR}/../libc/${MACHINE_CPUARCH}/sys
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../libc/${MACHINE_CPUARCH}
|
||||
|
||||
SYSCALLS= clock_gettime \
|
||||
kse_create \
|
||||
kse_exit \
|
||||
kse_release \
|
||||
kse_switchin \
|
||||
kse_thr_interrupt \
|
||||
kse_wakeup \
|
||||
sigaction \
|
||||
sigprocmask \
|
||||
sigtimedwait \
|
||||
write
|
||||
|
||||
SYSCALL_SRC= ${SYSCALLS:S/$/.S/}
|
||||
SYSCALL_OBJ= ${SYSCALLS:S/$/.So/}
|
||||
|
||||
${SYSCALL_SRC}:
|
||||
printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' > ${.TARGET}
|
||||
|
||||
LIBC_OBJS= sigsetops.So \
|
||||
bcopy.So \
|
||||
bzero.So \
|
||||
cerror.So \
|
||||
memcpy.So \
|
||||
memset.So \
|
||||
strcpy.So \
|
||||
strlen.So
|
||||
|
||||
SOBJS+= thr_libc.So
|
||||
CLEANFILES+= ${SYSCALL_SRC} ${SYSCALL_OBJ} ${LIBC_OBJS}
|
||||
|
||||
thr_libc.So: ${SYSCALL_OBJ} ${LIBC_OBJS}
|
||||
${CC} -fPIC -nostdlib -o ${.TARGET} -r ${.ALLSRC}
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2003 Alexander Kabaev.
|
||||
* 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kse.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "thr_private.h"
|
||||
|
||||
__strong_reference(clock_gettime, _thr_clock_gettime);
|
||||
__strong_reference(kse_exit, _thr_kse_exit);
|
||||
__strong_reference(kse_wakeup, _thr_kse_wakeup);
|
||||
__strong_reference(kse_create, _thr_kse_create);
|
||||
__strong_reference(kse_thr_interrupt, _thr_kse_thr_interrupt);
|
||||
__strong_reference(kse_release, _thr_kse_release);
|
||||
__strong_reference(kse_switchin, _thr_kse_switchin);
|
||||
|
||||
__strong_reference(sigaction, _thr_sigaction);
|
||||
__strong_reference(sigprocmask, _thr_sigprocmask);
|
||||
__strong_reference(sigemptyset, _thr_sigemptyset);
|
||||
__strong_reference(sigaddset, _thr_sigaddset);
|
||||
__strong_reference(sigfillset, _thr_sigfillset);
|
||||
__strong_reference(sigismember, _thr_sigismember);
|
||||
__strong_reference(sigdelset, _thr_sigdelset);
|
||||
|
||||
__strong_reference(memset, _thr_memset);
|
||||
__strong_reference(memcpy, _thr_memcpy);
|
||||
__strong_reference(strcpy, _thr_strcpy);
|
||||
__strong_reference(strlen, _thr_strlen);
|
||||
__strong_reference(bzero, _thr_bzero);
|
||||
__strong_reference(bcopy, _thr_bcopy);
|
||||
|
||||
__strong_reference(__sys_write, _thr__sys_write);
|
||||
__strong_reference(__sys_sigtimedwait, _thr__sys_sigtimedwait);
|
||||
|
@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/sys
|
||||
|
||||
SRCS+= lock.c thr_error.c
|
@ -1,362 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001, 2003 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "atomic_ops.h"
|
||||
#include "lock.h"
|
||||
|
||||
#ifdef _LOCK_DEBUG
|
||||
#define LCK_ASSERT(e) assert(e)
|
||||
#else
|
||||
#define LCK_ASSERT(e)
|
||||
#endif
|
||||
|
||||
#define MAX_SPINS 500
|
||||
|
||||
void
|
||||
_lock_destroy(struct lock *lck)
|
||||
{
|
||||
if ((lck != NULL) && (lck->l_head != NULL)) {
|
||||
free(lck->l_head);
|
||||
lck->l_head = NULL;
|
||||
lck->l_tail = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_lock_init(struct lock *lck, enum lock_type ltype,
|
||||
lock_handler_t *waitfunc, lock_handler_t *wakeupfunc,
|
||||
void *(calloc_cb)(size_t, size_t))
|
||||
{
|
||||
if (lck == NULL)
|
||||
return (-1);
|
||||
else if ((lck->l_head = calloc_cb(1, sizeof(struct lockreq))) == NULL)
|
||||
return (-1);
|
||||
else {
|
||||
lck->l_type = ltype;
|
||||
lck->l_wait = waitfunc;
|
||||
lck->l_wakeup = wakeupfunc;
|
||||
lck->l_head->lr_locked = 0;
|
||||
lck->l_head->lr_watcher = NULL;
|
||||
lck->l_head->lr_owner = NULL;
|
||||
lck->l_head->lr_active = 1;
|
||||
lck->l_tail = lck->l_head;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_lock_reinit(struct lock *lck, enum lock_type ltype,
|
||||
lock_handler_t *waitfunc, lock_handler_t *wakeupfunc)
|
||||
{
|
||||
if (lck == NULL)
|
||||
return (-1);
|
||||
else if (lck->l_head == NULL)
|
||||
return (_lock_init(lck, ltype, waitfunc, wakeupfunc, calloc));
|
||||
else {
|
||||
lck->l_head->lr_locked = 0;
|
||||
lck->l_head->lr_watcher = NULL;
|
||||
lck->l_head->lr_owner = NULL;
|
||||
lck->l_head->lr_active = 1;
|
||||
lck->l_tail = lck->l_head;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_lockuser_init(struct lockuser *lu, void *priv)
|
||||
{
|
||||
if (lu == NULL)
|
||||
return (-1);
|
||||
else if ((lu->lu_myreq == NULL) &&
|
||||
((lu->lu_myreq = malloc(sizeof(struct lockreq))) == NULL))
|
||||
return (-1);
|
||||
else {
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
lu->lu_myreq->lr_watcher = NULL;
|
||||
lu->lu_myreq->lr_owner = lu;
|
||||
lu->lu_myreq->lr_active = 0;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_priority = 0;
|
||||
lu->lu_private = priv;
|
||||
lu->lu_private2 = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_lockuser_reinit(struct lockuser *lu, void *priv)
|
||||
{
|
||||
if (lu == NULL)
|
||||
return (-1);
|
||||
if (lu->lu_watchreq != NULL) {
|
||||
/*
|
||||
* In this case the lock is active. All lockusers
|
||||
* keep their watch request and drop their own
|
||||
* (lu_myreq) request. Their own request is either
|
||||
* some other lockuser's watch request or is the
|
||||
* head of the lock.
|
||||
*/
|
||||
lu->lu_myreq = lu->lu_watchreq;
|
||||
lu->lu_watchreq = NULL;
|
||||
}
|
||||
if (lu->lu_myreq == NULL)
|
||||
/*
|
||||
* Oops, something isn't quite right. Try to
|
||||
* allocate one.
|
||||
*/
|
||||
return (_lockuser_init(lu, priv));
|
||||
else {
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
lu->lu_myreq->lr_watcher = NULL;
|
||||
lu->lu_myreq->lr_owner = lu;
|
||||
lu->lu_myreq->lr_active = 0;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_priority = 0;
|
||||
lu->lu_private = priv;
|
||||
lu->lu_private2 = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
_lockuser_destroy(struct lockuser *lu)
|
||||
{
|
||||
if ((lu != NULL) && (lu->lu_myreq != NULL))
|
||||
free(lu->lu_myreq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acquire a lock waiting (spin or sleep) for it to become available.
|
||||
*/
|
||||
void
|
||||
_lock_acquire(struct lock *lck, struct lockuser *lu, int prio)
|
||||
{
|
||||
int i;
|
||||
int lval;
|
||||
|
||||
/**
|
||||
* XXX - We probably want to remove these checks to optimize
|
||||
* performance. It is also a bug if any one of the
|
||||
* checks fail, so it's probably better to just let it
|
||||
* SEGV and fix it.
|
||||
*/
|
||||
#if 0
|
||||
if (lck == NULL || lu == NULL || lck->l_head == NULL)
|
||||
return;
|
||||
#endif
|
||||
if ((lck->l_type & LCK_PRIORITY) != 0) {
|
||||
LCK_ASSERT(lu->lu_myreq->lr_locked == 1);
|
||||
LCK_ASSERT(lu->lu_myreq->lr_watcher == NULL);
|
||||
LCK_ASSERT(lu->lu_myreq->lr_owner == lu);
|
||||
LCK_ASSERT(lu->lu_watchreq == NULL);
|
||||
|
||||
lu->lu_priority = prio;
|
||||
}
|
||||
/*
|
||||
* Atomically swap the head of the lock request with
|
||||
* this request.
|
||||
*/
|
||||
atomic_swap_ptr((void *)&lck->l_head, lu->lu_myreq,
|
||||
(void *)&lu->lu_watchreq);
|
||||
|
||||
if (lu->lu_watchreq->lr_locked != 0) {
|
||||
atomic_store_rel_ptr
|
||||
((volatile uintptr_t *)(void *)&lu->lu_watchreq->lr_watcher,
|
||||
(uintptr_t)lu);
|
||||
if ((lck->l_wait == NULL) ||
|
||||
((lck->l_type & LCK_ADAPTIVE) == 0)) {
|
||||
while (lu->lu_watchreq->lr_locked != 0)
|
||||
; /* spin, then yield? */
|
||||
} else {
|
||||
/*
|
||||
* Spin for a bit before invoking the wait function.
|
||||
*
|
||||
* We should be a little smarter here. If we're
|
||||
* running on a single processor, then the lock
|
||||
* owner got preempted and spinning will accomplish
|
||||
* nothing but waste time. If we're running on
|
||||
* multiple processors, the owner could be running
|
||||
* on another CPU and we might acquire the lock if
|
||||
* we spin for a bit.
|
||||
*
|
||||
* The other thing to keep in mind is that threads
|
||||
* acquiring these locks are considered to be in
|
||||
* critical regions; they will not be preempted by
|
||||
* the _UTS_ until they release the lock. It is
|
||||
* therefore safe to assume that if a lock can't
|
||||
* be acquired, it is currently held by a thread
|
||||
* running in another KSE.
|
||||
*/
|
||||
for (i = 0; i < MAX_SPINS; i++) {
|
||||
if (lu->lu_watchreq->lr_locked == 0)
|
||||
return;
|
||||
if (lu->lu_watchreq->lr_active == 0)
|
||||
break;
|
||||
}
|
||||
atomic_swap_int(&lu->lu_watchreq->lr_locked,
|
||||
2, &lval);
|
||||
if (lval == 0)
|
||||
lu->lu_watchreq->lr_locked = 0;
|
||||
else
|
||||
lck->l_wait(lck, lu);
|
||||
|
||||
}
|
||||
}
|
||||
lu->lu_myreq->lr_active = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a lock.
|
||||
*/
|
||||
void
|
||||
_lock_release(struct lock *lck, struct lockuser *lu)
|
||||
{
|
||||
struct lockuser *lu_tmp, *lu_h;
|
||||
struct lockreq *myreq;
|
||||
int prio_h;
|
||||
int lval;
|
||||
|
||||
/**
|
||||
* XXX - We probably want to remove these checks to optimize
|
||||
* performance. It is also a bug if any one of the
|
||||
* checks fail, so it's probably better to just let it
|
||||
* SEGV and fix it.
|
||||
*/
|
||||
#if 0
|
||||
if ((lck == NULL) || (lu == NULL))
|
||||
return;
|
||||
#endif
|
||||
if ((lck->l_type & LCK_PRIORITY) != 0) {
|
||||
prio_h = 0;
|
||||
lu_h = NULL;
|
||||
|
||||
/* Update tail if our request is last. */
|
||||
if (lu->lu_watchreq->lr_owner == NULL) {
|
||||
atomic_store_rel_ptr((volatile uintptr_t *)
|
||||
(void *)&lck->l_tail,
|
||||
(uintptr_t)lu->lu_myreq);
|
||||
atomic_store_rel_ptr((volatile uintptr_t *)
|
||||
(void *)&lu->lu_myreq->lr_owner,
|
||||
(uintptr_t)NULL);
|
||||
} else {
|
||||
/* Remove ourselves from the list. */
|
||||
atomic_store_rel_ptr((volatile uintptr_t *)
|
||||
(void *)&lu->lu_myreq->lr_owner,
|
||||
(uintptr_t)lu->lu_watchreq->lr_owner);
|
||||
atomic_store_rel_ptr((volatile uintptr_t *)
|
||||
(void *)&lu->lu_watchreq->lr_owner->lu_myreq,
|
||||
(uintptr_t)lu->lu_myreq);
|
||||
}
|
||||
/*
|
||||
* The watch request now becomes our own because we've
|
||||
* traded away our previous request. Save our previous
|
||||
* request so that we can grant the lock.
|
||||
*/
|
||||
myreq = lu->lu_myreq;
|
||||
lu->lu_myreq = lu->lu_watchreq;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
lu->lu_myreq->lr_owner = lu;
|
||||
lu->lu_myreq->lr_watcher = NULL;
|
||||
/*
|
||||
* Traverse the list of lock requests in reverse order
|
||||
* looking for the user with the highest priority.
|
||||
*/
|
||||
for (lu_tmp = lck->l_tail->lr_watcher; lu_tmp != NULL;
|
||||
lu_tmp = lu_tmp->lu_myreq->lr_watcher) {
|
||||
if (lu_tmp->lu_priority > prio_h) {
|
||||
lu_h = lu_tmp;
|
||||
prio_h = lu_tmp->lu_priority;
|
||||
}
|
||||
}
|
||||
if (lu_h != NULL) {
|
||||
/* Give the lock to the highest priority user. */
|
||||
if (lck->l_wakeup != NULL) {
|
||||
atomic_swap_int(
|
||||
&lu_h->lu_watchreq->lr_locked,
|
||||
0, &lval);
|
||||
if (lval == 2)
|
||||
/* Notify the sleeper */
|
||||
lck->l_wakeup(lck,
|
||||
lu_h->lu_myreq->lr_watcher);
|
||||
}
|
||||
else
|
||||
atomic_store_rel_int(
|
||||
&lu_h->lu_watchreq->lr_locked, 0);
|
||||
} else {
|
||||
if (lck->l_wakeup != NULL) {
|
||||
atomic_swap_int(&myreq->lr_locked,
|
||||
0, &lval);
|
||||
if (lval == 2)
|
||||
/* Notify the sleeper */
|
||||
lck->l_wakeup(lck, myreq->lr_watcher);
|
||||
}
|
||||
else
|
||||
/* Give the lock to the previous request. */
|
||||
atomic_store_rel_int(&myreq->lr_locked, 0);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The watch request now becomes our own because we've
|
||||
* traded away our previous request. Save our previous
|
||||
* request so that we can grant the lock.
|
||||
*/
|
||||
myreq = lu->lu_myreq;
|
||||
lu->lu_myreq = lu->lu_watchreq;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
if (lck->l_wakeup) {
|
||||
atomic_swap_int(&myreq->lr_locked, 0, &lval);
|
||||
if (lval == 2)
|
||||
/* Notify the sleeper */
|
||||
lck->l_wakeup(lck, myreq->lr_watcher);
|
||||
}
|
||||
else
|
||||
/* Give the lock to the previous request. */
|
||||
atomic_store_rel_int(&myreq->lr_locked, 0);
|
||||
}
|
||||
lu->lu_myreq->lr_active = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_lock_grant(struct lock *lck __unused /* unused */, struct lockuser *lu)
|
||||
{
|
||||
atomic_store_rel_int(&lu->lu_watchreq->lr_locked, 3);
|
||||
}
|
||||
|
||||
void
|
||||
_lockuser_setactive(struct lockuser *lu, int active)
|
||||
{
|
||||
lu->lu_myreq->lr_active = active;
|
||||
}
|
||||
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2003 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _LOCK_H_
|
||||
#define _LOCK_H_
|
||||
|
||||
struct lockreq;
|
||||
struct lockuser;
|
||||
struct lock;
|
||||
|
||||
enum lock_type {
|
||||
LCK_DEFAULT = 0x0000, /* default is FIFO spin locks */
|
||||
LCK_PRIORITY = 0x0001,
|
||||
LCK_ADAPTIVE = 0x0002 /* call user-supplied handlers */
|
||||
};
|
||||
|
||||
typedef void lock_handler_t(struct lock *, struct lockuser *);
|
||||
|
||||
struct lock {
|
||||
struct lockreq *l_head;
|
||||
struct lockreq *l_tail; /* only used for priority locks */
|
||||
enum lock_type l_type;
|
||||
lock_handler_t *l_wait; /* only used for adaptive locks */
|
||||
lock_handler_t *l_wakeup; /* only used for adaptive locks */
|
||||
};
|
||||
|
||||
/* Try to make this >= CACHELINESIZE */
|
||||
struct lockreq {
|
||||
struct lockuser *lr_watcher; /* only used for priority locks */
|
||||
struct lockuser *lr_owner; /* only used for priority locks */
|
||||
volatile int lr_locked; /* lock granted = 0, busy otherwise */
|
||||
volatile int lr_active; /* non-zero if the lock is last lock for thread */
|
||||
};
|
||||
|
||||
struct lockuser {
|
||||
struct lockreq *lu_myreq; /* request to give up/trade */
|
||||
struct lockreq *lu_watchreq; /* watch this request */
|
||||
int lu_priority; /* only used for priority locks */
|
||||
void *lu_private1; /* private{1,2} are initialized to */
|
||||
void *lu_private2; /* NULL and can be used by caller */
|
||||
#define lu_private lu_private1
|
||||
};
|
||||
|
||||
#define _LCK_INITIALIZER(lck_req) { &lck_req, NULL, LCK_DEFAULT, \
|
||||
NULL, NULL }
|
||||
#define _LCK_REQUEST_INITIALIZER { 0, NULL, NULL, 0 }
|
||||
|
||||
#define _LCK_BUSY(lu) ((lu)->lu_watchreq->lr_locked != 0)
|
||||
#define _LCK_ACTIVE(lu) ((lu)->lu_watchreq->lr_active != 0)
|
||||
#define _LCK_GRANTED(lu) ((lu)->lu_watchreq->lr_locked == 3)
|
||||
|
||||
#define _LCK_SET_PRIVATE(lu, p) (lu)->lu_private = (void *)(p)
|
||||
#define _LCK_GET_PRIVATE(lu) (lu)->lu_private
|
||||
#define _LCK_SET_PRIVATE2(lu, p) (lu)->lu_private2 = (void *)(p)
|
||||
#define _LCK_GET_PRIVATE2(lu) (lu)->lu_private2
|
||||
|
||||
void _lock_acquire(struct lock *, struct lockuser *, int);
|
||||
void _lock_destroy(struct lock *);
|
||||
void _lock_grant(struct lock *, struct lockuser *);
|
||||
int _lock_init(struct lock *, enum lock_type,
|
||||
lock_handler_t *, lock_handler_t *, void *(size_t, size_t));
|
||||
int _lock_reinit(struct lock *, enum lock_type,
|
||||
lock_handler_t *, lock_handler_t *);
|
||||
void _lock_release(struct lock *, struct lockuser *);
|
||||
int _lockuser_init(struct lockuser *lu, void *priv);
|
||||
void _lockuser_destroy(struct lockuser *lu);
|
||||
int _lockuser_reinit(struct lockuser *lu, void *priv);
|
||||
void _lockuser_setactive(struct lockuser *lu, int active);
|
||||
|
||||
#endif
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
|
||||
* Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
|
||||
* 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
|
||||
* and Chris Provenzano.
|
||||
* 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$
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "libc_private.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
#undef errno
|
||||
extern int errno;
|
||||
|
||||
int *
|
||||
__error(void)
|
||||
{
|
||||
struct pthread *curthread;
|
||||
|
||||
if (__isthreaded == 0)
|
||||
return (&errno);
|
||||
else if (_kse_in_critical())
|
||||
return &(_get_curkse()->k_error);
|
||||
else {
|
||||
curthread = _get_curthread();
|
||||
if ((curthread == NULL) || (curthread == _thr_initial))
|
||||
return (&errno);
|
||||
else
|
||||
return (&curthread->error);
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Automated test suite for libpthread (pthreads).
|
||||
#
|
||||
|
||||
# File lists.
|
||||
|
||||
# Tests written in C.
|
||||
CTESTS := hello_d.c hello_s.c join_leak_d.c mutex_d.c sem_d.c sigsuspend_d.c \
|
||||
sigwait_d.c
|
||||
|
||||
# C programs that are used internally by the tests. The build system merely
|
||||
# compiles these.
|
||||
BTESTS := guard_b.c hello_b.c
|
||||
|
||||
# Tests written in perl.
|
||||
PTESTS := guard_s.pl propagate_s.pl
|
||||
|
||||
# Munge the file lists to their final executable names (strip the .c).
|
||||
CTESTS := $(CTESTS:R)
|
||||
BTESTS := $(BTESTS:R)
|
||||
|
||||
CPPFLAGS := -D_LIBC_R_ -D_REENTRANT
|
||||
CFLAGS := -Wall -pipe -g3
|
||||
LDFLAGS_A := -static
|
||||
LDFLAGS_P := -pg
|
||||
LDFLAGS_S :=
|
||||
LIBS := -lpthread
|
||||
|
||||
# Flags passed to verify. "-v" or "-u" may be useful.
|
||||
VERIFY = perl verify
|
||||
VFLAGS :=
|
||||
|
||||
all : default
|
||||
|
||||
# Only use the following suffixes, in order to avoid any strange built-in rules.
|
||||
.SUFFIXES :
|
||||
.SUFFIXES : .c .o .d .pl
|
||||
|
||||
# Clear out all paths, then set just one (default path) for the main build
|
||||
# directory.
|
||||
.PATH :
|
||||
.PATH : .
|
||||
|
||||
# Build the C programs.
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
$(bin)_a : $(bin:S/$/&.c/)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/)
|
||||
$(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_A) $(LIBS)
|
||||
@$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_a.o \2/g\" > $(@:R:S/$/&.d/)"
|
||||
|
||||
$(bin)_p : $(bin:S/$/&.c/)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/)
|
||||
$(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_P) $(LIBS)
|
||||
@$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_p.o \2/g\" > $(@:R:S/$/&.d/)"
|
||||
|
||||
$(bin)_s : $(bin:S/$/&.c/)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/)
|
||||
$(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_S) $(LIBS)
|
||||
@$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_s.o \2/g\" > $(@:R:S/$/&.d/)"
|
||||
.endfor
|
||||
|
||||
# Dependency file inclusion.
|
||||
.for depfile in $(CTESTS:R:S/$/&_a.d/) $(BTESTS:R:S/$/&_a.d/) \
|
||||
$(CTESTS:R:S/$/&_p.d/) $(BTESTS:R:S/$/&_p.d/) \
|
||||
$(CTESTS:R:S/$/&_s.d/) $(BTESTS:R:S/$/&_s.d/)
|
||||
.if exists($(depfile))
|
||||
.include "$(depfile)"
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
default : check
|
||||
|
||||
tests_a : $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/)
|
||||
tests_p : $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/)
|
||||
tests_s : $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/)
|
||||
|
||||
tests : tests_a tests_p tests_s
|
||||
|
||||
check_a : tests_a
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
@cp $(bin)_a $(bin)
|
||||
.endfor
|
||||
@echo "Test static library:"
|
||||
@$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS)
|
||||
|
||||
check_p : tests_p
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
@cp $(bin)_p $(bin)
|
||||
.endfor
|
||||
@echo "Test profile library:"
|
||||
@$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS)
|
||||
|
||||
check_s : tests_s
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
@cp $(bin)_s $(bin)
|
||||
.endfor
|
||||
@echo "Test shared library:"
|
||||
@$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS)
|
||||
|
||||
check : check_a check_p check_s
|
||||
|
||||
clean :
|
||||
rm -f *~
|
||||
rm -f *.core
|
||||
rm -f *.out
|
||||
rm -f *.perf
|
||||
rm -f *.diff
|
||||
rm -f *.gmon
|
||||
rm -f $(CTESTS) $(BTESTS)
|
||||
rm -f $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/)
|
||||
rm -f $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/)
|
||||
rm -f $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/)
|
||||
rm -f *.d
|
||||
rm -f *.o
|
@ -1,28 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
This test suite is meant to test general functionality of pthreads, as well as
|
||||
provide a simple framework for regression tests. In general, this test suite
|
||||
can be used with any pthreads library, but in reality there are a number of
|
||||
libpthread-specific aspects to this test suite which would require some
|
||||
effort to get around if testing another pthreads library.
|
||||
|
||||
This test suite assumes that libpthread is installed.
|
||||
|
||||
There are two forms of test that the 'verify' script understands. The simpler
|
||||
form is the diff format, where the output of the test program is diff'ed with
|
||||
the correspondingly named .exp file. If there is diff output, the test fails.
|
||||
The sequence test format is somewhat more complex, and is documented in the
|
||||
command line usage output for verify. The advantage of this format is that it
|
||||
allows multiple tests to pass/fail within one program.
|
||||
|
||||
There is no driving need for test naming consistency, but the existing tests
|
||||
generally follow these conventions:
|
||||
|
||||
<name>_d.c <name>_d.exp : Diff mode C test and expected output file.
|
||||
<name>_s.c : Sequence mode C test.
|
||||
<name>_b*.c : Back end C program used by perl tests.
|
||||
<name>_d.pl <name>_d.pl.exp : Diff mode perl test and expected output file.
|
||||
<name>_s.pl : Sequence mode perl test.
|
||||
|
||||
<name> is something descriptive, such as "pr14685" in the case of a PR-related
|
||||
regression test, or "mutex" in the case of a test of mutexes.
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 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
|
||||
* unmodified other than the allowable 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$
|
||||
*
|
||||
* Test thread stack guard functionality.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define FRAME_SIZE 1024
|
||||
#define FRAME_OVERHEAD 40
|
||||
|
||||
struct args
|
||||
{
|
||||
void *top; /* Top of thread's initial stack frame. */
|
||||
int cur; /* Recursion depth. */
|
||||
int max; /* Maximum recursion depth. */
|
||||
};
|
||||
|
||||
void *
|
||||
recurse(void *args)
|
||||
{
|
||||
int top;
|
||||
struct args *parms = (struct args *)args;
|
||||
char filler[FRAME_SIZE - FRAME_OVERHEAD];
|
||||
|
||||
/* Touch the memory in this stack frame. */
|
||||
top = 0xa5;
|
||||
memset(filler, 0xa5, sizeof(filler));
|
||||
|
||||
if (parms->top == NULL) {
|
||||
/* Initial stack frame. */
|
||||
parms->top = (void*)⊤
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure frame size is what we expect. Getting this right involves
|
||||
* hand tweaking, so just print a warning rather than aborting.
|
||||
*/
|
||||
if (parms->top - (void *)&top != FRAME_SIZE * parms->cur) {
|
||||
fprintf(stderr,
|
||||
"Stack size (%ld) != expected (%ld), frame %ld\n",
|
||||
(long)parms->top - (long)&top,
|
||||
(long)(FRAME_SIZE * parms->cur), (long)parms->cur);
|
||||
}
|
||||
|
||||
parms->cur++;
|
||||
if (parms->cur < parms->max)
|
||||
recurse(args);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
size_t def_stacksize, def_guardsize;
|
||||
size_t stacksize, guardsize;
|
||||
pthread_t thread;
|
||||
pthread_attr_t attr;
|
||||
struct args args;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: guard_b <stacksize> <guardsize>\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Test begin\n");
|
||||
|
||||
stacksize = strtoul(argv[1], NULL, 10);
|
||||
guardsize = strtoul(argv[2], NULL, 10);
|
||||
|
||||
assert(pthread_attr_init(&attr) == 0);
|
||||
/*
|
||||
* Exercise the attribute APIs more thoroughly than is strictly
|
||||
* necessary for the meat of this test program.
|
||||
*/
|
||||
assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0);
|
||||
assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0);
|
||||
if (def_stacksize != stacksize) {
|
||||
assert(pthread_attr_setstacksize(&attr, stacksize) == 0);
|
||||
assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0);
|
||||
assert(def_stacksize == stacksize);
|
||||
}
|
||||
if (def_guardsize != guardsize) {
|
||||
assert(pthread_attr_setguardsize(&attr, guardsize) == 0);
|
||||
assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0);
|
||||
assert(def_guardsize >= guardsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a thread that will come just short of overflowing the thread
|
||||
* stack. We need to leave a bit of breathing room in case the thread
|
||||
* is context switched, and we also have to take care not to call any
|
||||
* functions in the deepest stack frame.
|
||||
*/
|
||||
args.top = NULL;
|
||||
args.cur = 0;
|
||||
args.max = (stacksize / FRAME_SIZE) - 1;
|
||||
fprintf(stderr, "No overflow:\n");
|
||||
assert(pthread_create(&thread, &attr, recurse, &args) == 0);
|
||||
assert(pthread_join(thread, NULL) == 0);
|
||||
|
||||
/*
|
||||
* Create a thread that will barely of overflow the thread stack. This
|
||||
* should cause a segfault.
|
||||
*/
|
||||
args.top = NULL;
|
||||
args.cur = 0;
|
||||
args.max = (stacksize / FRAME_SIZE) + 1;
|
||||
fprintf(stderr, "Overflow:\n");
|
||||
assert(pthread_create(&thread, &attr, recurse, &args) == 0);
|
||||
assert(pthread_join(thread, NULL) == 0);
|
||||
|
||||
/* Not reached. */
|
||||
fprintf(stderr, "Unexpected success\n");
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
# $FreeBSD$
|
||||
Test begin
|
||||
No overflow:
|
||||
Overflow:
|
@ -1,69 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Copyright (C) 2001 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
|
||||
# unmodified other than the allowable 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$
|
||||
#
|
||||
# Test thread stack guard functionality. The C test program needs to be driven
|
||||
# by this script because it segfaults when the stack guard is hit.
|
||||
#
|
||||
|
||||
print "1..30\n";
|
||||
|
||||
$i = 0;
|
||||
# Iterates 10 times.
|
||||
for ($stacksize = 65536; $stacksize < 131072; $stacksize += 7168)
|
||||
{
|
||||
# Iterates 3 times (1024, 4096, 7168).
|
||||
for ($guardsize = 1024; $guardsize < 8192; $guardsize += 3072)
|
||||
{
|
||||
$i++;
|
||||
|
||||
print "stacksize: $stacksize, guardsize: $guardsize\n";
|
||||
|
||||
`./guard_b $stacksize $guardsize >guard_b.out 2>&1`;
|
||||
|
||||
if (! -f "./guard_b.out")
|
||||
{
|
||||
print "not ok $i\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
`diff guard_b.exp guard_b.out >guard_b.diff 2>&1`;
|
||||
if ($?)
|
||||
{
|
||||
# diff returns non-zero if there is a difference.
|
||||
print "not ok $i\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "ok $i\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Back end C programs can be anything compilable.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Simple diff mode test.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void *
|
||||
entry(void * a_arg)
|
||||
{
|
||||
fprintf(stderr, "Hello world\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
pthread_t thread;
|
||||
int error;
|
||||
|
||||
error = pthread_create(&thread, NULL, entry, NULL);
|
||||
if (error)
|
||||
fprintf(stderr, "Error in pthread_create(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
error = pthread_join(thread, NULL);
|
||||
if (error)
|
||||
fprintf(stderr, "Error in pthread_join(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
# $FreeBSD$
|
||||
Hello world
|
@ -1,47 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Simple sequence mode test.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void *
|
||||
entry(void * a_arg)
|
||||
{
|
||||
fprintf(stderr, "ok 1\n");
|
||||
fprintf(stderr, "ok \n");
|
||||
fprintf(stderr, "ok 3\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
pthread_t thread;
|
||||
int error;
|
||||
|
||||
fprintf(stderr, "1..3\n");
|
||||
|
||||
fprintf(stderr, "Some random text\n");
|
||||
|
||||
error = pthread_create(&thread, NULL, entry, NULL);
|
||||
fprintf(stderr, "More unimportant text\n");
|
||||
if (error)
|
||||
fprintf(stderr,"Error in pthread_create(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
error = pthread_join(thread, NULL);
|
||||
if (error)
|
||||
fprintf(stderr, "Error in pthread_join(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
fprintf(stderr, "Hello world\n");
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 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$
|
||||
*
|
||||
* Test for leaked joined threads.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define NITERATIONS 16384
|
||||
#define MAXGROWTH 16384
|
||||
|
||||
void *
|
||||
thread_entry(void *a_arg)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
pthread_t thread;
|
||||
int i, error;
|
||||
char *brk, *nbrk;
|
||||
unsigned growth;
|
||||
|
||||
fprintf(stderr, "Test begin\n");
|
||||
|
||||
/* Get an initial brk value. */
|
||||
brk = sbrk(0);
|
||||
|
||||
/* Create threads and join them, one at a time. */
|
||||
for (i = 0; i < NITERATIONS; i++) {
|
||||
if ((error = pthread_create(&thread, NULL, thread_entry, NULL))
|
||||
!= 0) {
|
||||
fprintf(stderr, "Error in pthread_create(): %s\n",
|
||||
strerror(error));
|
||||
exit(1);
|
||||
}
|
||||
if ((error = pthread_join(thread, NULL)) != 0) {
|
||||
fprintf(stderr, "Error in pthread_join(): %s\n",
|
||||
strerror(error));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a final brk value. */
|
||||
nbrk = sbrk(0);
|
||||
|
||||
/*
|
||||
* Check that the amount of heap space allocated is below an acceptable
|
||||
* threshold. We could just compare brk and nbrk, but the test could
|
||||
* conceivably break if the internals of the threads library changes.
|
||||
*/
|
||||
if (nbrk > brk) {
|
||||
/* Heap grows up. */
|
||||
growth = nbrk - brk;
|
||||
} else if (nbrk <= brk) {
|
||||
/* Heap grows down, or no growth. */
|
||||
growth = brk - nbrk;
|
||||
}
|
||||
|
||||
if (growth > MAXGROWTH) {
|
||||
fprintf(stderr, "Heap growth exceeded maximum (%u > %u)\n",
|
||||
growth, MAXGROWTH);
|
||||
}
|
||||
#if (0)
|
||||
else {
|
||||
fprintf(stderr, "Heap growth acceptable (%u <= %u)\n",
|
||||
growth, MAXGROWTH);
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "Test end\n");
|
||||
return 0;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
# $FreeBSD$
|
||||
Test begin
|
||||
Test end
|
File diff suppressed because it is too large
Load Diff
@ -1,291 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
Testing pthread_mutex_init
|
||||
--------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS
|
||||
|
||||
Testing pthread_mutex_destroy
|
||||
-----------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified)
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
|
||||
Testing pthread_mutex_lock
|
||||
--------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified)
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
|
||||
Testing pthread_mutex_unlock
|
||||
----------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified)
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
|
||||
Testing queueing order
|
||||
----------------------
|
||||
Queueing order on a mutex - PASS
|
||||
Queueing order on a condition variable - PASS
|
||||
|
||||
Testing priority inheritence
|
||||
----------------------------
|
||||
Protype PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
|
||||
Testing priority ceilings
|
||||
-------------------------
|
||||
Protype PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
|
||||
Total tests 212, passed 212, failed 0
|
@ -1,74 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
###########################################################################
|
||||
#
|
||||
# Verify that no cancellation points are propagated inside of libpthread.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
@CPOINTS = ("aio_suspend", "close", "creat", "fcntl", "fsync", "mq_receive",
|
||||
"mq_send", "msync", "nanosleep", "open", "pause",
|
||||
"pthread_cond_timedwait", "pthread_cond_wait", "pthread_join",
|
||||
"pthread_testcancel", "read", "sem_wait", "sigsuspend",
|
||||
"sigtimedwait", "sigwait", "sigwaitinfo", "sleep", "system",
|
||||
"tcdrain", "wait", "waitpid", "write");
|
||||
|
||||
print "1..1\n";
|
||||
|
||||
$cpoints = join '\|', @CPOINTS;
|
||||
$regexp = "\" U \\(" . $cpoints . "\\\)\$\"";
|
||||
|
||||
`nm -a /usr/lib/libc.a |grep $regexp >propagate_s.out`;
|
||||
if (!open (NMOUT, "<./propagate_s.out"))
|
||||
{
|
||||
print "not ok 1\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$propagations = 0;
|
||||
|
||||
while (<NMOUT>)
|
||||
{
|
||||
$propagations++;
|
||||
print "$_\n";
|
||||
}
|
||||
if ($propagations != 0)
|
||||
{
|
||||
print "$propagations propagation(s)\n";
|
||||
print "not ok 1\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "ok 1\n";
|
||||
}
|
||||
close NMOUT;
|
||||
unlink "propagate_s.out";
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* sem test.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define NTHREADS 10
|
||||
|
||||
void *
|
||||
entry(void * a_arg)
|
||||
{
|
||||
sem_t * sem = (sem_t *) a_arg;
|
||||
|
||||
sem_wait(sem);
|
||||
fprintf(stderr, "Got semaphore\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
sem_t sem_a, sem_b;
|
||||
pthread_t threads[NTHREADS];
|
||||
unsigned i;
|
||||
int val;
|
||||
|
||||
fprintf(stderr, "Test begin\n");
|
||||
|
||||
#ifdef _LIBC_R_
|
||||
assert(-1 == sem_init(&sem_b, 1, 0));
|
||||
assert(EPERM == errno);
|
||||
#endif
|
||||
|
||||
assert(0 == sem_init(&sem_b, 0, 0));
|
||||
assert(0 == sem_getvalue(&sem_b, &val));
|
||||
assert(0 == val);
|
||||
|
||||
assert(0 == sem_post(&sem_b));
|
||||
assert(0 == sem_getvalue(&sem_b, &val));
|
||||
assert(1 == val);
|
||||
|
||||
assert(0 == sem_wait(&sem_b));
|
||||
assert(-1 == sem_trywait(&sem_b));
|
||||
assert(EAGAIN == errno);
|
||||
assert(0 == sem_post(&sem_b));
|
||||
assert(0 == sem_trywait(&sem_b));
|
||||
assert(0 == sem_post(&sem_b));
|
||||
assert(0 == sem_wait(&sem_b));
|
||||
assert(0 == sem_post(&sem_b));
|
||||
|
||||
#ifdef _LIBC_R_
|
||||
assert(SEM_FAILED == sem_open("/foo", O_CREAT | O_EXCL, 0644, 0));
|
||||
assert(ENOSYS == errno);
|
||||
|
||||
assert(-1 == sem_close(&sem_b));
|
||||
assert(ENOSYS == errno);
|
||||
|
||||
assert(-1 == sem_unlink("/foo"));
|
||||
assert(ENOSYS == errno);
|
||||
#endif
|
||||
|
||||
assert(0 == sem_destroy(&sem_b));
|
||||
|
||||
assert(0 == sem_init(&sem_a, 0, 0));
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_create(&threads[i], NULL, entry, (void *) &sem_a);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
assert(0 == sem_post(&sem_a));
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_create(&threads[i], NULL, entry, (void *) &sem_a);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
assert(0 == sem_post(&sem_a));
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
assert(0 == sem_destroy(&sem_a));
|
||||
|
||||
fprintf(stderr, "Test end\n");
|
||||
return 0;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
# $FreeBSD$
|
||||
Test begin
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Test end
|
@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel M. Eischen.
|
||||
* 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 DANIEL M. EISCHEN 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$
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_LIBC_R_)
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
static int sigcounts[NSIG + 1];
|
||||
static int sigfifo[NSIG + 1];
|
||||
static int fifo_depth = 0;
|
||||
static sigset_t suspender_mask;
|
||||
static pthread_t suspender_tid;
|
||||
|
||||
|
||||
static void *
|
||||
sigsuspender (void *arg)
|
||||
{
|
||||
int save_count, status, i;
|
||||
sigset_t run_mask;
|
||||
|
||||
/* Run with all signals blocked. */
|
||||
sigfillset (&run_mask);
|
||||
sigprocmask (SIG_SETMASK, &run_mask, NULL);
|
||||
|
||||
/* Allow these signals to wake us up during a sigsuspend. */
|
||||
sigfillset (&suspender_mask); /* Default action */
|
||||
sigdelset (&suspender_mask, SIGKILL); /* Cannot catch */
|
||||
sigdelset (&suspender_mask, SIGSTOP); /* Cannot catch */
|
||||
sigdelset (&suspender_mask, SIGINT); /* terminate */
|
||||
sigdelset (&suspender_mask, SIGHUP); /* terminate */
|
||||
sigdelset (&suspender_mask, SIGQUIT); /* create core image */
|
||||
sigdelset (&suspender_mask, SIGURG); /* ignore */
|
||||
sigdelset (&suspender_mask, SIGIO); /* ignore */
|
||||
sigdelset (&suspender_mask, SIGUSR2); /* terminate */
|
||||
|
||||
while (sigcounts[SIGINT] == 0) {
|
||||
save_count = sigcounts[SIGUSR2];
|
||||
|
||||
status = sigsuspend (&suspender_mask);
|
||||
if ((status == 0) || (errno != EINTR)) {
|
||||
fprintf (stderr, "Unable to suspend for signals, "
|
||||
"errno %d, return value %d\n",
|
||||
errno, status);
|
||||
exit (1);
|
||||
}
|
||||
for (i = 0; i < fifo_depth; i++)
|
||||
fprintf (stderr, "Sigsuspend woke up by signal %d\n",
|
||||
sigfifo[i]);
|
||||
fifo_depth = 0;
|
||||
}
|
||||
|
||||
pthread_exit (arg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sighandler (int signo)
|
||||
{
|
||||
sigset_t set, suspend_set;
|
||||
pthread_t self;
|
||||
|
||||
if ((signo >= 0) && (signo <= NSIG))
|
||||
sigcounts[signo]++;
|
||||
|
||||
/*
|
||||
* If we are running on behalf of the suspender thread,
|
||||
* ensure that we have the correct mask set.
|
||||
*/
|
||||
self = pthread_self ();
|
||||
if (self == suspender_tid) {
|
||||
sigfifo[fifo_depth] = signo;
|
||||
fifo_depth++;
|
||||
fprintf (stderr,
|
||||
" -> Suspender thread signal handler caught signal %d\n",
|
||||
signo);
|
||||
|
||||
/* Get the current signal mask. */
|
||||
sigprocmask (SIG_SETMASK, NULL, &set);
|
||||
|
||||
/* The handler should run with the current signal masked. */
|
||||
suspend_set = suspender_mask;
|
||||
sigaddset(&suspend_set, signo);
|
||||
|
||||
if (memcmp(&set, &suspend_set, sizeof(set)))
|
||||
fprintf (stderr,
|
||||
" >>> FAIL: sigsuspender signal handler running "
|
||||
"with incorrect mask.\n");
|
||||
}
|
||||
else
|
||||
fprintf (stderr,
|
||||
" -> Main thread signal handler caught signal %d\n",
|
||||
signo);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_thread_signal (pthread_t tid, int signo)
|
||||
{
|
||||
if (pthread_kill (tid, signo) != 0) {
|
||||
fprintf (stderr, "Unable to send thread signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_process_signal (int signo)
|
||||
{
|
||||
if (kill (getpid (), signo) != 0) {
|
||||
fprintf (stderr, "Unable to send process signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
pthread_attr_t pattr;
|
||||
void * exit_status;
|
||||
struct sigaction act;
|
||||
sigset_t oldset;
|
||||
sigset_t newset;
|
||||
|
||||
/* Initialize our signal counts. */
|
||||
memset ((void *) sigcounts, 0, NSIG * sizeof (int));
|
||||
|
||||
/* Ignore signal SIGIO. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGIO);
|
||||
act.sa_handler = SIG_IGN;
|
||||
act.sa_flags = 0;
|
||||
sigaction (SIGIO, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGURG. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGURG);
|
||||
act.sa_handler = sighandler;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction (SIGURG, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGXCPU */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGXCPU);
|
||||
sigaction (SIGXCPU, &act, NULL);
|
||||
|
||||
/* Get our current signal mask. */
|
||||
sigprocmask (SIG_SETMASK, NULL, &oldset);
|
||||
|
||||
/* Mask out SIGUSR1 and SIGUSR2. */
|
||||
newset = oldset;
|
||||
sigaddset (&newset, SIGUSR1);
|
||||
sigaddset (&newset, SIGUSR2);
|
||||
sigprocmask (SIG_SETMASK, &newset, NULL);
|
||||
|
||||
/* Install a signal handler for SIGUSR1 */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGUSR1);
|
||||
sigaction (SIGUSR1, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGUSR2 */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGUSR2);
|
||||
sigaction (SIGUSR2, &act, NULL);
|
||||
|
||||
/*
|
||||
* Initialize the thread attribute.
|
||||
*/
|
||||
if ((pthread_attr_init (&pattr) != 0) ||
|
||||
(pthread_attr_setdetachstate (&pattr,
|
||||
PTHREAD_CREATE_JOINABLE) != 0)) {
|
||||
fprintf (stderr, "Unable to initialize thread attributes.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the sigsuspender thread.
|
||||
*/
|
||||
if (pthread_create (&suspender_tid, &pattr, sigsuspender, NULL) != 0) {
|
||||
fprintf (stderr, "Unable to create thread, errno %d.\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
#if defined(_LIBC_R_)
|
||||
pthread_set_name_np (suspender_tid, "sigsuspender");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Verify that an ignored signal doesn't cause a wakeup.
|
||||
* We don't have a handler installed for SIGIO.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGIO);
|
||||
sleep (1);
|
||||
send_process_signal (SIGIO);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGIO] != 0)
|
||||
fprintf (stderr, "FAIL: sigsuspend wakes up for ignored signal "
|
||||
"SIGIO.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal with a default action of ignore, for
|
||||
* which we have a signal handler installed, will release a
|
||||
* sigsuspend.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGURG);
|
||||
sleep (1);
|
||||
send_process_signal (SIGURG);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGURG] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigsuspend doesn't wake up for SIGURG.\n");
|
||||
|
||||
/*
|
||||
* Verify that a SIGUSR2 signal will release a sigsuspended
|
||||
* thread.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGUSR2);
|
||||
sleep (1);
|
||||
send_process_signal (SIGUSR2);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR2] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigsuspend doesn't wake up for SIGUSR2.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal, blocked in both the main and
|
||||
* sigsuspender threads, does not cause the signal handler
|
||||
* to be called.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGUSR1);
|
||||
sleep (1);
|
||||
send_process_signal (SIGUSR1);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 0)
|
||||
fprintf (stderr, "FAIL: signal hander called for SIGUSR1.\n");
|
||||
|
||||
/*
|
||||
* Verify that we can still kill the process for a signal
|
||||
* not being waited on by sigwait.
|
||||
*/
|
||||
send_process_signal (SIGPIPE);
|
||||
fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n");
|
||||
|
||||
/*
|
||||
* Wait for the thread to finish.
|
||||
*/
|
||||
pthread_join (suspender_tid, &exit_status);
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# $FreeBSD$
|
||||
-> Suspender thread signal handler caught signal 16
|
||||
Sigsuspend woke up by signal 16
|
||||
-> Suspender thread signal handler caught signal 16
|
||||
Sigsuspend woke up by signal 16
|
||||
-> Suspender thread signal handler caught signal 31
|
||||
Sigsuspend woke up by signal 31
|
||||
-> Suspender thread signal handler caught signal 31
|
||||
Sigsuspend woke up by signal 31
|
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel M. Eischen.
|
||||
* 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 DANIEL M. EISCHEN 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$
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_LIBC_R_)
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
static int sigcounts[NSIG + 1];
|
||||
static sigset_t wait_mask;
|
||||
static pthread_mutex_t waiter_mutex;
|
||||
|
||||
|
||||
static void *
|
||||
sigwaiter (void *arg)
|
||||
{
|
||||
int signo;
|
||||
sigset_t mask;
|
||||
|
||||
/* Block SIGHUP */
|
||||
sigemptyset (&mask);
|
||||
sigaddset (&mask, SIGHUP);
|
||||
sigprocmask (SIG_BLOCK, &mask, NULL);
|
||||
|
||||
while (sigcounts[SIGINT] == 0) {
|
||||
if (sigwait (&wait_mask, &signo) != 0) {
|
||||
fprintf (stderr,
|
||||
"Unable to wait for signal, errno %d\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
sigcounts[signo]++;
|
||||
fprintf (stderr, "Sigwait caught signal %d\n", signo);
|
||||
|
||||
/* Allow the main thread to prevent the sigwait. */
|
||||
pthread_mutex_lock (&waiter_mutex);
|
||||
pthread_mutex_unlock (&waiter_mutex);
|
||||
}
|
||||
|
||||
pthread_exit (arg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sighandler (int signo)
|
||||
{
|
||||
fprintf (stderr, " -> Signal handler caught signal %d\n", signo);
|
||||
|
||||
if ((signo >= 0) && (signo <= NSIG))
|
||||
sigcounts[signo]++;
|
||||
}
|
||||
|
||||
static void
|
||||
send_thread_signal (pthread_t tid, int signo)
|
||||
{
|
||||
if (pthread_kill (tid, signo) != 0) {
|
||||
fprintf (stderr, "Unable to send thread signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
send_process_signal (int signo)
|
||||
{
|
||||
if (kill (getpid (), signo) != 0) {
|
||||
fprintf (stderr, "Unable to send process signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
pthread_mutexattr_t mattr;
|
||||
pthread_attr_t pattr;
|
||||
pthread_t tid;
|
||||
void * exit_status;
|
||||
struct sigaction act;
|
||||
|
||||
/* Initialize our signal counts. */
|
||||
memset ((void *) sigcounts, 0, NSIG * sizeof (int));
|
||||
|
||||
/* Setup our wait mask. */
|
||||
sigemptyset (&wait_mask); /* Default action */
|
||||
sigaddset (&wait_mask, SIGHUP); /* terminate */
|
||||
sigaddset (&wait_mask, SIGINT); /* terminate */
|
||||
sigaddset (&wait_mask, SIGQUIT); /* create core image */
|
||||
sigaddset (&wait_mask, SIGURG); /* ignore */
|
||||
sigaddset (&wait_mask, SIGIO); /* ignore */
|
||||
sigaddset (&wait_mask, SIGUSR1); /* terminate */
|
||||
|
||||
/* Ignore signals SIGHUP and SIGIO. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGHUP);
|
||||
sigaddset (&act.sa_mask, SIGIO);
|
||||
act.sa_handler = SIG_IGN;
|
||||
act.sa_flags = 0;
|
||||
sigaction (SIGHUP, &act, NULL);
|
||||
sigaction (SIGIO, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGURG */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGURG);
|
||||
act.sa_handler = sighandler;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction (SIGURG, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGXCPU */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGXCPU);
|
||||
sigaction (SIGXCPU, &act, NULL);
|
||||
|
||||
/*
|
||||
* Initialize the thread attribute.
|
||||
*/
|
||||
if ((pthread_attr_init (&pattr) != 0) ||
|
||||
(pthread_attr_setdetachstate (&pattr,
|
||||
PTHREAD_CREATE_JOINABLE) != 0)) {
|
||||
fprintf (stderr, "Unable to initialize thread attributes.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize and create a mutex.
|
||||
*/
|
||||
if ((pthread_mutexattr_init (&mattr) != 0) ||
|
||||
(pthread_mutex_init (&waiter_mutex, &mattr) != 0)) {
|
||||
fprintf (stderr, "Unable to create waiter mutex.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the sigwaiter thread.
|
||||
*/
|
||||
if (pthread_create (&tid, &pattr, sigwaiter, NULL) != 0) {
|
||||
fprintf (stderr, "Unable to create thread.\n");
|
||||
exit (1);
|
||||
}
|
||||
#if defined(_LIBC_R_)
|
||||
pthread_set_name_np (tid, "sigwaiter");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Verify that an ignored signal doesn't cause a wakeup.
|
||||
* We don't have a handler installed for SIGIO.
|
||||
*/
|
||||
send_thread_signal (tid, SIGIO);
|
||||
sleep (1);
|
||||
send_process_signal (SIGIO);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGIO] != 0)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait wakes up for ignored signal SIGIO.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal with a default action of ignore, for
|
||||
* which we have a signal handler installed, will release a sigwait.
|
||||
*/
|
||||
send_thread_signal (tid, SIGURG);
|
||||
sleep (1);
|
||||
send_process_signal (SIGURG);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGURG] != 2)
|
||||
fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGURG.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal with a default action that terminates
|
||||
* the process will release a sigwait.
|
||||
*/
|
||||
send_thread_signal (tid, SIGUSR1);
|
||||
sleep (1);
|
||||
send_process_signal (SIGUSR1);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't wake up for SIGUSR1.\n");
|
||||
|
||||
/*
|
||||
* Verify that if we install a signal handler for a previously
|
||||
* ignored signal, an occurrence of this signal will release
|
||||
* the (already waiting) sigwait.
|
||||
*/
|
||||
|
||||
/* Install a signal handler for SIGHUP. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGHUP);
|
||||
act.sa_handler = sighandler;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction (SIGHUP, &act, NULL);
|
||||
|
||||
/* Sending SIGHUP should release the sigwait. */
|
||||
send_process_signal (SIGHUP);
|
||||
sleep (1);
|
||||
send_thread_signal (tid, SIGHUP);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGHUP] != 2)
|
||||
fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n");
|
||||
|
||||
/*
|
||||
* Verify that a pending signal in the waiters mask will
|
||||
* cause sigwait to return the pending signal. We do this
|
||||
* by taking the waiters mutex and signaling the waiter to
|
||||
* release him from the sigwait. The waiter will block
|
||||
* on taking the mutex, and we can then send the waiter a
|
||||
* signal which should be added to his pending signals.
|
||||
* The next time the waiter does a sigwait, he should
|
||||
* return with the pending signal.
|
||||
*/
|
||||
sigcounts[SIGHUP] = 0;
|
||||
pthread_mutex_lock (&waiter_mutex);
|
||||
/* Release the waiter from sigwait. */
|
||||
send_process_signal (SIGHUP);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGHUP] != 1)
|
||||
fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n");
|
||||
/*
|
||||
* Add SIGHUP to the process pending signals. Since there is
|
||||
* a signal handler installed for SIGHUP and this signal is
|
||||
* blocked from the waiter thread and unblocked in the main
|
||||
* thread, the signal handler should be called once for SIGHUP.
|
||||
*/
|
||||
send_process_signal (SIGHUP);
|
||||
/* Release the waiter thread and allow him to run. */
|
||||
pthread_mutex_unlock (&waiter_mutex);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGHUP] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't return for pending SIGHUP.\n");
|
||||
|
||||
/*
|
||||
* Repeat the above test using pthread_kill and SIGUSR1.
|
||||
*/
|
||||
sigcounts[SIGUSR1] = 0;
|
||||
pthread_mutex_lock (&waiter_mutex);
|
||||
/* Release the waiter from sigwait. */
|
||||
send_thread_signal (tid, SIGUSR1);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 1)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't wake up for SIGUSR1.\n");
|
||||
/* Add SIGUSR1 to the waiters pending signals. */
|
||||
send_thread_signal (tid, SIGUSR1);
|
||||
/* Release the waiter thread and allow him to run. */
|
||||
pthread_mutex_unlock (&waiter_mutex);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't return for pending SIGUSR1.\n");
|
||||
|
||||
/*
|
||||
* Verify that we can still kill the process for a signal
|
||||
* not being waited on by sigwait.
|
||||
*/
|
||||
send_process_signal (SIGPIPE);
|
||||
fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n");
|
||||
|
||||
/*
|
||||
* Wait for the thread to finish.
|
||||
*/
|
||||
pthread_join (tid, &exit_status);
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
# $FreeBSD$
|
||||
Sigwait caught signal 16
|
||||
Sigwait caught signal 16
|
||||
Sigwait caught signal 30
|
||||
Sigwait caught signal 30
|
||||
Sigwait caught signal 1
|
||||
Sigwait caught signal 1
|
||||
Sigwait caught signal 1
|
||||
-> Signal handler caught signal 1
|
||||
Sigwait caught signal 30
|
||||
Sigwait caught signal 30
|
@ -1,474 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#-*-mode:perl-*-
|
||||
#############################################################################
|
||||
#
|
||||
# Copyright (C) 1999-2001 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.
|
||||
#
|
||||
#############################################################################
|
||||
#
|
||||
# Test harness.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
# Shut off buffering.
|
||||
select(STDOUT);
|
||||
$| = 1;
|
||||
|
||||
#
|
||||
# Parse command-line arguments.
|
||||
#
|
||||
use Getopt::Long;
|
||||
Getopt::Long::config("bundling"); # Allow -hv rather than forcing -h -v.
|
||||
|
||||
# Set option defaults for optional arguments.
|
||||
$opt_help = 0;
|
||||
$opt_verbose = 0;
|
||||
$opt_quiet = 0;
|
||||
$opt_srcdir = ".";
|
||||
$opt_objdir = ".";
|
||||
$opt_ustats = 0;
|
||||
$opt_zero = 0;
|
||||
|
||||
$opt_retval =
|
||||
&GetOptions("h|help" => \$opt_help,
|
||||
"v|verbose" => \$opt_verbose,
|
||||
"q|quiet" => \$opt_quiet,
|
||||
"s|srcdir=s" => \$opt_srcdir,
|
||||
"o|objdir=s" => \$opt_objdir,
|
||||
"u|ustats" => \$opt_ustats,
|
||||
"z|zero" => \$opt_zero
|
||||
);
|
||||
|
||||
if ($opt_help)
|
||||
{
|
||||
&usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($opt_retval == 0)
|
||||
{
|
||||
&usage();
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ($opt_verbose && $opt_quiet)
|
||||
{
|
||||
print STDERR "-v and -q are incompatible\n";
|
||||
&usage();
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ($#ARGV + 1 == 0)
|
||||
{
|
||||
print STDERR "No tests specified\n";
|
||||
&usage();
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ($opt_verbose)
|
||||
{
|
||||
print STDERR "Option values: h:$opt_help, v:$opt_verbose, "
|
||||
. "s:\"$opt_srcdir\", o:\"$opt_objdir\" "
|
||||
. "q:$opt_quiet, u:$opt_ustats, z:$opt_zero\n";
|
||||
printf STDERR "Tests (%d total): @ARGV\n", $#ARGV + 1;
|
||||
}
|
||||
|
||||
#
|
||||
# Create and print header.
|
||||
#
|
||||
@TSTATS =
|
||||
(
|
||||
"--------------------------------------------------------------------------\n",
|
||||
"Test c_user c_system c_total chng\n",
|
||||
" passed/FAILED h_user h_system h_total %% chng\n"
|
||||
);
|
||||
|
||||
if (!$opt_quiet)
|
||||
{
|
||||
foreach $line (@TSTATS)
|
||||
{
|
||||
printf STDOUT "$line";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Run sequence test(s).
|
||||
#
|
||||
$total_utime = 0.0; # Total user time.
|
||||
$total_stime = 0.0; # Total system time.
|
||||
$total_hutime = 0.0; # Total historical user time.
|
||||
$total_hstime = 0.0; # Total historical system time.
|
||||
$total_ntime = 0.0; # Total time for tests that have historical data.
|
||||
|
||||
foreach $test (@ARGV)
|
||||
{
|
||||
# Strip out any whitespace in $test.
|
||||
$test =~ s/^\s*(.*)\s*$/$1/;
|
||||
|
||||
$okay = 1;
|
||||
|
||||
if (-e "$opt_srcdir/$test.exp")
|
||||
{
|
||||
# Diff mode.
|
||||
|
||||
($okay, $utime, $stime) = &run_test($test);
|
||||
|
||||
if (-e "$opt_objdir/$test.out")
|
||||
{
|
||||
`diff $opt_srcdir/$test.exp $opt_objdir/$test.out > $opt_objdir/$test.diff 2>&1`;
|
||||
if ($?)
|
||||
{
|
||||
# diff returns non-zero if there is a difference.
|
||||
$okay = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$okay = 0;
|
||||
if ($opt_verbose)
|
||||
{
|
||||
print STDERR
|
||||
"Nonexistent output file \"$opt_objdir/$test.out\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
($hutime, $hstime) = &print_stats($test, $okay, 0, 0, $utime, $stime);
|
||||
}
|
||||
else
|
||||
{
|
||||
# Sequence mode.
|
||||
|
||||
($okay, $utime, $stime) = &run_test($test);
|
||||
|
||||
if (open (STEST_OUT, "<$opt_objdir/$test.out"))
|
||||
{
|
||||
$num_subtests = 0;
|
||||
$num_failed_subtests = 0;
|
||||
|
||||
while (defined($line = <STEST_OUT>))
|
||||
{
|
||||
if ($line =~ /1\.\.(\d+)/)
|
||||
{
|
||||
$num_subtests = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($num_subtests == 0)
|
||||
{
|
||||
$okay = 0;
|
||||
if ($opt_verbose)
|
||||
{
|
||||
print STDERR "Malformed or missing 1..n line\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($subtest = 1; $subtest <= $num_subtests; $subtest++)
|
||||
{
|
||||
while (defined($line = <STEST_OUT>))
|
||||
{
|
||||
if ($line =~ /^not\s+ok\s+(\d+)?/)
|
||||
{
|
||||
$not = 1;
|
||||
$test_num = $1;
|
||||
last;
|
||||
}
|
||||
elsif ($line =~ /^ok\s+(\d+)?/)
|
||||
{
|
||||
$not = 0;
|
||||
$test_num = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if (defined($line))
|
||||
{
|
||||
if (defined($test_num) && ($test_num != $subtest))
|
||||
{
|
||||
# There was no output printed for one or more tests.
|
||||
for (; $subtest < $test_num; $subtest++)
|
||||
{
|
||||
$num_failed_subtests++;
|
||||
}
|
||||
}
|
||||
if ($not)
|
||||
{
|
||||
$num_failed_subtests++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; $subtest <= $num_subtests; $subtest++)
|
||||
{
|
||||
$num_failed_subtests++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < $num_failed_subtests)
|
||||
{
|
||||
$okay = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$opt_quiet)
|
||||
{
|
||||
print STDERR "Cannot open output file \"$opt_objdir/$test.out\"\n";
|
||||
}
|
||||
exit 1;
|
||||
}
|
||||
|
||||
($hutime, $hstime) = &print_stats($test, $okay,
|
||||
$num_failed_subtests, $num_subtests,
|
||||
$utime, $stime);
|
||||
}
|
||||
|
||||
$total_hutime += $hutime;
|
||||
$total_hstime += $hstime;
|
||||
|
||||
if ($okay)
|
||||
{
|
||||
$total_utime += $utime;
|
||||
$total_stime += $stime;
|
||||
}
|
||||
else
|
||||
{
|
||||
@FAILED_TESTS = (@FAILED_TESTS, $test);
|
||||
}
|
||||
|
||||
# If there were historical data, add the run time to the total time to
|
||||
# compare against the historical run time.
|
||||
if (0 < ($hutime + $hstime))
|
||||
{
|
||||
$total_ntime += $utime + $stime;
|
||||
}
|
||||
}
|
||||
|
||||
# Print summary stats.
|
||||
$tt_str = sprintf ("%d / %d passed (%5.2f%%%%)",
|
||||
($#ARGV + 1) - ($#FAILED_TESTS + 1),
|
||||
$#ARGV + 1,
|
||||
(($#ARGV + 1) - ($#FAILED_TESTS + 1))
|
||||
/ ($#ARGV + 1) * 100);
|
||||
|
||||
$t_str = sprintf ("Totals %7.2f %7.2f %7.2f"
|
||||
. " %7.2f\n"
|
||||
. " %s %7.2f %7.2f %7.2f %7.2f%%%%\n",
|
||||
$total_utime, $total_stime, $total_utime + $total_stime,
|
||||
($total_ntime - ($total_hutime + $total_hstime)),
|
||||
$tt_str . ' ' x (40 - length($tt_str)),
|
||||
$total_hutime, $total_hstime, $total_hutime + $total_hstime,
|
||||
($total_hutime + $total_hstime == 0.0) ? 0.0 :
|
||||
(($total_ntime
|
||||
- ($total_hutime + $total_hstime))
|
||||
/ ($total_hutime + $total_hstime) * 100));
|
||||
|
||||
@TSTATS = ("--------------------------------------------------------------------------\n",
|
||||
$t_str,
|
||||
"--------------------------------------------------------------------------\n"
|
||||
);
|
||||
if (!$opt_quiet)
|
||||
{
|
||||
foreach $line (@TSTATS)
|
||||
{
|
||||
printf STDOUT "$line";
|
||||
}
|
||||
}
|
||||
|
||||
if ($#FAILED_TESTS >= 0)
|
||||
{
|
||||
# One or more tests failed, so return an error.
|
||||
exit 1;
|
||||
}
|
||||
# End of main execution.
|
||||
|
||||
sub run_test
|
||||
{
|
||||
my ($test) = @_;
|
||||
my ($okay) = 1;
|
||||
my ($tutime, $tstime);
|
||||
my ($utime, $stime, $cutime, $cstime);
|
||||
my (@TSTATS, @TPATH);
|
||||
my ($t_str);
|
||||
my ($srcdir, $objdir);
|
||||
|
||||
# Get the path component of $test, if any.
|
||||
@TPATH = split(/\//, $test);
|
||||
pop(@TPATH);
|
||||
$srcdir = join('/', ($opt_srcdir, @TPATH));
|
||||
$objdir = join('/', ($opt_objdir, @TPATH));
|
||||
|
||||
@TSTATS = ("--------------------------------------------------------------------------\n");
|
||||
|
||||
$t_str = sprintf ("%s%s", $test, ' ' x (40 - length($test)));
|
||||
@TSTATS = (@TSTATS, $t_str);
|
||||
@STATS = (@STATS, @TSTATS);
|
||||
if (!$opt_quiet)
|
||||
{
|
||||
foreach $line (@TSTATS)
|
||||
{
|
||||
printf STDOUT "$line";
|
||||
}
|
||||
}
|
||||
|
||||
($utime, $stime, $cutime, $cstime) = times;
|
||||
`$opt_objdir/$test $srcdir $objdir > $opt_objdir/$test.out 2>&1`;
|
||||
($utime, $stime, $tutime, $tstime) = times;
|
||||
|
||||
# Subtract the before time from the after time.
|
||||
$tutime -= $cutime;
|
||||
$tstime -= $cstime;
|
||||
|
||||
if ($opt_zero)
|
||||
{
|
||||
if ($?)
|
||||
{
|
||||
$okay = 0;
|
||||
if ($opt_verbose)
|
||||
{
|
||||
print STDERR
|
||||
"\"$opt_objdir/$test > $opt_objdir/$test.out 2>&1\" returned $?\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ($okay, $tutime, $tstime);
|
||||
}
|
||||
|
||||
sub print_stats
|
||||
{
|
||||
my ($test, $okay, $failed_subtests, $subtests, $utime, $stime) = @_;
|
||||
my ($hutime, $hstime);
|
||||
# my (TEST_PERF);
|
||||
my (@TSTATS);
|
||||
my ($t_str, $pass_str);
|
||||
|
||||
$pass_str = $okay ? "passed" : "*** FAILED ***";
|
||||
if ((0 != $subtests) && (!$okay))
|
||||
{
|
||||
$pass_str = $pass_str . " ($failed_subtests/$subtests failed)";
|
||||
}
|
||||
$pass_str = $pass_str . ' ' x (39 - length($pass_str));
|
||||
|
||||
if (-r "$test.perf")
|
||||
{
|
||||
if (!open (TEST_PERF, "<$opt_objdir/$test.perf"))
|
||||
{
|
||||
print STDERR "Unable to open \"$opt_objdir/$test.perf\"\n";
|
||||
exit 1;
|
||||
}
|
||||
$_ = <TEST_PERF>;
|
||||
|
||||
($hutime, $hstime) = split;
|
||||
close TEST_PERF;
|
||||
|
||||
$t_str = sprintf (" %7.2f %7.2f %7.2f %7.2f\n"
|
||||
. " %s %7.2f %7.2f %7.2f %7.2f%%%%\n",
|
||||
$utime, $stime, $utime + $stime,
|
||||
($utime + $stime) - ($hutime + $hstime),
|
||||
$pass_str,
|
||||
$hutime, $hstime, $hutime + $hstime,
|
||||
(($hutime + $hstime) == 0.0) ? 0.0 :
|
||||
((($utime + $stime) - ($hutime + $hstime))
|
||||
/ ($hutime + $hstime) * 100));
|
||||
}
|
||||
else
|
||||
{
|
||||
$hutime = 0.0;
|
||||
$hstime = 0.0;
|
||||
|
||||
$t_str = sprintf (" %7.2f %7.2f %7.2f \n"
|
||||
. " %s\n",
|
||||
$utime, $stime, $utime + $stime,
|
||||
$pass_str);
|
||||
}
|
||||
@TSTATS = ($t_str);
|
||||
if (!$opt_quiet)
|
||||
{
|
||||
foreach $line (@TSTATS)
|
||||
{
|
||||
printf STDOUT "$line";
|
||||
}
|
||||
}
|
||||
|
||||
if ($okay && $opt_ustats)
|
||||
{
|
||||
if (!open (TEST_PERF, ">$opt_objdir/$test.perf"))
|
||||
{
|
||||
if (!$opt_quiet)
|
||||
{
|
||||
print STDERR "Unable to update \"$opt_objdir/$test.perf\"\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print TEST_PERF "$utime $stime\n";
|
||||
close TEST_PERF;
|
||||
}
|
||||
}
|
||||
|
||||
return ($hutime, $hstime);
|
||||
}
|
||||
|
||||
sub usage
|
||||
{
|
||||
print <<EOF;
|
||||
$0 usage:
|
||||
$0 [<options>] <test>+
|
||||
|
||||
Option | Description
|
||||
--------------+-------------------------------------------------------------
|
||||
-h --help | Print usage and exit.
|
||||
-v --verbose | Verbose (incompatible with quiet).
|
||||
-q --quiet | Quiet (incompatible with verbose).
|
||||
-s --srcdir | Path to source tree (default is ".").
|
||||
-o --objdir | Path to object tree (default is ".").
|
||||
-u --ustats | Update historical statistics (stored in "<test>.perf".
|
||||
-z --zero | Consider non-zero exit code to be an error.
|
||||
--------------+-------------------------------------------------------------
|
||||
|
||||
If <test>.exp exists, <test>'s output is diff'ed with <test>.exp. Any
|
||||
difference is considered failure.
|
||||
|
||||
If <test>.exp does not exist, output to stdout of the following form is
|
||||
expected:
|
||||
|
||||
1..<n>
|
||||
{not }ok[ 1]
|
||||
{not }ok[ 2]
|
||||
...
|
||||
{not }ok[ n]
|
||||
|
||||
1 <= <n> < 2^31
|
||||
|
||||
Lines which do not match the patterns shown above are ignored.
|
||||
EOF
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# thr sources
|
||||
.PATH: ${.CURDIR}/thread
|
||||
|
||||
SRCS+= \
|
||||
thr_accept.c \
|
||||
thr_aio_suspend.c \
|
||||
thr_atfork.c \
|
||||
thr_attr_destroy.c \
|
||||
thr_attr_init.c \
|
||||
thr_attr_get_np.c \
|
||||
thr_attr_getdetachstate.c \
|
||||
thr_attr_getguardsize.c \
|
||||
thr_attr_getinheritsched.c \
|
||||
thr_attr_getschedparam.c \
|
||||
thr_attr_getschedpolicy.c \
|
||||
thr_attr_getscope.c \
|
||||
thr_attr_getstack.c \
|
||||
thr_attr_getstackaddr.c \
|
||||
thr_attr_getstacksize.c \
|
||||
thr_attr_setcreatesuspend_np.c \
|
||||
thr_attr_setdetachstate.c \
|
||||
thr_attr_setguardsize.c \
|
||||
thr_attr_setinheritsched.c \
|
||||
thr_attr_setschedparam.c \
|
||||
thr_attr_setschedpolicy.c \
|
||||
thr_attr_setscope.c \
|
||||
thr_attr_setstack.c \
|
||||
thr_attr_setstackaddr.c \
|
||||
thr_attr_setstacksize.c \
|
||||
thr_autoinit.c \
|
||||
thr_barrier.c \
|
||||
thr_barrierattr.c \
|
||||
thr_cancel.c \
|
||||
thr_clean.c \
|
||||
thr_close.c \
|
||||
thr_concurrency.c \
|
||||
thr_cond.c \
|
||||
thr_condattr_destroy.c \
|
||||
thr_condattr_init.c \
|
||||
thr_condattr_pshared.c \
|
||||
thr_connect.c \
|
||||
thr_creat.c \
|
||||
thr_create.c \
|
||||
thr_detach.c \
|
||||
thr_equal.c \
|
||||
thr_execve.c \
|
||||
thr_exit.c \
|
||||
thr_fcntl.c \
|
||||
thr_find_thread.c \
|
||||
thr_fork.c \
|
||||
thr_fsync.c \
|
||||
thr_getprio.c \
|
||||
thr_getschedparam.c \
|
||||
thr_info.c \
|
||||
thr_init.c \
|
||||
thr_join.c \
|
||||
thr_kern.c \
|
||||
thr_kill.c \
|
||||
thr_main_np.c \
|
||||
thr_mattr_init.c \
|
||||
thr_mattr_kind_np.c \
|
||||
thr_mattr_pshared.c \
|
||||
thr_msync.c \
|
||||
thr_multi_np.c \
|
||||
thr_mutex.c \
|
||||
thr_mutex_prioceiling.c \
|
||||
thr_mutex_protocol.c \
|
||||
thr_mutexattr_destroy.c \
|
||||
thr_nanosleep.c \
|
||||
thr_once.c \
|
||||
thr_open.c \
|
||||
thr_pause.c \
|
||||
thr_poll.c \
|
||||
thr_printf.c \
|
||||
thr_priority_queue.c \
|
||||
thr_pselect.c \
|
||||
thr_pspinlock.c \
|
||||
thr_raise.c \
|
||||
thr_read.c \
|
||||
thr_readv.c \
|
||||
thr_resume_np.c \
|
||||
thr_rtld.c \
|
||||
thr_rwlock.c \
|
||||
thr_rwlockattr.c \
|
||||
thr_select.c \
|
||||
thr_self.c \
|
||||
thr_sem.c \
|
||||
thr_seterrno.c \
|
||||
thr_setprio.c \
|
||||
thr_setschedparam.c \
|
||||
thr_sig.c \
|
||||
thr_sigaction.c \
|
||||
thr_sigaltstack.c \
|
||||
thr_sigmask.c \
|
||||
thr_sigpending.c \
|
||||
thr_sigprocmask.c \
|
||||
thr_sigsuspend.c \
|
||||
thr_sigwait.c \
|
||||
thr_single_np.c \
|
||||
thr_sleep.c \
|
||||
thr_spec.c \
|
||||
thr_spinlock.c \
|
||||
thr_stack.c \
|
||||
thr_suspend_np.c \
|
||||
thr_switch_np.c \
|
||||
thr_system.c \
|
||||
thr_symbols.c \
|
||||
thr_tcdrain.c \
|
||||
thr_vfork.c \
|
||||
thr_wait.c \
|
||||
thr_wait4.c \
|
||||
thr_waitpid.c \
|
||||
thr_write.c \
|
||||
thr_writev.c \
|
||||
thr_yield.c
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <pthread.h>
|
||||
#include "thr_private.h"
|
||||
|
||||
int __accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
__weak_reference(__accept, accept);
|
||||
|
||||
int
|
||||
__accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
struct pthread *curthread;
|
||||
int ret;
|
||||
|
||||
curthread = _get_curthread();
|
||||
_thr_cancel_enter(curthread);
|
||||
ret = __sys_accept(s, addr, addrlen);
|
||||
_thr_cancel_leave(curthread, ret == -1);
|
||||
|
||||
return (ret);
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <aio.h>
|
||||
#include <pthread.h>
|
||||
#include "thr_private.h"
|
||||
|
||||
|
||||
int
|
||||
_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
|
||||
timespec *timeout);
|
||||
|
||||
__weak_reference(_aio_suspend, aio_suspend);
|
||||
|
||||
int
|
||||
_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
|
||||
timespec *timeout)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int ret;
|
||||
|
||||
_thr_cancel_enter(curthread);
|
||||
ret = __sys_aio_suspend(iocbs, niocb, timeout);
|
||||
_thr_cancel_leave(curthread, 1);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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 THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/queue.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_atfork, pthread_atfork);
|
||||
|
||||
int
|
||||
_pthread_atfork(void (*prepare)(void), void (*parent)(void),
|
||||
void (*child)(void))
|
||||
{
|
||||
struct pthread_atfork *af;
|
||||
|
||||
if (_thr_initial == NULL)
|
||||
_libpthread_init(NULL);
|
||||
|
||||
if ((af = malloc(sizeof(struct pthread_atfork))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
af->prepare = prepare;
|
||||
af->parent = parent;
|
||||
af->child = child;
|
||||
_pthread_mutex_lock(&_thr_atfork_mutex);
|
||||
TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe);
|
||||
_pthread_mutex_unlock(&_thr_atfork_mutex);
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_destroy, pthread_attr_destroy);
|
||||
|
||||
int
|
||||
_pthread_attr_destroy(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL)
|
||||
/* Invalid argument: */
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Free the memory allocated to the attribute object: */
|
||||
free(*attr);
|
||||
|
||||
/*
|
||||
* Leave the attribute pointer NULL now that the memory
|
||||
* has been freed:
|
||||
*/
|
||||
*attr = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002,2003 Alexey Zelkin <phantom@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_get_np, pthread_attr_get_np);
|
||||
|
||||
int
|
||||
_pthread_attr_get_np(pthread_t pid, pthread_attr_t *dst)
|
||||
{
|
||||
struct pthread *curthread;
|
||||
struct pthread_attr attr;
|
||||
int ret;
|
||||
|
||||
if (pid == NULL || dst == NULL || *dst == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
curthread = _get_curthread();
|
||||
if ((ret = _thr_ref_add(curthread, pid, /*include dead*/0)) != 0)
|
||||
return (ret);
|
||||
attr = pid->attr;
|
||||
_thr_ref_delete(curthread, pid);
|
||||
memcpy(*dst, &attr, sizeof(struct pthread_attr));
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getdetachstate, pthread_attr_getdetachstate);
|
||||
|
||||
int
|
||||
_pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || detachstate == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if the detached flag is set: */
|
||||
if ((*attr)->flags & PTHREAD_DETACHED)
|
||||
/* Return detached: */
|
||||
*detachstate = PTHREAD_CREATE_DETACHED;
|
||||
else
|
||||
/* Return joinable: */
|
||||
*detachstate = PTHREAD_CREATE_JOINABLE;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 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
|
||||
* unmodified other than the allowable 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$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getguardsize, pthread_attr_getguardsize);
|
||||
|
||||
int
|
||||
_pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || guardsize == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the guard size: */
|
||||
*guardsize = (*attr)->guardsize_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getinheritsched, pthread_attr_getinheritsched);
|
||||
|
||||
int
|
||||
_pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL))
|
||||
ret = EINVAL;
|
||||
else
|
||||
*sched_inherit = (*attr)->sched_inherit;
|
||||
|
||||
return(ret);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getschedparam, pthread_attr_getschedparam);
|
||||
|
||||
int
|
||||
_pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL) || (param == NULL))
|
||||
ret = EINVAL;
|
||||
else
|
||||
param->sched_priority = (*attr)->prio;
|
||||
|
||||
return(ret);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getschedpolicy, pthread_attr_getschedpolicy);
|
||||
|
||||
int
|
||||
_pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL) || (policy == NULL))
|
||||
ret = EINVAL;
|
||||
else
|
||||
*policy = (*attr)->sched_policy;
|
||||
|
||||
return(ret);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getscope, pthread_attr_getscope);
|
||||
|
||||
int
|
||||
_pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL))
|
||||
/* Return an invalid argument: */
|
||||
ret = EINVAL;
|
||||
|
||||
else
|
||||
*contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ?
|
||||
PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS;
|
||||
|
||||
return(ret);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Craig Rodrigues.
|
||||
* 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 CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getstack, pthread_attr_getstack);
|
||||
|
||||
int
|
||||
_pthread_attr_getstack(const pthread_attr_t * __restrict attr,
|
||||
void ** __restrict stackaddr,
|
||||
size_t * __restrict stacksize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL
|
||||
|| stacksize == NULL )
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack address and size */
|
||||
*stackaddr = (*attr)->stackaddr_attr;
|
||||
*stacksize = (*attr)->stacksize_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getstackaddr, pthread_attr_getstackaddr);
|
||||
|
||||
int
|
||||
_pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack address: */
|
||||
*stackaddr = (*attr)->stackaddr_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_getstacksize, pthread_attr_getstacksize);
|
||||
|
||||
int
|
||||
_pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Return the stack size: */
|
||||
*stacksize = (*attr)->stacksize_attr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_init, pthread_attr_init);
|
||||
|
||||
int
|
||||
_pthread_attr_init(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
pthread_attr_t pattr;
|
||||
|
||||
/* Allocate memory for the attribute object: */
|
||||
if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
|
||||
/* Insufficient memory: */
|
||||
ret = ENOMEM;
|
||||
else {
|
||||
/* Initialise the attribute object with the defaults: */
|
||||
memcpy(pattr, &_pthread_attr_default,
|
||||
sizeof(struct pthread_attr));
|
||||
pattr->guardsize_attr = _thr_guard_default;
|
||||
pattr->stacksize_attr = _thr_stack_default;
|
||||
|
||||
/* Return a pointer to the attribute object: */
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
int _pthread_attr_setcreatesuspend_np(pthread_attr_t *attr);
|
||||
|
||||
__weak_reference(_pthread_attr_setcreatesuspend_np, pthread_attr_setcreatesuspend_np);
|
||||
|
||||
int
|
||||
_pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
ret = EINVAL;
|
||||
} else {
|
||||
(*attr)->suspend = THR_CREATE_SUSPENDED;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setdetachstate, pthread_attr_setdetachstate);
|
||||
|
||||
int
|
||||
_pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL ||
|
||||
(detachstate != PTHREAD_CREATE_DETACHED &&
|
||||
detachstate != PTHREAD_CREATE_JOINABLE))
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Check if detached state: */
|
||||
if (detachstate == PTHREAD_CREATE_DETACHED)
|
||||
/* Set the detached flag: */
|
||||
(*attr)->flags |= PTHREAD_DETACHED;
|
||||
else
|
||||
/* Reset the detached flag: */
|
||||
(*attr)->flags &= ~PTHREAD_DETACHED;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 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
|
||||
* unmodified other than the allowable 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$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setguardsize, pthread_attr_setguardsize);
|
||||
|
||||
int
|
||||
_pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments. */
|
||||
if (attr == NULL || *attr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack size. */
|
||||
(*attr)->guardsize_attr = guardsize;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setinheritsched, pthread_attr_setinheritsched);
|
||||
|
||||
int
|
||||
_pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL))
|
||||
ret = EINVAL;
|
||||
else if (sched_inherit != PTHREAD_INHERIT_SCHED &&
|
||||
sched_inherit != PTHREAD_EXPLICIT_SCHED)
|
||||
ret = ENOTSUP;
|
||||
else
|
||||
(*attr)->sched_inherit = sched_inherit;
|
||||
|
||||
return(ret);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setschedparam, pthread_attr_setschedparam);
|
||||
|
||||
int
|
||||
_pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL))
|
||||
ret = EINVAL;
|
||||
else if (param == NULL) {
|
||||
ret = ENOTSUP;
|
||||
} else if ((param->sched_priority < THR_MIN_PRIORITY) ||
|
||||
(param->sched_priority > THR_MAX_PRIORITY)) {
|
||||
/* Return an unsupported value error. */
|
||||
ret = ENOTSUP;
|
||||
} else
|
||||
(*attr)->prio = param->sched_priority;
|
||||
|
||||
return(ret);
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
|
||||
|
||||
int
|
||||
_pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL))
|
||||
ret = EINVAL;
|
||||
else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) {
|
||||
ret = ENOTSUP;
|
||||
} else
|
||||
(*attr)->sched_policy = policy;
|
||||
|
||||
return(ret);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel Eischen <eischen@vigrid.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Daniel Eischen.
|
||||
* 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 DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setscope, pthread_attr_setscope);
|
||||
|
||||
int
|
||||
_pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((attr == NULL) || (*attr == NULL)) {
|
||||
/* Return an invalid argument: */
|
||||
ret = EINVAL;
|
||||
} else if ((contentionscope != PTHREAD_SCOPE_PROCESS) &&
|
||||
(contentionscope != PTHREAD_SCOPE_SYSTEM)) {
|
||||
ret = EINVAL;
|
||||
} else if (contentionscope == PTHREAD_SCOPE_SYSTEM) {
|
||||
(*attr)->flags |= contentionscope;
|
||||
} else {
|
||||
(*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM;
|
||||
}
|
||||
return (ret);
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Craig Rodrigues.
|
||||
* 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 CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setstack, pthread_attr_setstack);
|
||||
|
||||
int
|
||||
_pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
|
||||
size_t stacksize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL
|
||||
|| stacksize < PTHREAD_STACK_MIN )
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack address and stack size */
|
||||
(*attr)->stackaddr_attr = stackaddr;
|
||||
(*attr)->stacksize_attr = stacksize;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setstackaddr, pthread_attr_setstackaddr);
|
||||
|
||||
int
|
||||
_pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stackaddr == NULL)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack address: */
|
||||
(*attr)->stackaddr_attr = stackaddr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_attr_setstacksize, pthread_attr_setstacksize);
|
||||
|
||||
int
|
||||
_pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check for invalid arguments: */
|
||||
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Save the stack size: */
|
||||
(*attr)->stacksize_attr = stacksize;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Alfred Perlstein <alfred@freebsd.org>.
|
||||
* Copyright (c) 1995 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 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module uses GCC extentions to initialize the
|
||||
* threads package at program start-up time.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include "thr_private.h"
|
||||
|
||||
void _thread_init_hack(void) __attribute__ ((constructor));
|
||||
|
||||
void
|
||||
_thread_init_hack(void)
|
||||
{
|
||||
|
||||
_libpthread_init(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* For the shared version of the threads library, the above is sufficient.
|
||||
* But for the archive version of the library, we need a little bit more.
|
||||
* Namely, we must arrange for this particular module to be pulled in from
|
||||
* the archive library at link time. To accomplish that, we define and
|
||||
* initialize a variable, "_thread_autoinit_dummy_decl". This variable is
|
||||
* referenced (as an extern) from libc/stdlib/exit.c. This will always
|
||||
* create a need for this module, ensuring that it is present in the
|
||||
* executable.
|
||||
*/
|
||||
extern int _thread_autoinit_dummy_decl;
|
||||
int _thread_autoinit_dummy_decl = 0;
|
@ -1,122 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 David Xu <davidxu@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_barrier_init, pthread_barrier_init);
|
||||
__weak_reference(_pthread_barrier_wait, pthread_barrier_wait);
|
||||
__weak_reference(_pthread_barrier_destroy, pthread_barrier_destroy);
|
||||
|
||||
int
|
||||
_pthread_barrier_destroy(pthread_barrier_t *barrier)
|
||||
{
|
||||
pthread_barrier_t bar;
|
||||
int ret, ret2;
|
||||
|
||||
if (barrier == NULL || *barrier == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
bar = *barrier;
|
||||
if (bar->b_waiters > 0)
|
||||
return (EBUSY);
|
||||
*barrier = NULL;
|
||||
ret = _pthread_mutex_destroy(&bar->b_lock);
|
||||
ret2 = _pthread_cond_destroy(&bar->b_cond);
|
||||
free(bar);
|
||||
return (ret ? ret : ret2);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_barrier_init(pthread_barrier_t *barrier,
|
||||
const pthread_barrierattr_t *attr __unused, unsigned count)
|
||||
{
|
||||
pthread_barrier_t bar;
|
||||
int ret;
|
||||
|
||||
if (barrier == NULL || count <= 0)
|
||||
return (EINVAL);
|
||||
|
||||
bar = malloc(sizeof(struct pthread_barrier));
|
||||
if (bar == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
if ((ret = _pthread_mutex_init(&bar->b_lock, NULL)) != 0) {
|
||||
free(bar);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
if ((ret = _pthread_cond_init(&bar->b_cond, NULL)) != 0) {
|
||||
_pthread_mutex_destroy(&bar->b_lock);
|
||||
free(bar);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
bar->b_waiters = 0;
|
||||
bar->b_count = count;
|
||||
bar->b_generation = 0;
|
||||
*barrier = bar;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_barrier_wait(pthread_barrier_t *barrier)
|
||||
{
|
||||
int ret, gen;
|
||||
pthread_barrier_t bar;
|
||||
|
||||
if (barrier == NULL || *barrier == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
bar = *barrier;
|
||||
if ((ret = _pthread_mutex_lock(&bar->b_lock)) != 0)
|
||||
return (ret);
|
||||
|
||||
if (++bar->b_waiters == bar->b_count) {
|
||||
/* Current thread is lastest thread */
|
||||
bar->b_generation++;
|
||||
bar->b_waiters = 0;
|
||||
ret = _pthread_cond_broadcast(&bar->b_cond);
|
||||
if (ret == 0)
|
||||
ret = PTHREAD_BARRIER_SERIAL_THREAD;
|
||||
} else {
|
||||
gen = bar->b_generation;
|
||||
do {
|
||||
ret = _pthread_cond_wait(
|
||||
&bar->b_cond, &bar->b_lock);
|
||||
/* test generation to avoid bogus wakeup */
|
||||
} while (ret == 0 && gen == bar->b_generation);
|
||||
}
|
||||
_pthread_mutex_unlock(&bar->b_lock);
|
||||
return (ret);
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 David Xu <davidxu@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$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_barrierattr_destroy, pthread_barrierattr_destroy);
|
||||
__weak_reference(_pthread_barrierattr_init, pthread_barrierattr_init);
|
||||
__weak_reference(_pthread_barrierattr_setpshared,
|
||||
pthread_barrierattr_setpshared);
|
||||
__weak_reference(_pthread_barrierattr_getpshared,
|
||||
pthread_barrierattr_getpshared);
|
||||
|
||||
int
|
||||
_pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
|
||||
{
|
||||
|
||||
if (attr == NULL || *attr == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
free(*attr);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr,
|
||||
int *pshared)
|
||||
{
|
||||
|
||||
if (attr == NULL || *attr == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*pshared = (*attr)->pshared;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_barrierattr_init(pthread_barrierattr_t *attr)
|
||||
{
|
||||
|
||||
if (attr == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
if ((*attr = malloc(sizeof(struct pthread_barrierattr))) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
(*attr)->pshared = PTHREAD_PROCESS_PRIVATE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)
|
||||
{
|
||||
|
||||
if (attr == NULL || *attr == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
/* Only PTHREAD_PROCESS_PRIVATE is supported. */
|
||||
if (pshared != PTHREAD_PROCESS_PRIVATE)
|
||||
return (EINVAL);
|
||||
|
||||
(*attr)->pshared = pshared;
|
||||
return (0);
|
||||
}
|
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* David Leonard <d@openbsd.org>, 1999. Public domain.
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <sys/errno.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_cancel, pthread_cancel);
|
||||
__weak_reference(_pthread_setcancelstate, pthread_setcancelstate);
|
||||
__weak_reference(_pthread_setcanceltype, pthread_setcanceltype);
|
||||
__weak_reference(_pthread_testcancel, pthread_testcancel);
|
||||
|
||||
static inline int
|
||||
checkcancel(struct pthread *curthread)
|
||||
{
|
||||
if ((curthread->cancelflags & THR_CANCELLING) != 0) {
|
||||
/*
|
||||
* It is possible for this thread to be swapped out
|
||||
* while performing cancellation; do not allow it
|
||||
* to be cancelled again.
|
||||
*/
|
||||
if ((curthread->flags & THR_FLAGS_EXITING) != 0) {
|
||||
/*
|
||||
* This may happen once, but after this, it
|
||||
* shouldn't happen again.
|
||||
*/
|
||||
curthread->cancelflags &= ~THR_CANCELLING;
|
||||
return (0);
|
||||
}
|
||||
if ((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) {
|
||||
curthread->cancelflags &= ~THR_CANCELLING;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
testcancel(struct pthread *curthread)
|
||||
{
|
||||
if (checkcancel(curthread) != 0) {
|
||||
/* Unlock before exiting: */
|
||||
THR_THREAD_UNLOCK(curthread, curthread);
|
||||
|
||||
_thr_exit_cleanup();
|
||||
_pthread_exit(PTHREAD_CANCELED);
|
||||
PANIC("cancel");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cancel(pthread_t pthread)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
struct pthread *joinee = NULL;
|
||||
struct kse_mailbox *kmbx = NULL;
|
||||
int ret;
|
||||
|
||||
if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) == 0) {
|
||||
/*
|
||||
* Take the thread's lock while we change the cancel flags.
|
||||
*/
|
||||
THR_THREAD_LOCK(curthread, pthread);
|
||||
THR_SCHED_LOCK(curthread, pthread);
|
||||
if (pthread->flags & THR_FLAGS_EXITING) {
|
||||
THR_SCHED_UNLOCK(curthread, pthread);
|
||||
THR_THREAD_UNLOCK(curthread, pthread);
|
||||
_thr_ref_delete(curthread, pthread);
|
||||
return (ESRCH);
|
||||
}
|
||||
if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) ||
|
||||
(((pthread->cancelflags & THR_AT_CANCEL_POINT) == 0) &&
|
||||
((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0)))
|
||||
/* Just mark it for cancellation: */
|
||||
pthread->cancelflags |= THR_CANCELLING;
|
||||
else {
|
||||
/*
|
||||
* Check if we need to kick it back into the
|
||||
* run queue:
|
||||
*/
|
||||
switch (pthread->state) {
|
||||
case PS_RUNNING:
|
||||
/* No need to resume: */
|
||||
pthread->cancelflags |= THR_CANCELLING;
|
||||
break;
|
||||
|
||||
case PS_LOCKWAIT:
|
||||
/*
|
||||
* These can't be removed from the queue.
|
||||
* Just mark it as cancelling and tell it
|
||||
* to yield once it leaves the critical
|
||||
* region.
|
||||
*/
|
||||
pthread->cancelflags |= THR_CANCELLING;
|
||||
pthread->critical_yield = 1;
|
||||
break;
|
||||
|
||||
case PS_SLEEP_WAIT:
|
||||
case PS_SIGSUSPEND:
|
||||
case PS_SIGWAIT:
|
||||
/* Interrupt and resume: */
|
||||
pthread->interrupted = 1;
|
||||
pthread->cancelflags |= THR_CANCELLING;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
break;
|
||||
|
||||
case PS_JOIN:
|
||||
/* Disconnect the thread from the joinee: */
|
||||
joinee = pthread->join_status.thread;
|
||||
pthread->join_status.thread = NULL;
|
||||
pthread->cancelflags |= THR_CANCELLING;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
if ((joinee != NULL) &&
|
||||
(pthread->kseg == joinee->kseg)) {
|
||||
/* Remove the joiner from the joinee. */
|
||||
joinee->joiner = NULL;
|
||||
joinee = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case PS_SUSPENDED:
|
||||
case PS_MUTEX_WAIT:
|
||||
case PS_COND_WAIT:
|
||||
/*
|
||||
* Threads in these states may be in queues.
|
||||
* In order to preserve queue integrity, the
|
||||
* cancelled thread must remove itself from the
|
||||
* queue. Mark the thread as interrupted and
|
||||
* needing cancellation, and set the state to
|
||||
* running. When the thread resumes, it will
|
||||
* remove itself from the queue and call the
|
||||
* cancellation completion routine.
|
||||
*/
|
||||
pthread->interrupted = 1;
|
||||
pthread->cancelflags |= THR_CANCEL_NEEDED;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
pthread->continuation =
|
||||
_thr_finish_cancellation;
|
||||
break;
|
||||
|
||||
case PS_DEAD:
|
||||
case PS_DEADLOCK:
|
||||
case PS_STATE_MAX:
|
||||
/* Ignore - only here to silence -Wall: */
|
||||
break;
|
||||
}
|
||||
if ((pthread->cancelflags & THR_AT_CANCEL_POINT) &&
|
||||
(pthread->blocked != 0 ||
|
||||
pthread->attr.flags & PTHREAD_SCOPE_SYSTEM))
|
||||
kse_thr_interrupt(&pthread->tcb->tcb_tmbx,
|
||||
KSE_INTR_INTERRUPT, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the thread's lock and remove the
|
||||
* reference:
|
||||
*/
|
||||
THR_SCHED_UNLOCK(curthread, pthread);
|
||||
THR_THREAD_UNLOCK(curthread, pthread);
|
||||
_thr_ref_delete(curthread, pthread);
|
||||
if (kmbx != NULL)
|
||||
kse_wakeup(kmbx);
|
||||
|
||||
if ((joinee != NULL) &&
|
||||
(_thr_ref_add(curthread, joinee, /* include dead */1) == 0)) {
|
||||
/* Remove the joiner from the joinee. */
|
||||
THR_SCHED_LOCK(curthread, joinee);
|
||||
joinee->joiner = NULL;
|
||||
THR_SCHED_UNLOCK(curthread, joinee);
|
||||
_thr_ref_delete(curthread, joinee);
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_setcancelstate(int state, int *oldstate)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int ostate;
|
||||
int ret;
|
||||
int need_exit = 0;
|
||||
|
||||
/* Take the thread's lock while fiddling with the state: */
|
||||
THR_THREAD_LOCK(curthread, curthread);
|
||||
|
||||
ostate = curthread->cancelflags & PTHREAD_CANCEL_DISABLE;
|
||||
|
||||
switch (state) {
|
||||
case PTHREAD_CANCEL_ENABLE:
|
||||
curthread->cancelflags &= ~PTHREAD_CANCEL_DISABLE;
|
||||
if ((curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)
|
||||
need_exit = checkcancel(curthread);
|
||||
ret = 0;
|
||||
break;
|
||||
case PTHREAD_CANCEL_DISABLE:
|
||||
curthread->cancelflags |= PTHREAD_CANCEL_DISABLE;
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
THR_THREAD_UNLOCK(curthread, curthread);
|
||||
if (need_exit != 0) {
|
||||
_thr_exit_cleanup();
|
||||
_pthread_exit(PTHREAD_CANCELED);
|
||||
PANIC("cancel");
|
||||
}
|
||||
if (ret == 0 && oldstate != NULL)
|
||||
*oldstate = ostate;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_setcanceltype(int type, int *oldtype)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int otype;
|
||||
int ret;
|
||||
int need_exit = 0;
|
||||
|
||||
/* Take the thread's lock while fiddling with the state: */
|
||||
THR_THREAD_LOCK(curthread, curthread);
|
||||
|
||||
otype = curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS;
|
||||
switch (type) {
|
||||
case PTHREAD_CANCEL_ASYNCHRONOUS:
|
||||
curthread->cancelflags |= PTHREAD_CANCEL_ASYNCHRONOUS;
|
||||
need_exit = checkcancel(curthread);
|
||||
ret = 0;
|
||||
break;
|
||||
case PTHREAD_CANCEL_DEFERRED:
|
||||
curthread->cancelflags &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
THR_THREAD_UNLOCK(curthread, curthread);
|
||||
if (need_exit != 0) {
|
||||
_thr_exit_cleanup();
|
||||
_pthread_exit(PTHREAD_CANCELED);
|
||||
PANIC("cancel");
|
||||
}
|
||||
if (ret == 0 && oldtype != NULL)
|
||||
*oldtype = otype;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
_pthread_testcancel(void)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
|
||||
THR_THREAD_LOCK(curthread, curthread);
|
||||
testcancel(curthread);
|
||||
THR_THREAD_UNLOCK(curthread, curthread);
|
||||
}
|
||||
|
||||
void
|
||||
_thr_cancel_enter(struct pthread *thread)
|
||||
{
|
||||
/* Look for a cancellation before we block: */
|
||||
THR_THREAD_LOCK(thread, thread);
|
||||
testcancel(thread);
|
||||
thread->cancelflags |= THR_AT_CANCEL_POINT;
|
||||
THR_THREAD_UNLOCK(thread, thread);
|
||||
}
|
||||
|
||||
void
|
||||
_thr_cancel_leave(struct pthread *thread, int check)
|
||||
{
|
||||
THR_THREAD_LOCK(thread, thread);
|
||||
thread->cancelflags &= ~THR_AT_CANCEL_POINT;
|
||||
/* Look for a cancellation after we unblock: */
|
||||
if (check)
|
||||
testcancel(thread);
|
||||
THR_THREAD_UNLOCK(thread, thread);
|
||||
}
|
||||
|
||||
void
|
||||
_thr_finish_cancellation(void *arg __unused)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
|
||||
curthread->continuation = NULL;
|
||||
curthread->interrupted = 0;
|
||||
|
||||
THR_THREAD_LOCK(curthread, curthread);
|
||||
if ((curthread->cancelflags & THR_CANCEL_NEEDED) != 0) {
|
||||
curthread->cancelflags &= ~THR_CANCEL_NEEDED;
|
||||
THR_THREAD_UNLOCK(curthread, curthread);
|
||||
_thr_exit_cleanup();
|
||||
_pthread_exit(PTHREAD_CANCELED);
|
||||
}
|
||||
THR_THREAD_UNLOCK(curthread, curthread);
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
__weak_reference(_pthread_cleanup_push, pthread_cleanup_push);
|
||||
__weak_reference(_pthread_cleanup_pop, pthread_cleanup_pop);
|
||||
|
||||
void
|
||||
_pthread_cleanup_push(void (*routine) (void *), void *routine_arg)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
struct pthread_cleanup *new;
|
||||
|
||||
if ((new = (struct pthread_cleanup *)
|
||||
malloc(sizeof(struct pthread_cleanup))) != NULL) {
|
||||
new->routine = routine;
|
||||
new->routine_arg = routine_arg;
|
||||
new->onstack = 0;
|
||||
new->next = curthread->cleanup;
|
||||
|
||||
curthread->cleanup = new;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_pthread_cleanup_pop(int execute)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
struct pthread_cleanup *old;
|
||||
|
||||
if ((old = curthread->cleanup) != NULL) {
|
||||
curthread->cleanup = old->next;
|
||||
if (execute) {
|
||||
old->routine(old->routine_arg);
|
||||
}
|
||||
if (old->onstack == 0)
|
||||
free(old);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995-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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
int __close(int fd);
|
||||
|
||||
__weak_reference(__close, close);
|
||||
|
||||
int
|
||||
__close(int fd)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int ret;
|
||||
|
||||
_thr_cancel_enter(curthread);
|
||||
ret = __sys_close(fd);
|
||||
_thr_cancel_leave(curthread, 1);
|
||||
|
||||
return (ret);
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org>
|
||||
* Copyright (c) 2003 Sergey Osokin <osa@freebsd.org.ru>.
|
||||
* 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. 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 THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "thr_private.h"
|
||||
|
||||
/*#define DEBUG_CONCURRENCY */
|
||||
#ifdef DEBUG_CONCURRENCY
|
||||
#define DBG_MSG stdout_debug
|
||||
#else
|
||||
#define DBG_MSG(x...)
|
||||
#endif
|
||||
|
||||
static int level = 0;
|
||||
|
||||
__weak_reference(_pthread_getconcurrency, pthread_getconcurrency);
|
||||
__weak_reference(_pthread_setconcurrency, pthread_setconcurrency);
|
||||
|
||||
int
|
||||
_pthread_getconcurrency(void)
|
||||
{
|
||||
return (level);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_setconcurrency(int new_level)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (new_level < 0)
|
||||
ret = EINVAL;
|
||||
else if (new_level == level)
|
||||
ret = 0;
|
||||
else if (new_level == 0) {
|
||||
level = 0;
|
||||
ret = 0;
|
||||
} else if ((_kse_isthreaded() == 0) && (_kse_setthreaded(1) != 0)) {
|
||||
DBG_MSG("Can't enable threading.\n");
|
||||
ret = EAGAIN;
|
||||
} else {
|
||||
ret = _thr_setconcurrency(new_level);
|
||||
if (ret == 0)
|
||||
level = new_level;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_thr_setconcurrency(int new_level)
|
||||
{
|
||||
struct pthread *curthread;
|
||||
struct kse *newkse, *kse;
|
||||
kse_critical_t crit;
|
||||
int kse_count;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Turn on threaded mode, if failed, it is unnecessary to
|
||||
* do further work.
|
||||
*/
|
||||
if (_kse_isthreaded() == 0 && _kse_setthreaded(1))
|
||||
return (EAGAIN);
|
||||
|
||||
ret = 0;
|
||||
curthread = _get_curthread();
|
||||
/* Race condition, but so what. */
|
||||
kse_count = _kse_initial->k_kseg->kg_ksecount;
|
||||
if (new_level > kse_count) {
|
||||
for (i = kse_count; i < new_level; i++) {
|
||||
newkse = _kse_alloc(curthread, 0);
|
||||
if (newkse == NULL) {
|
||||
DBG_MSG("Can't alloc new KSE.\n");
|
||||
ret = EAGAIN;
|
||||
break;
|
||||
}
|
||||
newkse->k_kseg = _kse_initial->k_kseg;
|
||||
newkse->k_schedq = _kse_initial->k_schedq;
|
||||
newkse->k_curthread = NULL;
|
||||
crit = _kse_critical_enter();
|
||||
KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg);
|
||||
TAILQ_INSERT_TAIL(&newkse->k_kseg->kg_kseq,
|
||||
newkse, k_kgqe);
|
||||
newkse->k_kseg->kg_ksecount++;
|
||||
newkse->k_flags |= KF_STARTED;
|
||||
KSE_SCHED_UNLOCK(curthread->kse, newkse->k_kseg);
|
||||
if (kse_create(&newkse->k_kcb->kcb_kmbx, 0) != 0) {
|
||||
KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg);
|
||||
TAILQ_REMOVE(&newkse->k_kseg->kg_kseq,
|
||||
newkse, k_kgqe);
|
||||
newkse->k_kseg->kg_ksecount--;
|
||||
KSE_SCHED_UNLOCK(curthread->kse,
|
||||
newkse->k_kseg);
|
||||
_kse_critical_leave(crit);
|
||||
_kse_free(curthread, newkse);
|
||||
DBG_MSG("kse_create syscall failed.\n");
|
||||
ret = EAGAIN;
|
||||
break;
|
||||
} else {
|
||||
_kse_critical_leave(crit);
|
||||
}
|
||||
}
|
||||
} else if (new_level < kse_count) {
|
||||
kse_count = 0;
|
||||
crit = _kse_critical_enter();
|
||||
KSE_SCHED_LOCK(curthread->kse, _kse_initial->k_kseg);
|
||||
/* Count the number of active KSEs */
|
||||
TAILQ_FOREACH(kse, &_kse_initial->k_kseg->kg_kseq, k_kgqe) {
|
||||
if ((kse->k_flags & KF_TERMINATED) == 0)
|
||||
kse_count++;
|
||||
}
|
||||
/* Reduce the number of active KSEs appropriately. */
|
||||
kse = TAILQ_FIRST(&_kse_initial->k_kseg->kg_kseq);
|
||||
while ((kse != NULL) && (kse_count > new_level)) {
|
||||
if ((kse != _kse_initial) &&
|
||||
((kse->k_flags & KF_TERMINATED) == 0)) {
|
||||
kse->k_flags |= KF_TERMINATED;
|
||||
kse_count--;
|
||||
/* Wakup the KSE in case it is idle. */
|
||||
kse_wakeup(&kse->k_kcb->kcb_kmbx);
|
||||
}
|
||||
kse = TAILQ_NEXT(kse, k_kgqe);
|
||||
}
|
||||
KSE_SCHED_UNLOCK(curthread->kse, _kse_initial->k_kseg);
|
||||
_kse_critical_leave(crit);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_thr_setmaxconcurrency(void)
|
||||
{
|
||||
int vcpu;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(vcpu);
|
||||
ret = sysctlbyname("kern.threads.virtual_cpu", &vcpu, &len, NULL, 0);
|
||||
if (ret == 0 && vcpu > 0)
|
||||
ret = _thr_setconcurrency(vcpu);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -1,836 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 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. 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 AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
#define THR_IN_CONDQ(thr) (((thr)->sflags & THR_FLAGS_IN_SYNCQ) != 0)
|
||||
#define THR_CONDQ_SET(thr) (thr)->sflags |= THR_FLAGS_IN_SYNCQ
|
||||
#define THR_CONDQ_CLEAR(thr) (thr)->sflags &= ~THR_FLAGS_IN_SYNCQ
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
static inline struct pthread *cond_queue_deq(pthread_cond_t);
|
||||
static inline void cond_queue_remove(pthread_cond_t, pthread_t);
|
||||
static inline void cond_queue_enq(pthread_cond_t, pthread_t);
|
||||
static void cond_wait_backout(void *);
|
||||
static inline void check_continuation(struct pthread *,
|
||||
struct pthread_cond *, pthread_mutex_t *);
|
||||
|
||||
int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime);
|
||||
|
||||
/*
|
||||
* Double underscore versions are cancellation points. Single underscore
|
||||
* versions are not and are provided for libc internal usage (which
|
||||
* shouldn't introduce cancellation points).
|
||||
*/
|
||||
__weak_reference(__pthread_cond_wait, pthread_cond_wait);
|
||||
__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait);
|
||||
|
||||
__weak_reference(_pthread_cond_init, pthread_cond_init);
|
||||
__weak_reference(_pthread_cond_destroy, pthread_cond_destroy);
|
||||
__weak_reference(_pthread_cond_signal, pthread_cond_signal);
|
||||
__weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast);
|
||||
|
||||
|
||||
int
|
||||
_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
|
||||
{
|
||||
enum pthread_cond_type type;
|
||||
pthread_cond_t pcond;
|
||||
int flags;
|
||||
int rval = 0;
|
||||
|
||||
if (cond == NULL)
|
||||
rval = EINVAL;
|
||||
else {
|
||||
/*
|
||||
* Check if a pointer to a condition variable attribute
|
||||
* structure was passed by the caller:
|
||||
*/
|
||||
if (cond_attr != NULL && *cond_attr != NULL) {
|
||||
/* Default to a fast condition variable: */
|
||||
type = (*cond_attr)->c_type;
|
||||
flags = (*cond_attr)->c_flags;
|
||||
} else {
|
||||
/* Default to a fast condition variable: */
|
||||
type = COND_TYPE_FAST;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
/* Process according to condition variable type: */
|
||||
switch (type) {
|
||||
/* Fast condition variable: */
|
||||
case COND_TYPE_FAST:
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
|
||||
/* Trap invalid condition variable types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
rval = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for no errors: */
|
||||
if (rval == 0) {
|
||||
if ((pcond = (pthread_cond_t)
|
||||
malloc(sizeof(struct pthread_cond))) == NULL) {
|
||||
rval = ENOMEM;
|
||||
} else if (_lock_init(&pcond->c_lock, LCK_ADAPTIVE,
|
||||
_thr_lock_wait, _thr_lock_wakeup, calloc) != 0) {
|
||||
free(pcond);
|
||||
rval = ENOMEM;
|
||||
} else {
|
||||
/*
|
||||
* Initialise the condition variable
|
||||
* structure:
|
||||
*/
|
||||
TAILQ_INIT(&pcond->c_queue);
|
||||
pcond->c_flags = COND_FLAGS_INITED;
|
||||
pcond->c_type = type;
|
||||
pcond->c_mutex = NULL;
|
||||
pcond->c_seqno = 0;
|
||||
*cond = pcond;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
struct pthread_cond *cv;
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int rval = 0;
|
||||
|
||||
if (cond == NULL || *cond == NULL)
|
||||
rval = EINVAL;
|
||||
else {
|
||||
/* Lock the condition variable structure: */
|
||||
THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock);
|
||||
|
||||
/*
|
||||
* NULL the caller's pointer now that the condition
|
||||
* variable has been destroyed:
|
||||
*/
|
||||
cv = *cond;
|
||||
*cond = NULL;
|
||||
|
||||
/* Unlock the condition variable structure: */
|
||||
THR_LOCK_RELEASE(curthread, &cv->c_lock);
|
||||
|
||||
/* Free the cond lock structure: */
|
||||
_lock_destroy(&cv->c_lock);
|
||||
|
||||
/*
|
||||
* Free the memory allocated for the condition
|
||||
* variable structure:
|
||||
*/
|
||||
free(cv);
|
||||
|
||||
}
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int rval = 0;
|
||||
int done = 0;
|
||||
int mutex_locked = 1;
|
||||
int seqno;
|
||||
|
||||
if (cond == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* If the condition variable is statically initialized,
|
||||
* perform the dynamic initialization:
|
||||
*/
|
||||
if (*cond == NULL &&
|
||||
(rval = _pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
|
||||
if (!_kse_isthreaded())
|
||||
_kse_setthreaded(1);
|
||||
|
||||
/*
|
||||
* Enter a loop waiting for a condition signal or broadcast
|
||||
* to wake up this thread. A loop is needed in case the waiting
|
||||
* thread is interrupted by a signal to execute a signal handler.
|
||||
* It is not (currently) possible to remain in the waiting queue
|
||||
* while running a handler. Instead, the thread is interrupted
|
||||
* and backed out of the waiting queue prior to executing the
|
||||
* signal handler.
|
||||
*/
|
||||
|
||||
/* Lock the condition variable structure: */
|
||||
THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock);
|
||||
seqno = (*cond)->c_seqno;
|
||||
do {
|
||||
/*
|
||||
* If the condvar was statically allocated, properly
|
||||
* initialize the tail queue.
|
||||
*/
|
||||
if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
|
||||
TAILQ_INIT(&(*cond)->c_queue);
|
||||
(*cond)->c_flags |= COND_FLAGS_INITED;
|
||||
}
|
||||
|
||||
/* Process according to condition variable type: */
|
||||
switch ((*cond)->c_type) {
|
||||
/* Fast condition variable: */
|
||||
case COND_TYPE_FAST:
|
||||
if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
|
||||
((*cond)->c_mutex != *mutex))) {
|
||||
/* Return invalid argument error: */
|
||||
rval = EINVAL;
|
||||
} else {
|
||||
/* Reset the timeout and interrupted flags: */
|
||||
curthread->timeout = 0;
|
||||
curthread->interrupted = 0;
|
||||
|
||||
/*
|
||||
* Queue the running thread for the condition
|
||||
* variable:
|
||||
*/
|
||||
cond_queue_enq(*cond, curthread);
|
||||
|
||||
/* Wait forever: */
|
||||
curthread->wakeup_time.tv_sec = -1;
|
||||
|
||||
/* Unlock the mutex: */
|
||||
if (mutex_locked &&
|
||||
((rval = _mutex_cv_unlock(mutex)) != 0)) {
|
||||
/*
|
||||
* Cannot unlock the mutex, so remove
|
||||
* the running thread from the condition
|
||||
* variable queue:
|
||||
*/
|
||||
cond_queue_remove(*cond, curthread);
|
||||
}
|
||||
else {
|
||||
/* Remember the mutex: */
|
||||
(*cond)->c_mutex = *mutex;
|
||||
|
||||
/*
|
||||
* Don't unlock the mutex the next
|
||||
* time through the loop (if the
|
||||
* thread has to be requeued after
|
||||
* handling a signal).
|
||||
*/
|
||||
mutex_locked = 0;
|
||||
|
||||
/*
|
||||
* This thread is active and is in a
|
||||
* critical region (holding the cv
|
||||
* lock); we should be able to safely
|
||||
* set the state.
|
||||
*/
|
||||
THR_SCHED_LOCK(curthread, curthread);
|
||||
THR_SET_STATE(curthread, PS_COND_WAIT);
|
||||
|
||||
/* Remember the CV: */
|
||||
curthread->data.cond = *cond;
|
||||
curthread->sigbackout = cond_wait_backout;
|
||||
THR_SCHED_UNLOCK(curthread, curthread);
|
||||
|
||||
/* Unlock the CV structure: */
|
||||
THR_LOCK_RELEASE(curthread,
|
||||
&(*cond)->c_lock);
|
||||
|
||||
/* Schedule the next thread: */
|
||||
_thr_sched_switch(curthread);
|
||||
|
||||
/*
|
||||
* XXX - This really isn't a good check
|
||||
* since there can be more than one
|
||||
* thread waiting on the CV. Signals
|
||||
* sent to threads waiting on mutexes
|
||||
* or CVs should really be deferred
|
||||
* until the threads are no longer
|
||||
* waiting, but POSIX says that signals
|
||||
* should be sent "as soon as possible".
|
||||
*/
|
||||
done = (seqno != (*cond)->c_seqno);
|
||||
if (done && !THR_IN_CONDQ(curthread)) {
|
||||
/*
|
||||
* The thread is dequeued, so
|
||||
* it is safe to clear these.
|
||||
*/
|
||||
curthread->data.cond = NULL;
|
||||
curthread->sigbackout = NULL;
|
||||
check_continuation(curthread,
|
||||
NULL, mutex);
|
||||
return (_mutex_cv_lock(mutex));
|
||||
}
|
||||
|
||||
/* Relock the CV structure: */
|
||||
THR_LOCK_ACQUIRE(curthread,
|
||||
&(*cond)->c_lock);
|
||||
|
||||
/*
|
||||
* Clear these after taking the lock to
|
||||
* prevent a race condition where a
|
||||
* signal can arrive before dequeueing
|
||||
* the thread.
|
||||
*/
|
||||
curthread->data.cond = NULL;
|
||||
curthread->sigbackout = NULL;
|
||||
done = (seqno != (*cond)->c_seqno);
|
||||
|
||||
if (THR_IN_CONDQ(curthread)) {
|
||||
cond_queue_remove(*cond,
|
||||
curthread);
|
||||
|
||||
/* Check for no more waiters: */
|
||||
if (TAILQ_EMPTY(&(*cond)->c_queue))
|
||||
(*cond)->c_mutex = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Trap invalid condition variable types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
rval = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
check_continuation(curthread, *cond,
|
||||
mutex_locked ? NULL : mutex);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
/* Unlock the condition variable structure: */
|
||||
THR_LOCK_RELEASE(curthread, &(*cond)->c_lock);
|
||||
|
||||
if (mutex_locked == 0)
|
||||
_mutex_cv_lock(mutex);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
__strong_reference(_pthread_cond_wait, _thr_cond_wait);
|
||||
|
||||
int
|
||||
__pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int ret;
|
||||
|
||||
_thr_cancel_enter(curthread);
|
||||
ret = _pthread_cond_wait(cond, mutex);
|
||||
_thr_cancel_leave(curthread, 1);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
const struct timespec * abstime)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int rval = 0;
|
||||
int done = 0;
|
||||
int mutex_locked = 1;
|
||||
int seqno;
|
||||
|
||||
THR_ASSERT(curthread->locklevel == 0,
|
||||
"cv_timedwait: locklevel is not zero!");
|
||||
|
||||
if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
|
||||
abstime->tv_nsec >= 1000000000)
|
||||
return (EINVAL);
|
||||
/*
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
if (*cond == NULL && (rval = _pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
|
||||
if (!_kse_isthreaded())
|
||||
_kse_setthreaded(1);
|
||||
|
||||
/*
|
||||
* Enter a loop waiting for a condition signal or broadcast
|
||||
* to wake up this thread. A loop is needed in case the waiting
|
||||
* thread is interrupted by a signal to execute a signal handler.
|
||||
* It is not (currently) possible to remain in the waiting queue
|
||||
* while running a handler. Instead, the thread is interrupted
|
||||
* and backed out of the waiting queue prior to executing the
|
||||
* signal handler.
|
||||
*/
|
||||
|
||||
/* Lock the condition variable structure: */
|
||||
THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock);
|
||||
seqno = (*cond)->c_seqno;
|
||||
do {
|
||||
/*
|
||||
* If the condvar was statically allocated, properly
|
||||
* initialize the tail queue.
|
||||
*/
|
||||
if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
|
||||
TAILQ_INIT(&(*cond)->c_queue);
|
||||
(*cond)->c_flags |= COND_FLAGS_INITED;
|
||||
}
|
||||
|
||||
/* Process according to condition variable type: */
|
||||
switch ((*cond)->c_type) {
|
||||
/* Fast condition variable: */
|
||||
case COND_TYPE_FAST:
|
||||
if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
|
||||
((*cond)->c_mutex != *mutex))) {
|
||||
/* Return invalid argument error: */
|
||||
rval = EINVAL;
|
||||
} else {
|
||||
/* Reset the timeout and interrupted flags: */
|
||||
curthread->timeout = 0;
|
||||
curthread->interrupted = 0;
|
||||
|
||||
/*
|
||||
* Queue the running thread for the condition
|
||||
* variable:
|
||||
*/
|
||||
cond_queue_enq(*cond, curthread);
|
||||
|
||||
/* Unlock the mutex: */
|
||||
if (mutex_locked &&
|
||||
((rval = _mutex_cv_unlock(mutex)) != 0)) {
|
||||
/*
|
||||
* Cannot unlock the mutex; remove the
|
||||
* running thread from the condition
|
||||
* variable queue:
|
||||
*/
|
||||
cond_queue_remove(*cond, curthread);
|
||||
} else {
|
||||
/* Remember the mutex: */
|
||||
(*cond)->c_mutex = *mutex;
|
||||
|
||||
/*
|
||||
* Don't unlock the mutex the next
|
||||
* time through the loop (if the
|
||||
* thread has to be requeued after
|
||||
* handling a signal).
|
||||
*/
|
||||
mutex_locked = 0;
|
||||
|
||||
/*
|
||||
* This thread is active and is in a
|
||||
* critical region (holding the cv
|
||||
* lock); we should be able to safely
|
||||
* set the state.
|
||||
*/
|
||||
THR_SCHED_LOCK(curthread, curthread);
|
||||
/* Set the wakeup time: */
|
||||
curthread->wakeup_time.tv_sec =
|
||||
abstime->tv_sec;
|
||||
curthread->wakeup_time.tv_nsec =
|
||||
abstime->tv_nsec;
|
||||
THR_SET_STATE(curthread, PS_COND_WAIT);
|
||||
|
||||
/* Remember the CV: */
|
||||
curthread->data.cond = *cond;
|
||||
curthread->sigbackout = cond_wait_backout;
|
||||
THR_SCHED_UNLOCK(curthread, curthread);
|
||||
|
||||
/* Unlock the CV structure: */
|
||||
THR_LOCK_RELEASE(curthread,
|
||||
&(*cond)->c_lock);
|
||||
|
||||
/* Schedule the next thread: */
|
||||
_thr_sched_switch(curthread);
|
||||
|
||||
/*
|
||||
* XXX - This really isn't a good check
|
||||
* since there can be more than one
|
||||
* thread waiting on the CV. Signals
|
||||
* sent to threads waiting on mutexes
|
||||
* or CVs should really be deferred
|
||||
* until the threads are no longer
|
||||
* waiting, but POSIX says that signals
|
||||
* should be sent "as soon as possible".
|
||||
*/
|
||||
done = (seqno != (*cond)->c_seqno);
|
||||
if (done && !THR_IN_CONDQ(curthread)) {
|
||||
/*
|
||||
* The thread is dequeued, so
|
||||
* it is safe to clear these.
|
||||
*/
|
||||
curthread->data.cond = NULL;
|
||||
curthread->sigbackout = NULL;
|
||||
check_continuation(curthread,
|
||||
NULL, mutex);
|
||||
return (_mutex_cv_lock(mutex));
|
||||
}
|
||||
|
||||
/* Relock the CV structure: */
|
||||
THR_LOCK_ACQUIRE(curthread,
|
||||
&(*cond)->c_lock);
|
||||
|
||||
/*
|
||||
* Clear these after taking the lock to
|
||||
* prevent a race condition where a
|
||||
* signal can arrive before dequeueing
|
||||
* the thread.
|
||||
*/
|
||||
curthread->data.cond = NULL;
|
||||
curthread->sigbackout = NULL;
|
||||
|
||||
done = (seqno != (*cond)->c_seqno);
|
||||
|
||||
if (THR_IN_CONDQ(curthread)) {
|
||||
cond_queue_remove(*cond,
|
||||
curthread);
|
||||
|
||||
/* Check for no more waiters: */
|
||||
if (TAILQ_EMPTY(&(*cond)->c_queue))
|
||||
(*cond)->c_mutex = NULL;
|
||||
}
|
||||
|
||||
if (curthread->timeout != 0) {
|
||||
/* The wait timedout. */
|
||||
rval = ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Trap invalid condition variable types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
rval = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
check_continuation(curthread, *cond,
|
||||
mutex_locked ? NULL : mutex);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
/* Unlock the condition variable structure: */
|
||||
THR_LOCK_RELEASE(curthread, &(*cond)->c_lock);
|
||||
|
||||
if (mutex_locked == 0)
|
||||
_mutex_cv_lock(mutex);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
__pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int ret;
|
||||
|
||||
_thr_cancel_enter(curthread);
|
||||
ret = _pthread_cond_timedwait(cond, mutex, abstime);
|
||||
_thr_cancel_leave(curthread, 1);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_pthread_cond_signal(pthread_cond_t * cond)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
struct pthread *pthread;
|
||||
struct kse_mailbox *kmbx;
|
||||
int rval = 0;
|
||||
|
||||
THR_ASSERT(curthread->locklevel == 0,
|
||||
"cv_timedwait: locklevel is not zero!");
|
||||
if (cond == NULL)
|
||||
rval = EINVAL;
|
||||
/*
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
else if (*cond != NULL || (rval = _pthread_cond_init(cond, NULL)) == 0) {
|
||||
/* Lock the condition variable structure: */
|
||||
THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock);
|
||||
|
||||
/* Process according to condition variable type: */
|
||||
switch ((*cond)->c_type) {
|
||||
/* Fast condition variable: */
|
||||
case COND_TYPE_FAST:
|
||||
/* Increment the sequence number: */
|
||||
(*cond)->c_seqno++;
|
||||
|
||||
/*
|
||||
* Wakeups have to be done with the CV lock held;
|
||||
* otherwise there is a race condition where the
|
||||
* thread can timeout, run on another KSE, and enter
|
||||
* another blocking state (including blocking on a CV).
|
||||
*/
|
||||
if ((pthread = TAILQ_FIRST(&(*cond)->c_queue))
|
||||
!= NULL) {
|
||||
THR_SCHED_LOCK(curthread, pthread);
|
||||
cond_queue_remove(*cond, pthread);
|
||||
pthread->sigbackout = NULL;
|
||||
if ((pthread->kseg == curthread->kseg) &&
|
||||
(pthread->active_priority >
|
||||
curthread->active_priority))
|
||||
curthread->critical_yield = 1;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
THR_SCHED_UNLOCK(curthread, pthread);
|
||||
if (kmbx != NULL)
|
||||
kse_wakeup(kmbx);
|
||||
}
|
||||
/* Check for no more waiters: */
|
||||
if (TAILQ_EMPTY(&(*cond)->c_queue))
|
||||
(*cond)->c_mutex = NULL;
|
||||
break;
|
||||
|
||||
/* Trap invalid condition variable types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
rval = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unlock the condition variable structure: */
|
||||
THR_LOCK_RELEASE(curthread, &(*cond)->c_lock);
|
||||
}
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
__strong_reference(_pthread_cond_signal, _thr_cond_signal);
|
||||
|
||||
int
|
||||
_pthread_cond_broadcast(pthread_cond_t * cond)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
struct pthread *pthread;
|
||||
struct kse_mailbox *kmbx;
|
||||
int rval = 0;
|
||||
|
||||
THR_ASSERT(curthread->locklevel == 0,
|
||||
"cv_timedwait: locklevel is not zero!");
|
||||
if (cond == NULL)
|
||||
rval = EINVAL;
|
||||
/*
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
else if (*cond != NULL || (rval = _pthread_cond_init(cond, NULL)) == 0) {
|
||||
/* Lock the condition variable structure: */
|
||||
THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock);
|
||||
|
||||
/* Process according to condition variable type: */
|
||||
switch ((*cond)->c_type) {
|
||||
/* Fast condition variable: */
|
||||
case COND_TYPE_FAST:
|
||||
/* Increment the sequence number: */
|
||||
(*cond)->c_seqno++;
|
||||
|
||||
/*
|
||||
* Enter a loop to bring all threads off the
|
||||
* condition queue:
|
||||
*/
|
||||
while ((pthread = TAILQ_FIRST(&(*cond)->c_queue))
|
||||
!= NULL) {
|
||||
THR_SCHED_LOCK(curthread, pthread);
|
||||
cond_queue_remove(*cond, pthread);
|
||||
pthread->sigbackout = NULL;
|
||||
if ((pthread->kseg == curthread->kseg) &&
|
||||
(pthread->active_priority >
|
||||
curthread->active_priority))
|
||||
curthread->critical_yield = 1;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
THR_SCHED_UNLOCK(curthread, pthread);
|
||||
if (kmbx != NULL)
|
||||
kse_wakeup(kmbx);
|
||||
}
|
||||
|
||||
/* There are no more waiting threads: */
|
||||
(*cond)->c_mutex = NULL;
|
||||
break;
|
||||
|
||||
/* Trap invalid condition variable types: */
|
||||
default:
|
||||
/* Return an invalid argument error: */
|
||||
rval = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unlock the condition variable structure: */
|
||||
THR_LOCK_RELEASE(curthread, &(*cond)->c_lock);
|
||||
}
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
__strong_reference(_pthread_cond_broadcast, _thr_cond_broadcast);
|
||||
|
||||
static inline void
|
||||
check_continuation(struct pthread *curthread, struct pthread_cond *cond,
|
||||
pthread_mutex_t *mutex)
|
||||
{
|
||||
if ((curthread->interrupted != 0) &&
|
||||
(curthread->continuation != NULL)) {
|
||||
if (cond != NULL)
|
||||
/* Unlock the condition variable structure: */
|
||||
THR_LOCK_RELEASE(curthread, &cond->c_lock);
|
||||
/*
|
||||
* Note that even though this thread may have been
|
||||
* canceled, POSIX requires that the mutex be
|
||||
* reaquired prior to cancellation.
|
||||
*/
|
||||
if (mutex != NULL)
|
||||
_mutex_cv_lock(mutex);
|
||||
curthread->continuation((void *) curthread);
|
||||
PANIC("continuation returned in pthread_cond_wait.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cond_wait_backout(void *arg)
|
||||
{
|
||||
struct pthread *curthread = (struct pthread *)arg;
|
||||
pthread_cond_t cond;
|
||||
|
||||
cond = curthread->data.cond;
|
||||
if (cond != NULL) {
|
||||
/* Lock the condition variable structure: */
|
||||
THR_LOCK_ACQUIRE(curthread, &cond->c_lock);
|
||||
|
||||
/* Process according to condition variable type: */
|
||||
switch (cond->c_type) {
|
||||
/* Fast condition variable: */
|
||||
case COND_TYPE_FAST:
|
||||
cond_queue_remove(cond, curthread);
|
||||
|
||||
/* Check for no more waiters: */
|
||||
if (TAILQ_EMPTY(&cond->c_queue))
|
||||
cond->c_mutex = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unlock the condition variable structure: */
|
||||
THR_LOCK_RELEASE(curthread, &cond->c_lock);
|
||||
}
|
||||
/* No need to call this again. */
|
||||
curthread->sigbackout = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dequeue a waiting thread from the head of a condition queue in
|
||||
* descending priority order.
|
||||
*/
|
||||
static inline struct pthread *
|
||||
cond_queue_deq(pthread_cond_t cond)
|
||||
{
|
||||
struct pthread *pthread;
|
||||
|
||||
while ((pthread = TAILQ_FIRST(&cond->c_queue)) != NULL) {
|
||||
TAILQ_REMOVE(&cond->c_queue, pthread, sqe);
|
||||
THR_CONDQ_CLEAR(pthread);
|
||||
if ((pthread->timeout == 0) && (pthread->interrupted == 0))
|
||||
/*
|
||||
* Only exit the loop when we find a thread
|
||||
* that hasn't timed out or been canceled;
|
||||
* those threads are already running and don't
|
||||
* need their run state changed.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
return (pthread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a waiting thread from a condition queue in descending priority
|
||||
* order.
|
||||
*/
|
||||
static inline void
|
||||
cond_queue_remove(pthread_cond_t cond, struct pthread *pthread)
|
||||
{
|
||||
/*
|
||||
* Because pthread_cond_timedwait() can timeout as well
|
||||
* as be signaled by another thread, it is necessary to
|
||||
* guard against removing the thread from the queue if
|
||||
* it isn't in the queue.
|
||||
*/
|
||||
if (THR_IN_CONDQ(pthread)) {
|
||||
TAILQ_REMOVE(&cond->c_queue, pthread, sqe);
|
||||
THR_CONDQ_CLEAR(pthread);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enqueue a waiting thread to a condition queue in descending priority
|
||||
* order.
|
||||
*/
|
||||
static inline void
|
||||
cond_queue_enq(pthread_cond_t cond, struct pthread *pthread)
|
||||
{
|
||||
struct pthread *tid = TAILQ_LAST(&cond->c_queue, cond_head);
|
||||
|
||||
THR_ASSERT(!THR_IN_SYNCQ(pthread),
|
||||
"cond_queue_enq: thread already queued!");
|
||||
|
||||
/*
|
||||
* For the common case of all threads having equal priority,
|
||||
* we perform a quick check against the priority of the thread
|
||||
* at the tail of the queue.
|
||||
*/
|
||||
if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
|
||||
TAILQ_INSERT_TAIL(&cond->c_queue, pthread, sqe);
|
||||
else {
|
||||
tid = TAILQ_FIRST(&cond->c_queue);
|
||||
while (pthread->active_priority <= tid->active_priority)
|
||||
tid = TAILQ_NEXT(tid, sqe);
|
||||
TAILQ_INSERT_BEFORE(tid, pthread, sqe);
|
||||
}
|
||||
THR_CONDQ_SET(pthread);
|
||||
pthread->data.cond = cond;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user