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:
brooks 2014-04-16 17:12:59 +00:00
parent 21fced0602
commit 4739008eab
179 changed files with 0 additions and 27209 deletions

View File

@ -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>

View File

@ -1,3 +0,0 @@
# $FreeBSD$
SRCS+= context.S enter_uts.S pthread_md.c

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -1,5 +0,0 @@
# $FreeBSD$
CFLAGS+=-DSYSTEM_SCOPE_ONLY
SRCS+= pthread_md.c context.S

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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_ */

View File

@ -1,3 +0,0 @@
# $FreeBSD$
SRCS+= thr_enter_uts.S thr_getcontext.S pthread_md.c

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,3 +0,0 @@
# $FreeBSD$
SRCS+= context.S enter_uts.S pthread_md.c

View File

@ -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)

View File

@ -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)

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -1,6 +0,0 @@
# $FreeBSD$
# XXX temporary
CFLAGS+=-DSYSTEM_SCOPE_ONLY
SRCS+= enter_uts.S context.S pthread_md.c

View File

@ -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

View File

@ -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_ */

View File

@ -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]));

View File

@ -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

View File

@ -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

View File

@ -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) */

View File

@ -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);
}

View File

@ -1,3 +0,0 @@
# $FreeBSD$
SRCS+= pthread_md.c thr_getcontext.S

View File

@ -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

View File

@ -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_ */

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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;
};

View File

@ -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}

View File

@ -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);

View File

@ -1,5 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/sys
SRCS+= lock.c thr_error.c

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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.

View File

@ -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*)&top;
}
/*
* 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;
}

View File

@ -1,4 +0,0 @@
# $FreeBSD$
Test begin
No overflow:
Overflow:

View File

@ -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";
}
}
}
}

View File

@ -1,13 +0,0 @@
/****************************************************************************
*
* Back end C programs can be anything compilable.
*
* $FreeBSD$
*
****************************************************************************/
int
main()
{
return 0;
}

View File

@ -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;
}

View File

@ -1,2 +0,0 @@
# $FreeBSD$
Hello world

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,3 +0,0 @@
# $FreeBSD$
Test begin
Test end

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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";
}

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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