diff options
author | obrien <obrien@FreeBSD.org> | 2007-10-09 14:16:39 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2007-10-09 14:16:39 +0000 |
commit | 9724a293f7f7df7e791661a0a5159fe124c80f7d (patch) | |
tree | d0edefa18994441e9444e6531011f2a5d5cf29b6 | |
parent | eb3f6a9e7473ee9d6e8016ce8d9cc1e8286bdd98 (diff) | |
download | FreeBSD-src-9724a293f7f7df7e791661a0a5159fe124c80f7d.zip FreeBSD-src-9724a293f7f7df7e791661a0a5159fe124c80f7d.tar.gz |
Repo copy libpthreads to libkse.
This introduces the WITHOUT_LIBKSE nob,
and changes WITHOUT_LIBPTHREADS to mean with neither threading libs.
Approved by: re(kensmith)
177 files changed, 0 insertions, 26833 deletions
diff --git a/lib/libpthread/arch/amd64/Makefile.inc b/lib/libpthread/arch/amd64/Makefile.inc deleted file mode 100644 index c8b0362..0000000 --- a/lib/libpthread/arch/amd64/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH} - -SRCS+= context.S enter_uts.S pthread_md.c diff --git a/lib/libpthread/arch/amd64/amd64/context.S b/lib/libpthread/arch/amd64/amd64/context.S deleted file mode 100644 index 6a6b558..0000000 --- a/lib/libpthread/arch/amd64/amd64/context.S +++ /dev/null @@ -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 - diff --git a/lib/libpthread/arch/amd64/amd64/enter_uts.S b/lib/libpthread/arch/amd64/amd64/enter_uts.S deleted file mode 100644 index fb0df87..0000000 --- a/lib/libpthread/arch/amd64/amd64/enter_uts.S +++ /dev/null @@ -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 diff --git a/lib/libpthread/arch/amd64/amd64/pthread_md.c b/lib/libpthread/arch/amd64/amd64/pthread_md.c deleted file mode 100644 index 3aceec7..0000000 --- a/lib/libpthread/arch/amd64/amd64/pthread_md.c +++ /dev/null @@ -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); -} diff --git a/lib/libpthread/arch/amd64/include/atomic_ops.h b/lib/libpthread/arch/amd64/include/atomic_ops.h deleted file mode 100644 index 980eb8e..0000000 --- a/lib/libpthread/arch/amd64/include/atomic_ops.h +++ /dev/null @@ -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(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(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((intptr_t *)(d), (intptr_t)(v), (intptr_t *)(r)) - -#endif diff --git a/lib/libpthread/arch/amd64/include/pthread_md.h b/lib/libpthread/arch/amd64/include/pthread_md.h deleted file mode 100644 index a7da5df..0000000 --- a/lib/libpthread/arch/amd64/include/pthread_md.h +++ /dev/null @@ -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 *)&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 diff --git a/lib/libpthread/arch/arm/Makefile.inc b/lib/libpthread/arch/arm/Makefile.inc deleted file mode 100644 index ced7063..0000000 --- a/lib/libpthread/arch/arm/Makefile.inc +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH} - -CFLAGS+=-DSYSTEM_SCOPE_ONLY - -SRCS+= pthread_md.c context.S diff --git a/lib/libpthread/arch/arm/arm/context.S b/lib/libpthread/arch/arm/arm/context.S deleted file mode 100644 index c638804..0000000 --- a/lib/libpthread/arch/arm/arm/context.S +++ /dev/null @@ -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 diff --git a/lib/libpthread/arch/arm/arm/pthread_md.c b/lib/libpthread/arch/arm/arm/pthread_md.c deleted file mode 100644 index 72426d4..0000000 --- a/lib/libpthread/arch/arm/arm/pthread_md.c +++ /dev/null @@ -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); -} diff --git a/lib/libpthread/arch/arm/include/atomic_ops.h b/lib/libpthread/arch/arm/include/atomic_ops.h deleted file mode 100644 index 3a209b3..0000000 --- a/lib/libpthread/arch/arm/include/atomic_ops.h +++ /dev/null @@ -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(intptr_t *dst, intptr_t val, intptr_t *res) -{ - *res = __swp(val, dst); -} - -#define atomic_swap_ptr(d, v, r) \ - atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r) - -#define atomic_swap_int(d, v, r) \ - atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r) -#endif - diff --git a/lib/libpthread/arch/arm/include/pthread_md.h b/lib/libpthread/arch/arm/include/pthread_md.h deleted file mode 100644 index 857fa1b..0000000 --- a/lib/libpthread/arch/arm/include/pthread_md.h +++ /dev/null @@ -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_ */ diff --git a/lib/libpthread/arch/i386/Makefile.inc b/lib/libpthread/arch/i386/Makefile.inc deleted file mode 100644 index 73a9a8a..0000000 --- a/lib/libpthread/arch/i386/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH} - -SRCS+= thr_enter_uts.S thr_getcontext.S pthread_md.c diff --git a/lib/libpthread/arch/i386/i386/pthread_md.c b/lib/libpthread/arch/i386/i386/pthread_md.c deleted file mode 100644 index cbea6d4..0000000 --- a/lib/libpthread/arch/i386/i386/pthread_md.c +++ /dev/null @@ -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)); -} diff --git a/lib/libpthread/arch/i386/i386/thr_enter_uts.S b/lib/libpthread/arch/i386/i386/thr_enter_uts.S deleted file mode 100644 index bf6df8f..0000000 --- a/lib/libpthread/arch/i386/i386/thr_enter_uts.S +++ /dev/null @@ -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 diff --git a/lib/libpthread/arch/i386/i386/thr_getcontext.S b/lib/libpthread/arch/i386/i386/thr_getcontext.S deleted file mode 100644 index d9d300f..0000000 --- a/lib/libpthread/arch/i386/i386/thr_getcontext.S +++ /dev/null @@ -1,156 +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 CNAME(_thr_setcontext) - .set CNAME(_thr_setcontext),CNAME(__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 CNAME(_thr_getcontext) - .set CNAME(_thr_getcontext),CNAME(__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 diff --git a/lib/libpthread/arch/i386/include/atomic_ops.h b/lib/libpthread/arch/i386/include/atomic_ops.h deleted file mode 100644 index 7bc3d1b..0000000 --- a/lib/libpthread/arch/i386/include/atomic_ops.h +++ /dev/null @@ -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(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((intptr_t *)d, (intptr_t)v, (intptr_t *)r) - -#define atomic_swap_int(d, v, r) \ - atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r) -#endif diff --git a/lib/libpthread/arch/i386/include/pthread_md.h b/lib/libpthread/arch/i386/include/pthread_md.h deleted file mode 100644 index 52afd6a..0000000 --- a/lib/libpthread/arch/i386/include/pthread_md.h +++ /dev/null @@ -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 *)&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 diff --git a/lib/libpthread/arch/ia64/Makefile.inc b/lib/libpthread/arch/ia64/Makefile.inc deleted file mode 100644 index c8b0362..0000000 --- a/lib/libpthread/arch/ia64/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH} - -SRCS+= context.S enter_uts.S pthread_md.c diff --git a/lib/libpthread/arch/ia64/ia64/context.S b/lib/libpthread/arch/ia64/ia64/context.S deleted file mode 100644 index 9411293..0000000 --- a/lib/libpthread/arch/ia64/ia64/context.S +++ /dev/null @@ -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) diff --git a/lib/libpthread/arch/ia64/ia64/enter_uts.S b/lib/libpthread/arch/ia64/ia64/enter_uts.S deleted file mode 100644 index 5df4d93..0000000 --- a/lib/libpthread/arch/ia64/ia64/enter_uts.S +++ /dev/null @@ -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) diff --git a/lib/libpthread/arch/ia64/ia64/pthread_md.c b/lib/libpthread/arch/ia64/ia64/pthread_md.c deleted file mode 100644 index dc59b0e..0000000 --- a/lib/libpthread/arch/ia64/ia64/pthread_md.c +++ /dev/null @@ -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); -} diff --git a/lib/libpthread/arch/ia64/include/atomic_ops.h b/lib/libpthread/arch/ia64/include/atomic_ops.h deleted file mode 100644 index 483c905..0000000 --- a/lib/libpthread/arch/ia64/include/atomic_ops.h +++ /dev/null @@ -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(int *dst, int val, int *res) -{ - __asm("xchg4 %0=[%2],%1" : "=r"(*res) : "r"(val), "r"(dst)); -} - -static inline void -atomic_swap_long(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((long*)d, (long)v, (long*)r) - -#endif /* _ATOMIC_OPS_H_ */ diff --git a/lib/libpthread/arch/ia64/include/pthread_md.h b/lib/libpthread/arch/ia64/include/pthread_md.h deleted file mode 100644 index c5fef18..0000000 --- a/lib/libpthread/arch/ia64/include/pthread_md.h +++ /dev/null @@ -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() -{ - 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_ */ diff --git a/lib/libpthread/arch/powerpc/Makefile.inc b/lib/libpthread/arch/powerpc/Makefile.inc deleted file mode 100644 index f4417a6..0000000 --- a/lib/libpthread/arch/powerpc/Makefile.inc +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -# XXX temporary -CFLAGS+=-DSYSTEM_SCOPE_ONLY - -.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH} - -SRCS+= enter_uts.S context.S pthread_md.c diff --git a/lib/libpthread/arch/powerpc/include/atomic_ops.h b/lib/libpthread/arch/powerpc/include/atomic_ops.h deleted file mode 100644 index 8068e6f..0000000 --- a/lib/libpthread/arch/powerpc/include/atomic_ops.h +++ /dev/null @@ -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(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((intptr_t *)d, (intptr_t)v, (intptr_t *)r) - -#define atomic_swap_int(d, v, r) \ - atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r) -#endif diff --git a/lib/libpthread/arch/powerpc/include/pthread_md.h b/lib/libpthread/arch/powerpc/include/pthread_md.h deleted file mode 100644 index 2b13e4b..0000000 --- a/lib/libpthread/arch/powerpc/include/pthread_md.h +++ /dev/null @@ -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() -{ - 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() -{ - 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 *)&kcb->kcb_kmbx.km_curthread); - else - _ppc32_setcontext(mc, 0, NULL); - } - - /* We should not reach here. */ - return (-1); -} - -#endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libpthread/arch/powerpc/powerpc/assym.c b/lib/libpthread/arch/powerpc/powerpc/assym.c deleted file mode 100644 index a8479e7..0000000 --- a/lib/libpthread/arch/powerpc/powerpc/assym.c +++ /dev/null @@ -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])); diff --git a/lib/libpthread/arch/powerpc/powerpc/assym.s b/lib/libpthread/arch/powerpc/powerpc/assym.s deleted file mode 100644 index 7017c15..0000000 --- a/lib/libpthread/arch/powerpc/powerpc/assym.s +++ /dev/null @@ -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 - diff --git a/lib/libpthread/arch/powerpc/powerpc/context.S b/lib/libpthread/arch/powerpc/powerpc/context.S deleted file mode 100644 index 34d175a..0000000 --- a/lib/libpthread/arch/powerpc/powerpc/context.S +++ /dev/null @@ -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 diff --git a/lib/libpthread/arch/powerpc/powerpc/enter_uts.S b/lib/libpthread/arch/powerpc/powerpc/enter_uts.S deleted file mode 100644 index 7cc4d7f..0000000 --- a/lib/libpthread/arch/powerpc/powerpc/enter_uts.S +++ /dev/null @@ -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) */ diff --git a/lib/libpthread/arch/powerpc/powerpc/pthread_md.c b/lib/libpthread/arch/powerpc/powerpc/pthread_md.c deleted file mode 100644 index 7aa5ee9..0000000 --- a/lib/libpthread/arch/powerpc/powerpc/pthread_md.c +++ /dev/null @@ -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); -} diff --git a/lib/libpthread/arch/sparc64/Makefile.inc b/lib/libpthread/arch/sparc64/Makefile.inc deleted file mode 100644 index 07107b4..0000000 --- a/lib/libpthread/arch/sparc64/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH} - -SRCS+= pthread_md.c thr_getcontext.S diff --git a/lib/libpthread/arch/sparc64/include/atomic_ops.h b/lib/libpthread/arch/sparc64/include/atomic_ops.h deleted file mode 100644 index 4f4d8af..0000000 --- a/lib/libpthread/arch/sparc64/include/atomic_ops.h +++ /dev/null @@ -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(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(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((long *)dst, (long)val, (long *)res) - -#endif diff --git a/lib/libpthread/arch/sparc64/include/pthread_md.h b/lib/libpthread/arch/sparc64/include/pthread_md.h deleted file mode 100644 index fac62c2..0000000 --- a/lib/libpthread/arch/sparc64/include/pthread_md.h +++ /dev/null @@ -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 *)&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_ */ diff --git a/lib/libpthread/arch/sparc64/sparc64/assym.s b/lib/libpthread/arch/sparc64/sparc64/assym.s deleted file mode 100644 index 3e22c9f..0000000 --- a/lib/libpthread/arch/sparc64/sparc64/assym.s +++ /dev/null @@ -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 diff --git a/lib/libpthread/arch/sparc64/sparc64/pthread_md.c b/lib/libpthread/arch/sparc64/sparc64/pthread_md.c deleted file mode 100644 index d6bf95d..0000000 --- a/lib/libpthread/arch/sparc64/sparc64/pthread_md.c +++ /dev/null @@ -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); -} diff --git a/lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S b/lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S deleted file mode 100644 index ca6473a..0000000 --- a/lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S +++ /dev/null @@ -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) diff --git a/lib/libpthread/support/Makefile.inc b/lib/libpthread/support/Makefile.inc deleted file mode 100644 index 956667f..0000000 --- a/lib/libpthread/support/Makefile.inc +++ /dev/null @@ -1,40 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/support ${.CURDIR}/../libc/gen ${.CURDIR}/../libc/string -.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys - -CFLAGS+= -I${.CURDIR}/../libc/${MACHINE_ARCH} - -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} - diff --git a/lib/libpthread/support/thr_support.c b/lib/libpthread/support/thr_support.c deleted file mode 100644 index 2956e07..0000000 --- a/lib/libpthread/support/thr_support.c +++ /dev/null @@ -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); - diff --git a/lib/libpthread/sys/Makefile.inc b/lib/libpthread/sys/Makefile.inc deleted file mode 100644 index fb4a108..0000000 --- a/lib/libpthread/sys/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/sys - -SRCS+= lock.c thr_error.c diff --git a/lib/libpthread/sys/lock.c b/lib/libpthread/sys/lock.c deleted file mode 100644 index 2ac8c0c..0000000 --- a/lib/libpthread/sys/lock.c +++ /dev/null @@ -1,351 +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) -{ - if (lck == NULL) - return (-1); - else if ((lck->l_head = malloc(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)); - 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); - /* - * 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; - if (lu->lu_myreq == NULL) - 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(&lck->l_head, lu->lu_myreq, &lu->lu_watchreq); - - if (lu->lu_watchreq->lr_locked != 0) { - atomic_store_rel_ptr - ((volatile uintptr_t *)&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((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 *)&lck->l_tail, - (uintptr_t)lu->lu_myreq); - atomic_store_rel_ptr - ((volatile uintptr_t *)&lu->lu_myreq->lr_owner, - (uintptr_t)NULL); - } else { - /* Remove ourselves from the list. */ - atomic_store_rel_ptr((volatile uintptr_t *) - &lu->lu_myreq->lr_owner, - (uintptr_t)lu->lu_watchreq->lr_owner); - atomic_store_rel_ptr((volatile uintptr_t *) - &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( - (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((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((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 */, 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; -} - diff --git a/lib/libpthread/sys/lock.h b/lib/libpthread/sys/lock.h deleted file mode 100644 index 6102a0b..0000000 --- a/lib/libpthread/sys/lock.h +++ /dev/null @@ -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 *); -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 diff --git a/lib/libpthread/sys/thr_error.c b/lib/libpthread/sys/thr_error.c deleted file mode 100644 index 0ba34e0..0000000 --- a/lib/libpthread/sys/thr_error.c +++ /dev/null @@ -1,61 +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 <pthread.h> -#include "libc_private.h" -#include "thr_private.h" - -#undef errno -extern int errno; - -LT10_COMPAT_DEFAULT(__error); - -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); - } -} diff --git a/lib/libpthread/test/Makefile b/lib/libpthread/test/Makefile deleted file mode 100644 index 5b5eb3c..0000000 --- a/lib/libpthread/test/Makefile +++ /dev/null @@ -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 diff --git a/lib/libpthread/test/README b/lib/libpthread/test/README deleted file mode 100644 index 8f625a1..0000000 --- a/lib/libpthread/test/README +++ /dev/null @@ -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. diff --git a/lib/libpthread/test/guard_b.c b/lib/libpthread/test/guard_b.c deleted file mode 100644 index 2e27031..0000000 --- a/lib/libpthread/test/guard_b.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - * Test thread stack guard functionality. - */ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <pthread.h> - -#define FRAME_SIZE 1024 -#define FRAME_OVERHEAD 40 - -struct args -{ - void *top; /* Top of thread's initial stack frame. */ - int cur; /* Recursion depth. */ - int max; /* Maximum recursion depth. */ -}; - -void * -recurse(void *args) -{ - int top; - struct args *parms = (struct args *)args; - char filler[FRAME_SIZE - FRAME_OVERHEAD]; - - /* Touch the memory in this stack frame. */ - top = 0xa5; - memset(filler, 0xa5, sizeof(filler)); - - if (parms->top == NULL) { - /* Initial stack frame. */ - parms->top = (void*)⊤ - } - - /* - * Make sure frame size is what we expect. Getting this right involves - * hand tweaking, so just print a warning rather than aborting. - */ - if (parms->top - (void *)&top != FRAME_SIZE * parms->cur) { - fprintf(stderr, - "Stack size (%ld) != expected (%ld), frame %ld\n", - (long)parms->top - (long)&top, - (long)(FRAME_SIZE * parms->cur), (long)parms->cur); - } - - parms->cur++; - if (parms->cur < parms->max) - recurse(args); - - return NULL; -} - - -int -main(int argc, char **argv) -{ - size_t def_stacksize, def_guardsize; - size_t stacksize, guardsize; - pthread_t thread; - pthread_attr_t attr; - struct args args; - - if (argc != 3) { - fprintf(stderr, "usage: guard_b <stacksize> <guardsize>\n"); - exit(1); - } - fprintf(stderr, "Test begin\n"); - - stacksize = strtoul(argv[1], NULL, 10); - guardsize = strtoul(argv[2], NULL, 10); - - assert(pthread_attr_init(&attr) == 0); - /* - * Exercise the attribute APIs more thoroughly than is strictly - * necessary for the meat of this test program. - */ - assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0); - assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0); - if (def_stacksize != stacksize) { - assert(pthread_attr_setstacksize(&attr, stacksize) == 0); - assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0); - assert(def_stacksize == stacksize); - } - if (def_guardsize != guardsize) { - assert(pthread_attr_setguardsize(&attr, guardsize) == 0); - assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0); - assert(def_guardsize >= guardsize); - } - - /* - * Create a thread that will come just short of overflowing the thread - * stack. We need to leave a bit of breathing room in case the thread - * is context switched, and we also have to take care not to call any - * functions in the deepest stack frame. - */ - args.top = NULL; - args.cur = 0; - args.max = (stacksize / FRAME_SIZE) - 1; - fprintf(stderr, "No overflow:\n"); - assert(pthread_create(&thread, &attr, recurse, &args) == 0); - assert(pthread_join(thread, NULL) == 0); - - /* - * Create a thread that will barely of overflow the thread stack. This - * should cause a segfault. - */ - args.top = NULL; - args.cur = 0; - args.max = (stacksize / FRAME_SIZE) + 1; - fprintf(stderr, "Overflow:\n"); - assert(pthread_create(&thread, &attr, recurse, &args) == 0); - assert(pthread_join(thread, NULL) == 0); - - /* Not reached. */ - fprintf(stderr, "Unexpected success\n"); - abort(); - - return 0; -} diff --git a/lib/libpthread/test/guard_b.exp b/lib/libpthread/test/guard_b.exp deleted file mode 100644 index 8e5b9e4..0000000 --- a/lib/libpthread/test/guard_b.exp +++ /dev/null @@ -1,3 +0,0 @@ -Test begin -No overflow: -Overflow: diff --git a/lib/libpthread/test/guard_s.pl b/lib/libpthread/test/guard_s.pl deleted file mode 100755 index 7802ff3..0000000 --- a/lib/libpthread/test/guard_s.pl +++ /dev/null @@ -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"; - } - } - } -} diff --git a/lib/libpthread/test/hello_b.c b/lib/libpthread/test/hello_b.c deleted file mode 100644 index 2eefa7f..0000000 --- a/lib/libpthread/test/hello_b.c +++ /dev/null @@ -1,13 +0,0 @@ -/**************************************************************************** - * - * Back end C programs can be anything compilable. - * - * $FreeBSD$ - * - ****************************************************************************/ - -int -main() -{ - return 0; -} diff --git a/lib/libpthread/test/hello_d.c b/lib/libpthread/test/hello_d.c deleted file mode 100644 index 6d77526..0000000 --- a/lib/libpthread/test/hello_d.c +++ /dev/null @@ -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; -} diff --git a/lib/libpthread/test/hello_d.exp b/lib/libpthread/test/hello_d.exp deleted file mode 100644 index 802992c..0000000 --- a/lib/libpthread/test/hello_d.exp +++ /dev/null @@ -1 +0,0 @@ -Hello world diff --git a/lib/libpthread/test/hello_s.c b/lib/libpthread/test/hello_s.c deleted file mode 100644 index 942bf2d..0000000 --- a/lib/libpthread/test/hello_s.c +++ /dev/null @@ -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; -} diff --git a/lib/libpthread/test/join_leak_d.c b/lib/libpthread/test/join_leak_d.c deleted file mode 100644 index 6532ca5..0000000 --- a/lib/libpthread/test/join_leak_d.c +++ /dev/null @@ -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; -} diff --git a/lib/libpthread/test/join_leak_d.exp b/lib/libpthread/test/join_leak_d.exp deleted file mode 100644 index 369a88d..0000000 --- a/lib/libpthread/test/join_leak_d.exp +++ /dev/null @@ -1,2 +0,0 @@ -Test begin -Test end diff --git a/lib/libpthread/test/mutex_d.c b/lib/libpthread/test/mutex_d.c deleted file mode 100644 index 2aa3b1d..0000000 --- a/lib/libpthread/test/mutex_d.c +++ /dev/null @@ -1,1558 +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 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/time.h> -#include <sys/ioctl.h> -#include <stdlib.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <sched.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <sysexits.h> -#include "pthread.h" - -#if defined(_LIBC_R_) -#include <pthread_np.h> -#endif - -#ifndef NELEMENTS -#define NELEMENTS(arr) (sizeof (arr) / sizeof (arr[0])) -#endif - -#ifndef NUM_THREADS -#define NUM_THREADS 10 -#endif - -#define MAX_THREAD_CMDS 10 - -static void log_error(const char *, ...) __printflike(1, 2); -static void log_trace (const char *, ...) __printflike(1, 2); -static void log (const char *, ...) __printflike(1, 2); - -/*------------------------------------------------------------ - * Types - *----------------------------------------------------------*/ - -typedef enum { - STAT_INITIAL, /* initial state */ - STAT_WAITCONDVAR, /* waiting for condition variable signal */ - STAT_WAITMUTEX /* waiting for mutex lock */ -} thread_status_t; - -typedef enum { - FLAGS_REPORT_WAITCONDMUTEX = 0x01, - FLAGS_REPORT_WAITCONDVAR = 0x02, - FLAGS_REPORT_WAITMUTEX = 0x04, - FLAGS_REPORT_BUSY_LOOP = 0x08, - FLAGS_IS_BUSY = 0x10, - FLAGS_WAS_BUSY = 0x20 -} thread_flags_t; - -typedef enum { - CMD_NONE, - CMD_TAKE_MUTEX, - CMD_RELEASE_MUTEX, - CMD_WAIT_FOR_SIGNAL, - CMD_BUSY_LOOP, - CMD_PROTECTED_OP, - CMD_RELEASE_ALL -} thread_cmd_id_t; - -typedef struct { - thread_cmd_id_t cmd_id; - pthread_mutex_t *mutex; - pthread_cond_t *cond; -} thread_cmd_t; - -typedef struct { - pthread_cond_t cond_var; - thread_status_t status; - thread_cmd_t cmd; - int flags; - int priority; - int ret; - pthread_t tid; - u_int8_t id; -} thread_state_t; - -typedef enum { - M_POSIX, - M_SS2_DEFAULT, - M_SS2_ERRORCHECK, - M_SS2_NORMAL, - M_SS2_RECURSIVE -} mutex_kind_t; - - -/*------------------------------------------------------------ - * Constants - *----------------------------------------------------------*/ - -const char *protocol_strs[] = { - "PTHREAD_PRIO_NONE", - "PTHREAD_PRIO_INHERIT", - "PTHREAD_PRIO_PROTECT" -}; - -const int protocols[] = { - PTHREAD_PRIO_NONE, - PTHREAD_PRIO_INHERIT, - PTHREAD_PRIO_PROTECT -}; - -const char *mutextype_strs[] = { - "POSIX (type not specified)", - "SS2 PTHREAD_MUTEX_DEFAULT", - "SS2 PTHREAD_MUTEX_ERRORCHECK", - "SS2 PTHREAD_MUTEX_NORMAL", - "SS2 PTHREAD_MUTEX_RECURSIVE" -}; - -const int mutex_types[] = { - 0, /* M_POSIX */ - PTHREAD_MUTEX_DEFAULT, /* M_SS2_DEFAULT */ - PTHREAD_MUTEX_ERRORCHECK, /* M_SS2_ERRORCHECK */ - PTHREAD_MUTEX_NORMAL, /* M_SS2_NORMAL */ - PTHREAD_MUTEX_RECURSIVE /* M_SS2_RECURSIVE */ -}; - - -/*------------------------------------------------------------ - * Objects - *----------------------------------------------------------*/ - -static int done = 0; -static int trace_enabled = 0; -static int use_global_condvar = 0; -static thread_state_t states[NUM_THREADS]; -static int pipefd[2]; - -static pthread_mutex_t waiter_mutex; -static pthread_mutex_t cond_mutex; -static pthread_cond_t cond_var; - -static FILE *logfile; -static int error_count = 0, pass_count = 0, total = 0; - - -/*------------------------------------------------------------ - * Prototypes - *----------------------------------------------------------*/ -extern char *strtok_r(char *str, const char *sep, char **last); - - -/*------------------------------------------------------------ - * Functions - *----------------------------------------------------------*/ - -#if defined(_LIBC_R_) && defined(DEBUG) -static void -kern_switch (pthread_t pthread_out, pthread_t pthread_in) -{ - if (pthread_out != NULL) - printf ("Swapping out thread 0x%lx, ", (long) pthread_out); - else - printf ("Swapping out kernel thread, "); - - if (pthread_in != NULL) - printf ("swapping in thread 0x%lx\n", (long) pthread_in); - else - printf ("swapping in kernel thread.\n"); -} -#endif - - -static void -log_error (const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - fprintf (logfile, "FAIL: "); - vfprintf (logfile, fmt, ap); - error_count = error_count + 1; - total = total + 1; -} - - -static void -log_pass (void) -{ - fprintf (logfile, "PASS\n"); - pass_count = pass_count + 1; - total = total + 1; -} - - -static void -log_trace (const char *fmt, ...) -{ - va_list ap; - - if (trace_enabled) { - va_start (ap, fmt); - vfprintf (logfile, fmt, ap); - } -} - - -static void -log (const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - vfprintf (logfile, fmt, ap); -} - - -static void -check_result (int expected, int actual) -{ - if (expected != actual) - log_error ("expected %d, returned %d\n", expected, actual); - else - log_pass (); -} - - -/* - * Check to see that the threads ran in the specified order. - */ -static void -check_run_order (char *order) -{ - const char *sep = ":,"; - char *tok, *last, *idstr, *endptr; - int expected_id, bytes, count = 0, errors = 0; - u_int8_t id; - - assert ((tok = (char *) malloc (strlen(order) + 1)) != NULL); - strcpy (tok, order); /* tok has to be larger than order */ - assert (ioctl (pipefd[0], FIONREAD, &bytes) == 0); - log_trace ("%d bytes read from FIFO.\n", bytes); - - for (idstr = strtok_r (tok, sep, &last); - (idstr != NULL) && (count < bytes); - idstr = strtok_r (NULL, sep, &last)) { - - /* Get the expected id: */ - expected_id = (int) strtol (idstr, &endptr, 10); - assert ((endptr != NULL) && (*endptr == '\0')); - - /* Read the actual id from the pipe: */ - assert (read (pipefd[0], &id, sizeof (id)) == sizeof (id)); - count = count + sizeof (id); - - if (id != expected_id) { - log_trace ("Thread %d ran out of order.\n", id); - errors = errors + 1; - } - else { - log_trace ("Thread %d at priority %d reporting.\n", - (int) id, states[id].priority); - } - } - - if (count < bytes) { - /* Clear the pipe: */ - while (count < bytes) { - read (pipefd[0], &id, sizeof (id)); - count = count + 1; - errors = errors + 1; - } - } - else if (bytes < count) - errors = errors + count - bytes; - - if (errors == 0) - log_pass (); - else - log_error ("%d threads ran out of order", errors); -} - - -static void * -waiter (void *arg) -{ - thread_state_t *statep = (thread_state_t *) arg; - pthread_mutex_t *held_mutex[MAX_THREAD_CMDS]; - int held_mutex_owned[MAX_THREAD_CMDS]; - sigset_t mask; - struct timeval tv1, tv2; - thread_cmd_t cmd; - int i, mutex_count = 0; - - statep->status = STAT_INITIAL; - - /* Block all signals except for interrupt.*/ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_BLOCK, &mask, NULL); - - while (done == 0) { - /* Wait for signal from the main thread to continue. */ - statep->status = STAT_WAITMUTEX; - log_trace ("Thread %d: locking cond_mutex.\n", - (int) statep->id); - pthread_mutex_lock (&cond_mutex); - - /* Do we report our status. */ - if (statep->flags & FLAGS_REPORT_WAITCONDMUTEX) - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: waiting for cond_var.\n", - (int) statep->id); - - /* Wait for a command. */ - statep->status = STAT_WAITCONDVAR; - - /* - * The threads are allowed commanded to wait either on - * their own unique condition variable (so they may be - * separately signaled) or on one global condition variable - * (so they may be signaled together). - */ - if (use_global_condvar != 0) - pthread_cond_wait (&cond_var, &cond_mutex); - else - pthread_cond_wait (&statep->cond_var, &cond_mutex); - - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_WAITCONDVAR) { - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: wrote to pipe.\n", - (int) statep->id); - } - log_trace ("Thread %d: received cond_var signal.\n", - (int) statep->id); - - /* Get a copy of the command before releasing the mutex. */ - cmd = statep->cmd; - - /* Clear the command after copying it. */ - statep->cmd.cmd_id = CMD_NONE; - - /* Unlock the condition variable mutex. */ - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - /* Peform the command.*/ - switch (cmd.cmd_id) { - case CMD_TAKE_MUTEX: - statep->ret = pthread_mutex_lock (cmd.mutex); - if (statep->ret == 0) { - assert (mutex_count < sizeof (held_mutex)); - held_mutex[mutex_count] = cmd.mutex; - held_mutex_owned[mutex_count] = 1; - mutex_count++; - } - else { - held_mutex_owned[mutex_count] = 0; - log_trace ("Thread id %d unable to lock mutex, " - "error = %d\n", (int) statep->id, - statep->ret); - } - break; - - case CMD_RELEASE_MUTEX: - assert ((mutex_count <= sizeof (held_mutex)) && - (mutex_count > 0)); - mutex_count--; - if (held_mutex_owned[mutex_count] != 0) - assert (pthread_mutex_unlock - (held_mutex[mutex_count]) == 0); - break; - - case CMD_WAIT_FOR_SIGNAL: - assert (pthread_mutex_lock (cmd.mutex) == 0); - assert (pthread_cond_wait (cmd.cond, cmd.mutex) == 0); - assert (pthread_mutex_unlock (cmd.mutex) == 0); - break; - - case CMD_BUSY_LOOP: - log_trace ("Thread %d: Entering busy loop.\n", - (int) statep->id); - /* Spin for 15 seconds. */ - assert (gettimeofday (&tv2, NULL) == 0); - tv1.tv_sec = tv2.tv_sec + 5; - tv1.tv_usec = tv2.tv_usec; - statep->flags |= FLAGS_IS_BUSY; - while (timercmp (&tv2, &tv1,<)) { - assert (gettimeofday (&tv2, NULL) == 0); - } - statep->flags &= ~FLAGS_IS_BUSY; - statep->flags |= FLAGS_WAS_BUSY; - - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_BUSY_LOOP) - write (pipefd[1], &statep->id, - sizeof (statep->id)); - - log_trace ("Thread %d: Leaving busy loop.\n", - (int) statep->id); - break; - - case CMD_PROTECTED_OP: - assert (pthread_mutex_lock (cmd.mutex) == 0); - statep->flags |= FLAGS_WAS_BUSY; - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_BUSY_LOOP) - write (pipefd[1], &statep->id, - sizeof (statep->id)); - - assert (pthread_mutex_unlock (cmd.mutex) == 0); - break; - - case CMD_RELEASE_ALL: - assert ((mutex_count <= sizeof (held_mutex)) && - (mutex_count > 0)); - for (i = mutex_count - 1; i >= 0; i--) { - if (held_mutex_owned[i] != 0) - assert (pthread_mutex_unlock - (held_mutex[i]) == 0); - } - mutex_count = 0; - break; - - case CMD_NONE: - default: - break; - } - - /* Wait for the big giant waiter lock. */ - statep->status = STAT_WAITMUTEX; - log_trace ("Thread %d: waiting for big giant lock.\n", - (int) statep->id); - pthread_mutex_lock (&waiter_mutex); - if (statep->flags & FLAGS_REPORT_WAITMUTEX) - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: got big giant lock.\n", - (int) statep->id); - statep->status = STAT_INITIAL; - pthread_mutex_unlock (&waiter_mutex); - } - - log_trace ("Thread %ld: Exiting thread 0x%lx\n", (long) statep->id, - (long) pthread_self()); - pthread_exit (arg); - return (NULL); -} - - -static void * -lock_twice (void *arg) -{ - thread_state_t *statep = (thread_state_t *) arg; - sigset_t mask; - - statep->status = STAT_INITIAL; - - /* Block all signals except for interrupt.*/ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_BLOCK, &mask, NULL); - - /* Wait for a signal to continue. */ - log_trace ("Thread %d: locking cond_mutex.\n", (int) statep->id); - pthread_mutex_lock (&cond_mutex); - - log_trace ("Thread %d: waiting for cond_var.\n", (int) statep->id); - statep->status = STAT_WAITCONDVAR; - pthread_cond_wait (&cond_var, &cond_mutex); - - log_trace ("Thread %d: received cond_var signal.\n", (int) statep->id); - - /* Unlock the condition variable mutex. */ - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - statep->status = STAT_WAITMUTEX; - /* Lock the mutex once. */ - assert (pthread_mutex_lock (statep->cmd.mutex) == 0); - - /* Lock it again and capture the error. */ - statep->ret = pthread_mutex_lock (statep->cmd.mutex); - statep->status = 0; - - assert (pthread_mutex_unlock (statep->cmd.mutex) == 0); - - /* Unlock it again if it is locked recursively. */ - if (statep->ret == 0) - pthread_mutex_unlock (statep->cmd.mutex); - - log_trace ("Thread %ld: Exiting thread 0x%lx\n", (long) statep->id, - (long) pthread_self()); - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - log ("Signal handler caught signal %d, thread id 0x%lx\n", - signo, (long) pthread_self()); - - if (signo == SIGINT) - done = 1; -} - - -static void -send_cmd (int id, thread_cmd_id_t cmd) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = NULL; - states[id].cmd.cond = NULL; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -send_mutex_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = m; - states[id].cmd.cond = NULL; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -send_mutex_cv_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m, - pthread_cond_t *cv) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = m; - states[id].cmd.cond = cv; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -mutex_init_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - mutex_kind_t mkind; - int mproto, ret; - - /* - * Initialize a mutex attribute. - * - * pthread_mutexattr_init not tested for: ENOMEM - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* - * Initialize a mutex. - * - * pthread_mutex_init not tested for: EAGAIN ENOMEM EPERM EBUSY - */ - log ("Testing pthread_mutex_init\n"); - log ("--------------------------\n"); - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - log (" Protocol %s, Type %s - ", - protocol_strs[mproto], mutextype_strs[mkind]); - ret = pthread_mutex_init (&mutex, &mattr); - check_result (/* expected */ 0, ret); - assert (pthread_mutex_destroy (&mutex) == 0); - - /* - * Destroy a mutex attribute. - * - * XXX - There should probably be a magic number - * associated with a mutex attribute so that - * destroy can be reasonably sure the attribute - * is valid. - * - * pthread_mutexattr_destroy not tested for: EINVAL - */ - assert (pthread_mutexattr_destroy (&mattr) == 0); - } - } -} - - -static void -mutex_destroy_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - pthread_condattr_t cattr; - pthread_cond_t cv; - pthread_attr_t pattr; - int mproto, ret; - mutex_kind_t mkind; - thread_state_t state; - - /* - * Destroy a mutex. - * - * XXX - There should probably be a magic number associated - * with a mutex so that destroy can be reasonably sure - * the mutex is valid. - * - * pthread_mutex_destroy not tested for: - */ - log ("Testing pthread_mutex_destroy\n"); - log ("-----------------------------\n"); - - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_DETACHED) == 0); - state.flags = 0; /* No flags yet. */ - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Destruction of unused mutex - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ 0, ret); - - log (" Destruction of mutex locked by self - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - assert (pthread_mutex_lock (&mutex) == 0); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - assert (pthread_mutex_unlock (&mutex) == 0); - assert (pthread_mutex_destroy (&mutex) == 0); - - log (" Destruction of mutex locked by another " - "thread - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - send_mutex_cmd (0, CMD_TAKE_MUTEX, &mutex); - sleep (1); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - send_cmd (0, CMD_RELEASE_ALL); - sleep (1); - assert (pthread_mutex_destroy (&mutex) == 0); - - log (" Destruction of mutex while being used in " - "cond_wait - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - assert (pthread_condattr_init (&cattr) == 0); - assert (pthread_cond_init (&cv, &cattr) == 0); - send_mutex_cv_cmd (0, CMD_WAIT_FOR_SIGNAL, &mutex, &cv); - sleep (1); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - pthread_cond_signal (&cv); - sleep (1); - assert (pthread_mutex_destroy (&mutex) == 0); - } - } -} - - -static void -mutex_lock_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - pthread_attr_t pattr; - int mproto, ret; - mutex_kind_t mkind; - thread_state_t state; - - /* - * Lock a mutex. - * - * pthread_lock not tested for: - */ - log ("Testing pthread_mutex_lock\n"); - log ("--------------------------\n"); - - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_DETACHED) == 0); - state.flags = 0; /* No flags yet. */ - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Lock on unlocked mutex - "); - ret = pthread_mutex_lock (&mutex); - check_result (/* expected */ 0, ret); - pthread_mutex_unlock (&mutex); - - log (" Lock on invalid mutex - "); - ret = pthread_mutex_lock (NULL); - check_result (/* expected */ EINVAL, ret); - - log (" Lock on mutex held by self - "); - assert (pthread_create (&state.tid, &pattr, lock_twice, - (void *) &state) == 0); - /* Let the thread start. */ - sleep (1); - state.cmd.mutex = &mutex; - state.ret = 0xdeadbeef; - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_signal (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - /* Let the thread receive and process the command. */ - sleep (1); - - switch (mkind) { - case M_POSIX: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_DEFAULT: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_ERRORCHECK: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_NORMAL: - check_result (/* expected */ 0xdeadbeef, - state.ret); - break; - case M_SS2_RECURSIVE: - check_result (/* expected */ 0, state.ret); - break; - } - pthread_mutex_destroy (&mutex); - pthread_mutexattr_destroy (&mattr); - } - } -} - - -static void -mutex_unlock_test (void) -{ - const int test_thread_id = 0; /* ID of test thread */ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - int mproto, ret; - mutex_kind_t mkind; - - /* - * Unlock a mutex. - * - * pthread_unlock not tested for: - */ - log ("Testing pthread_mutex_unlock\n"); - log ("----------------------------\n"); - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Unlock on mutex held by self - "); - assert (pthread_mutex_lock (&mutex) == 0); - ret = pthread_mutex_unlock (&mutex); - check_result (/* expected */ 0, ret); - - log (" Unlock on invalid mutex - "); - ret = pthread_mutex_unlock (NULL); - check_result (/* expected */ EINVAL, ret); - - log (" Unlock on mutex locked by another thread - "); - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &mutex); - sleep (1); - ret = pthread_mutex_unlock (&mutex); - switch (mkind) { - case M_POSIX: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_DEFAULT: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_ERRORCHECK: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_NORMAL: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_RECURSIVE: - check_result (/* expected */ EPERM, ret); - break; - } - if (ret == 0) { - /* - * If for some reason we were able to unlock - * the mutex, relock it so that the test - * thread has no problems releasing the mutex. - */ - pthread_mutex_lock (&mutex); - } - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - pthread_mutex_destroy (&mutex); - pthread_mutexattr_destroy (&mattr); - } - } -} - - -static void -queueing_order_test (void) -{ - int i; - - log ("Testing queueing order\n"); - log ("----------------------\n"); - assert (pthread_mutex_lock (&waiter_mutex) == 0); - /* - * Tell the threads to report when they take the waiters mutex. - */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - for (i = 0; i < NUM_THREADS; i++) { - states[i].flags = FLAGS_REPORT_WAITMUTEX; - assert (pthread_cond_signal (&states[i].cond_var) == 0); - } - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - /* Signal the threads to continue. */ - sleep (1); - - /* Use the global condition variable next time. */ - use_global_condvar = 1; - - /* Release the waiting threads and allow them to run again. */ - assert (pthread_mutex_unlock (&waiter_mutex) == 0); - sleep (1); - - log (" Queueing order on a mutex - "); - check_run_order ("9,8,7,6,5,4,3,2,1,0"); - for (i = 0; i < NUM_THREADS; i = i + 1) { - /* Tell the threads to report when they've been signaled. */ - states[i].flags = FLAGS_REPORT_WAITCONDVAR; - } - - /* - * Prevent the threads from continuing their loop after we - * signal them. - */ - assert (pthread_mutex_lock (&waiter_mutex) == 0); - - - log (" Queueing order on a condition variable - "); - /* - * Signal one thread to run and see that the highest priority - * thread executes. - */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_signal (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - sleep (1); - if (states[NUM_THREADS - 1].status != STAT_WAITMUTEX) - log_error ("highest priority thread does not run.\n"); - - /* Signal the remaining threads. */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_broadcast (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - sleep (1); - - check_run_order ("9,8,7,6,5,4,3,2,1,0"); - for (i = 0; i < NUM_THREADS; i = i + 1) { - /* Tell the threads not to report anything. */ - states[i].flags = 0; - } - - /* Use the thread unique condition variable next time. */ - use_global_condvar = 0; - - /* Allow the threads to continue their loop. */ - assert (pthread_mutex_unlock (&waiter_mutex) == 0); - sleep (1); -} - - -static void -mutex_prioceiling_test (void) -{ - const int test_thread_id = 0; /* ID of test thread */ - pthread_mutexattr_t mattr; - struct sched_param param; - pthread_mutex_t m[3]; - mutex_kind_t mkind; - int i, ret, policy, my_prio, old_ceiling; - - log ("Testing priority ceilings\n"); - log ("-------------------------\n"); - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - - log (" Protype PTHREAD_PRIO_PROTECT, Type %s\n", - mutextype_strs[mkind]); - - /* - * Initialize and create a mutex. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* Get this threads current priority. */ - assert (pthread_getschedparam (pthread_self(), &policy, - ¶m) == 0); - my_prio = param.sched_priority; /* save for later use */ - log_trace ("Current scheduling policy %d, priority %d\n", - policy, my_prio); - - /* - * Initialize and create 3 priority protection mutexes with - * default (max priority) ceilings. - */ - assert (pthread_mutexattr_setprotocol(&mattr, - PTHREAD_PRIO_PROTECT) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - for (i = 0; i < 3; i++) - assert (pthread_mutex_init (&m[i], &mattr) == 0); - - /* - * Set the ceiling priorities for the 3 priority protection - * mutexes to, 5 less than, equal to, and 5 greater than, - * this threads current priority. - */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_setprioceiling (&m[i], - my_prio - 5 + 5*i, &old_ceiling) == 0); - - /* - * Check that if we attempt to take a mutex whose priority - * ceiling is lower than our priority, we get an error. - */ - log (" Lock with ceiling priority < thread priority - "); - ret = pthread_mutex_lock (&m[0]); - check_result (/* expected */ EINVAL, ret); - if (ret == 0) - pthread_mutex_unlock (&m[0]); - - /* - * Check that we can take a mutex whose priority ceiling - * is equal to our priority. - */ - log (" Lock with ceiling priority = thread priority - "); - ret = pthread_mutex_lock (&m[1]); - check_result (/* expected */ 0, ret); - if (ret == 0) - pthread_mutex_unlock (&m[1]); - - /* - * Check that we can take a mutex whose priority ceiling - * is higher than our priority. - */ - log (" Lock with ceiling priority > thread priority - "); - ret = pthread_mutex_lock (&m[2]); - check_result (/* expected */ 0, ret); - if (ret == 0) - pthread_mutex_unlock (&m[2]); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it doesn't block this thread (since the - * priority ceiling of mutex 0 and the priority of the test - * thread are both less than the priority of this thread). - */ - log (" Preemption with ceiling priority < thread " - "priority - "); - /* Have the test thread take mutex 0. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[0]); - sleep (1); - - log_trace ("Sending busy command.\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if (states[test_thread_id].flags & - (FLAGS_IS_BUSY | FLAGS_WAS_BUSY)) - log_error ("test thread inproperly preempted us.\n"); - else { - /* Let the thread finish its busy loop. */ - sleep (6); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - } - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 0. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it preempts this thread (since the priority - * ceiling of mutex 1 is the same as the priority of this - * thread). The test thread should not run to completion - * as its time quantum should expire before the 5 seconds - * are up. - */ - log (" Preemption with ceiling priority = thread " - "priority - "); - - /* Have the test thread take mutex 1. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_IS_BUSY) == 0) - log_error ("test thread did not switch in on yield.\n"); - else if (states[test_thread_id].flags & FLAGS_WAS_BUSY) - log_error ("test thread ran to completion.\n"); - else { - /* Let the thread finish its busy loop. */ - sleep (6); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - } - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 1. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Set the scheduling policy of the test thread to SCHED_FIFO - * and have it go into a busy loop for 5 seconds. This - * thread is SCHED_RR, and since the priority ceiling of - * mutex 1 is the same as the priority of this thread, the - * test thread should run to completion once it is switched - * in. - */ - log (" SCHED_FIFO scheduling and ceiling priority = " - "thread priority - "); - param.sched_priority = states[test_thread_id].priority; - assert (pthread_setschedparam (states[test_thread_id].tid, - SCHED_FIFO, ¶m) == 0); - - /* Have the test thread take mutex 1. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) { - log_error ("test thread did not run to completion.\n"); - /* Let the thread finish it's busy loop. */ - sleep (6); - } - else - log_pass (); - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Restore the test thread scheduling parameters. */ - param.sched_priority = states[test_thread_id].priority; - assert (pthread_setschedparam (states[test_thread_id].tid, - SCHED_RR, ¶m) == 0); - - /* Have the test thread release mutex 1. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it preempts this thread (since the priority - * ceiling of mutex 2 is the greater than the priority of - * this thread). The test thread should run to completion - * and block this thread because its active priority is - * higher. - */ - log (" SCHED_FIFO scheduling and ceiling priority > " - "thread priority - "); - /* Have the test thread take mutex 2. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[2]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_IS_BUSY) != 0) { - log_error ("test thread did not run to completion.\n"); - /* Let the thread finish it's busy loop. */ - sleep (6); - } - else if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 2. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* Destroy the mutexes. */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_destroy (&m[i]) == 0); - } -} - - -static void -mutex_prioinherit_test (void) -{ - pthread_mutexattr_t mattr; - struct sched_param param; - pthread_mutex_t m[3]; - mutex_kind_t mkind; - int i, policy, my_prio; - - /* Get this threads current priority. */ - assert (pthread_getschedparam (pthread_self(), &policy, - ¶m) == 0); - my_prio = param.sched_priority; /* save for later use */ - log_trace ("Current scheduling policy %d, priority %d\n", - policy, my_prio); - - log ("Testing priority inheritence\n"); - log ("----------------------------\n"); - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - - log (" Protype PTHREAD_PRIO_INHERIT, Type %s\n", - mutextype_strs[mkind]); - - /* - * Initialize and create a mutex. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* - * Initialize and create 3 priority inheritence mutexes with - * default (max priority) ceilings. - */ - assert (pthread_mutexattr_setprotocol(&mattr, - PTHREAD_PRIO_INHERIT) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - for (i = 0; i < 3; i++) - assert (pthread_mutex_init (&m[i], &mattr) == 0); - - /* - * Test setup: - * Thread 4 - take mutex 0, 1 - * Thread 2 - enter protected busy loop with mutex 0 - * Thread 3 - enter protected busy loop with mutex 1 - * Thread 4 - enter protected busy loop with mutex 2 - * Thread 5 - enter busy loop - * Thread 6 - enter protected busy loop with mutex 0 - * Thread 4 - releases mutexes 1 and 0. - * - * Expected results: - * Threads complete in order 4, 6, 5, 3, 2 - */ - log (" Simple inheritence test - "); - - /* - * Command thread 4 to take mutexes 0 and 1. - */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]); - sleep (1); /* Allow command to be received. */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - /* - * Tell the threads to report themselves when they are - * at the bottom of their loop (waiting on wait_mutex). - */ - for (i = 0; i < NUM_THREADS; i++) - states[i].flags |= FLAGS_REPORT_WAITMUTEX; - - /* - * Command thread 2 to take mutex 0 and thread 3 to take - * mutex 1, both via a protected operation command. Since - * thread 4 owns mutexes 0 and 1, both threads 2 and 3 - * will block until the mutexes are released by thread 4. - */ - log_trace ("Commanding protected operation to thread 2.\n"); - send_mutex_cmd (2, CMD_PROTECTED_OP, &m[0]); - log_trace ("Commanding protected operation to thread 3.\n"); - send_mutex_cmd (3, CMD_PROTECTED_OP, &m[1]); - sleep (1); - - /* - * Command thread 4 to take mutex 2 via a protected operation - * and thread 5 to enter a busy loop for 5 seconds. Since - * thread 5 has higher priority than thread 4, thread 5 will - * enter the busy loop before thread 4 is activated. - */ - log_trace ("Commanding protected operation to thread 4.\n"); - send_mutex_cmd (4, CMD_PROTECTED_OP, &m[2]); - log_trace ("Commanding busy loop to thread 5.\n"); - send_cmd (5, CMD_BUSY_LOOP); - sleep (1); - if ((states[5].flags & FLAGS_IS_BUSY) == 0) - log_error ("thread 5 is not running.\n"); - log_trace ("Commanding protected operation thread 6.\n"); - send_mutex_cmd (6, CMD_PROTECTED_OP, &m[0]); - sleep (1); - if ((states[4].flags & FLAGS_WAS_BUSY) == 0) - log_error ("thread 4 failed to inherit priority.\n"); - states[4].flags = 0; - send_cmd (4, CMD_RELEASE_ALL); - sleep (5); - check_run_order ("4,6,5,3,2"); - - /* - * Clear the flags. - */ - for (i = 0; i < NUM_THREADS; i++) - states[i].flags = 0; - - /* - * Test setup: - * Thread 2 - enter busy loop (SCHED_FIFO) - * Thread 4 - take mutex 0 - * Thread 4 - priority change to same priority as thread 2 - * Thread 4 - release mutex 0 - * - * Expected results: - * Since thread 4 owns a priority mutex, it should be - * placed at the front of the run queue (for its new - * priority slot) when its priority is lowered to the - * same priority as thread 2. If thread 4 did not own - * a priority mutex, then it would have been added to - * the end of the run queue and thread 2 would have - * executed until it blocked (because it's scheduling - * policy is SCHED_FIFO). - * - */ - log (" Inheritence test with change of priority - "); - - /* - * Change threads 2 and 4 scheduling policies to be - * SCHED_FIFO. - */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[2].tid, SCHED_FIFO, - ¶m) == 0); - param.sched_priority = states[4].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_FIFO, - ¶m) == 0); - - /* - * Command thread 4 to take mutex 0. - */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]); - sleep (1); - - /* - * Command thread 2 to enter busy loop. - */ - send_cmd (2, CMD_BUSY_LOOP); - sleep (1); /* Allow command to be received. */ - - /* - * Command thread 4 to enter busy loop. - */ - send_cmd (4, CMD_BUSY_LOOP); - sleep (1); /* Allow command to be received. */ - - /* Have threads 2 and 4 report themselves. */ - states[2].flags = FLAGS_REPORT_WAITMUTEX; - states[4].flags = FLAGS_REPORT_WAITMUTEX; - - /* Change the priority of thread 4. */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_FIFO, - ¶m) == 0); - sleep (5); - check_run_order ("4,2"); - - /* Clear the flags */ - states[2].flags = 0; - states[4].flags = 0; - - /* Reset the policies. */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[2].tid, SCHED_RR, - ¶m) == 0); - param.sched_priority = states[4].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_RR, - ¶m) == 0); - - send_cmd (4, CMD_RELEASE_MUTEX); - sleep (1); - - /* Destroy the mutexes. */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_destroy (&m[i]) == 0); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_mutexattr_t mattr; - pthread_condattr_t cattr; - pthread_attr_t pattr; - int i, policy, main_prio; - void * exit_status; - sigset_t mask; - struct sigaction act; - struct sched_param param; - - logfile = stdout; - - assert (pthread_getschedparam (pthread_self (), &policy, ¶m) == 0); - main_prio = param.sched_priority; - - /* Setupt our signal mask. */ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_SETMASK, &mask, NULL); - - /* Install a signal handler for SIGINT */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGINT); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGINT, &act, NULL); - - /* This test relies on the concurrency level being 1. */ - pthread_setconcurrency(1); - - /* - * Initialize the thread attribute. - */ - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) == 0); - - /* - * Initialize and create the waiter and condvar mutexes. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutex_init (&waiter_mutex, &mattr) == 0); - assert (pthread_mutex_init (&cond_mutex, &mattr) == 0); - - /* - * Initialize and create a condition variable. - */ - assert (pthread_condattr_init (&cattr) == 0); - assert (pthread_cond_init (&cond_var, &cattr) == 0); - - /* Create a pipe to catch the results of thread wakeups. */ - assert (pipe (pipefd) == 0); - -#if defined(_LIBC_R_) && defined(DEBUG) - assert (pthread_switch_add_np (kern_switch) == 0); -#endif - - /* - * Create the waiting threads. - */ - for (i = 0; i < NUM_THREADS; i++) { - assert (pthread_cond_init (&states[i].cond_var, &cattr) == 0); - states[i].id = (u_int8_t) i; /* NUM_THREADS must be <= 256 */ - states[i].status = 0; - states[i].cmd.cmd_id = CMD_NONE; - states[i].flags = 0; /* No flags yet. */ - assert (pthread_create (&states[i].tid, &pattr, waiter, - (void *) &states[i]) == 0); - param.sched_priority = main_prio - 10 + i; - states[i].priority = param.sched_priority; - assert (pthread_setschedparam (states[i].tid, SCHED_OTHER, - ¶m) == 0); -#if defined(_LIBC_R_) - { - char buf[30]; - - snprintf (buf, sizeof(buf), "waiter_%d", i); - pthread_set_name_np (states[i].tid, buf); - } -#endif - } - - /* Allow the threads to start. */ - sleep (1); - log_trace ("Done creating threads.\n"); - - log ("\n"); - mutex_init_test (); - log ("\n"); - mutex_destroy_test (); - log ("\n"); - mutex_lock_test (); - log ("\n"); - mutex_unlock_test (); - log ("\n"); - queueing_order_test (); - log ("\n"); - mutex_prioinherit_test (); - log ("\n"); - mutex_prioceiling_test (); - log ("\n"); - - log ("Total tests %d, passed %d, failed %d\n", - total, pass_count, error_count); - - /* Set the done flag and signal the threads to exit. */ - log_trace ("Setting done flag.\n"); - done = 1; - - /* - * Wait for the threads to finish. - */ - log_trace ("Trying to join threads.\n"); - for (i = 0; i < NUM_THREADS; i++) { - send_cmd (i, CMD_NONE); - assert (pthread_join (states[i].tid, &exit_status) == 0); - } - - /* Clean up after ourselves. */ - close (pipefd[0]); - close (pipefd[1]); - - if (error_count != 0) - exit (EX_OSERR); /* any better ideas??? */ - else - exit (EX_OK); -} diff --git a/lib/libpthread/test/mutex_d.exp b/lib/libpthread/test/mutex_d.exp deleted file mode 100644 index de8a4e4..0000000 --- a/lib/libpthread/test/mutex_d.exp +++ /dev/null @@ -1,290 +0,0 @@ - -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 diff --git a/lib/libpthread/test/propagate_s.pl b/lib/libpthread/test/propagate_s.pl deleted file mode 100755 index 6b85090..0000000 --- a/lib/libpthread/test/propagate_s.pl +++ /dev/null @@ -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"; -} diff --git a/lib/libpthread/test/sem_d.c b/lib/libpthread/test/sem_d.c deleted file mode 100644 index b834591..0000000 --- a/lib/libpthread/test/sem_d.c +++ /dev/null @@ -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; -} diff --git a/lib/libpthread/test/sem_d.exp b/lib/libpthread/test/sem_d.exp deleted file mode 100644 index b0de3da..0000000 --- a/lib/libpthread/test/sem_d.exp +++ /dev/null @@ -1,22 +0,0 @@ -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 diff --git a/lib/libpthread/test/sigsuspend_d.c b/lib/libpthread/test/sigsuspend_d.c deleted file mode 100644 index d405e3d..0000000 --- a/lib/libpthread/test/sigsuspend_d.c +++ /dev/null @@ -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); -} diff --git a/lib/libpthread/test/sigsuspend_d.exp b/lib/libpthread/test/sigsuspend_d.exp deleted file mode 100644 index 901fa50..0000000 --- a/lib/libpthread/test/sigsuspend_d.exp +++ /dev/null @@ -1,8 +0,0 @@ - -> 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 diff --git a/lib/libpthread/test/sigwait_d.c b/lib/libpthread/test/sigwait_d.c deleted file mode 100644 index f3ccd6b..0000000 --- a/lib/libpthread/test/sigwait_d.c +++ /dev/null @@ -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); -} diff --git a/lib/libpthread/test/sigwait_d.exp b/lib/libpthread/test/sigwait_d.exp deleted file mode 100644 index 2e9b2c4..0000000 --- a/lib/libpthread/test/sigwait_d.exp +++ /dev/null @@ -1,10 +0,0 @@ -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 diff --git a/lib/libpthread/test/verify b/lib/libpthread/test/verify deleted file mode 100755 index 2863e5c..0000000 --- a/lib/libpthread/test/verify +++ /dev/null @@ -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 -} diff --git a/lib/libpthread/thread/Makefile.inc b/lib/libpthread/thread/Makefile.inc deleted file mode 100644 index 561be93..0000000 --- a/lib/libpthread/thread/Makefile.inc +++ /dev/null @@ -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 diff --git a/lib/libpthread/thread/thr_accept.c b/lib/libpthread/thread/thr_accept.c deleted file mode 100644 index fc60fb4..0000000 --- a/lib/libpthread/thread/thr_accept.c +++ /dev/null @@ -1,52 +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" - -LT10_COMPAT_PRIVATE(__accept); -LT10_COMPAT_DEFAULT(accept); - -__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); -} diff --git a/lib/libpthread/thread/thr_aio_suspend.c b/lib/libpthread/thread/thr_aio_suspend.c deleted file mode 100644 index 43a2414..0000000 --- a/lib/libpthread/thread/thr_aio_suspend.c +++ /dev/null @@ -1,54 +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" - -LT10_COMPAT_PRIVATE(_aio_suspend); -LT10_COMPAT_DEFAULT(aio_suspend); - -__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); -} - diff --git a/lib/libpthread/thread/thr_atfork.c b/lib/libpthread/thread/thr_atfork.c deleted file mode 100644 index a741329..0000000 --- a/lib/libpthread/thread/thr_atfork.c +++ /dev/null @@ -1,59 +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 <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include <sys/queue.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_atfork); -LT10_COMPAT_DEFAULT(pthread_atfork); - -__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); -} - diff --git a/lib/libpthread/thread/thr_attr_destroy.c b/lib/libpthread/thread/thr_attr_destroy.c deleted file mode 100644 index 0e2b2e1..0000000 --- a/lib/libpthread/thread/thr_attr_destroy.c +++ /dev/null @@ -1,62 +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 <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_destroy); -LT10_COMPAT_DEFAULT(pthread_attr_destroy); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_get_np.c b/lib/libpthread/thread/thr_attr_get_np.c deleted file mode 100644 index a63088f..0000000 --- a/lib/libpthread/thread/thr_attr_get_np.c +++ /dev/null @@ -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 <errno.h> -#include <string.h> -#include <pthread.h> -#include <pthread_np.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_get_np); -LT10_COMPAT_DEFAULT(pthread_attr_get_np); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getdetachstate.c b/lib/libpthread/thread/thr_attr_getdetachstate.c deleted file mode 100644 index 465ad28..0000000 --- a/lib/libpthread/thread/thr_attr_getdetachstate.c +++ /dev/null @@ -1,59 +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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getdetachstate); -LT10_COMPAT_DEFAULT(pthread_attr_getdetachstate); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getguardsize.c b/lib/libpthread/thread/thr_attr_getguardsize.c deleted file mode 100644 index 351015c..0000000 --- a/lib/libpthread/thread/thr_attr_getguardsize.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getguardsize); -LT10_COMPAT_DEFAULT(pthread_attr_getguardsize); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getinheritsched.c b/lib/libpthread/thread/thr_attr_getinheritsched.c deleted file mode 100644 index eab19e3..0000000 --- a/lib/libpthread/thread/thr_attr_getinheritsched.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getinheritsched); -LT10_COMPAT_DEFAULT(pthread_attr_getinheritsched); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getschedparam.c b/lib/libpthread/thread/thr_attr_getschedparam.c deleted file mode 100644 index ca2eed3..0000000 --- a/lib/libpthread/thread/thr_attr_getschedparam.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getschedparam); -LT10_COMPAT_DEFAULT(pthread_attr_getschedparam); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getschedpolicy.c b/lib/libpthread/thread/thr_attr_getschedpolicy.c deleted file mode 100644 index dc952bd..0000000 --- a/lib/libpthread/thread/thr_attr_getschedpolicy.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getschedpolicy); -LT10_COMPAT_DEFAULT(pthread_attr_getschedpolicy); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getscope.c b/lib/libpthread/thread/thr_attr_getscope.c deleted file mode 100644 index ceb198f..0000000 --- a/lib/libpthread/thread/thr_attr_getscope.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getscope); -LT10_COMPAT_DEFAULT(pthread_attr_getscope); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getstack.c b/lib/libpthread/thread/thr_attr_getstack.c deleted file mode 100644 index 79a92cb..0000000 --- a/lib/libpthread/thread/thr_attr_getstack.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getstack); -LT10_COMPAT_DEFAULT(pthread_attr_getstack); - -__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); -} - diff --git a/lib/libpthread/thread/thr_attr_getstackaddr.c b/lib/libpthread/thread/thr_attr_getstackaddr.c deleted file mode 100644 index ed526da..0000000 --- a/lib/libpthread/thread/thr_attr_getstackaddr.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getstackaddr); -LT10_COMPAT_DEFAULT(pthread_attr_getstackaddr); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_getstacksize.c b/lib/libpthread/thread/thr_attr_getstacksize.c deleted file mode 100644 index 4ccced6..0000000 --- a/lib/libpthread/thread/thr_attr_getstacksize.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_getstacksize); -LT10_COMPAT_DEFAULT(pthread_attr_getstacksize); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_init.c b/lib/libpthread/thread/thr_attr_init.c deleted file mode 100644 index af6260e..0000000 --- a/lib/libpthread/thread/thr_attr_init.c +++ /dev/null @@ -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 <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_init); -LT10_COMPAT_DEFAULT(pthread_attr_init); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setcreatesuspend_np.c b/lib/libpthread/thread/thr_attr_setcreatesuspend_np.c deleted file mode 100644 index 8ff485b..0000000 --- a/lib/libpthread/thread/thr_attr_setcreatesuspend_np.c +++ /dev/null @@ -1,52 +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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setcreatesuspend_np); -LT10_COMPAT_DEFAULT(pthread_attr_setcreatesuspend_np); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setdetachstate.c b/lib/libpthread/thread/thr_attr_setdetachstate.c deleted file mode 100644 index ebffd20..0000000 --- a/lib/libpthread/thread/thr_attr_setdetachstate.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setdetachstate); -LT10_COMPAT_DEFAULT(pthread_attr_setdetachstate); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setguardsize.c b/lib/libpthread/thread/thr_attr_setguardsize.c deleted file mode 100644 index dedee8b..0000000 --- a/lib/libpthread/thread/thr_attr_setguardsize.c +++ /dev/null @@ -1,56 +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 <sys/param.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setguardsize); -LT10_COMPAT_DEFAULT(pthread_attr_setguardsize); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setinheritsched.c b/lib/libpthread/thread/thr_attr_setinheritsched.c deleted file mode 100644 index 5182b7d..0000000 --- a/lib/libpthread/thread/thr_attr_setinheritsched.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setinheritsched); -LT10_COMPAT_DEFAULT(pthread_attr_setinheritsched); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setschedparam.c b/lib/libpthread/thread/thr_attr_setschedparam.c deleted file mode 100644 index 61d741d..0000000 --- a/lib/libpthread/thread/thr_attr_setschedparam.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setschedparam); -LT10_COMPAT_DEFAULT(pthread_attr_setschedparam); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setschedpolicy.c b/lib/libpthread/thread/thr_attr_setschedpolicy.c deleted file mode 100644 index fb24cb1..0000000 --- a/lib/libpthread/thread/thr_attr_setschedpolicy.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setschedpolicy); -LT10_COMPAT_DEFAULT(pthread_attr_setschedpolicy); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setscope.c b/lib/libpthread/thread/thr_attr_setscope.c deleted file mode 100644 index 3cc7f16..0000000 --- a/lib/libpthread/thread/thr_attr_setscope.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setscope); -LT10_COMPAT_DEFAULT(pthread_attr_setscope); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setstack.c b/lib/libpthread/thread/thr_attr_setstack.c deleted file mode 100644 index bdccfd8..0000000 --- a/lib/libpthread/thread/thr_attr_setstack.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setstack); -LT10_COMPAT_DEFAULT(pthread_attr_setstack); - -__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); -} - diff --git a/lib/libpthread/thread/thr_attr_setstackaddr.c b/lib/libpthread/thread/thr_attr_setstackaddr.c deleted file mode 100644 index f82729a..0000000 --- a/lib/libpthread/thread/thr_attr_setstackaddr.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setstackaddr); -LT10_COMPAT_DEFAULT(pthread_attr_setstackaddr); - -__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); -} diff --git a/lib/libpthread/thread/thr_attr_setstacksize.c b/lib/libpthread/thread/thr_attr_setstacksize.c deleted file mode 100644 index 590e71e..0000000 --- a/lib/libpthread/thread/thr_attr_setstacksize.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_attr_setstacksize); -LT10_COMPAT_DEFAULT(pthread_attr_setstacksize); - -__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); -} diff --git a/lib/libpthread/thread/thr_autoinit.c b/lib/libpthread/thread/thr_autoinit.c deleted file mode 100644 index 95b2a85..0000000 --- a/lib/libpthread/thread/thr_autoinit.c +++ /dev/null @@ -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; diff --git a/lib/libpthread/thread/thr_barrier.c b/lib/libpthread/thread/thr_barrier.c deleted file mode 100644 index c8be343..0000000 --- a/lib/libpthread/thread/thr_barrier.c +++ /dev/null @@ -1,129 +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 <errno.h> -#include <stdlib.h> -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_barrier_init); -LT10_COMPAT_DEFAULT(pthread_barrier_init); -LT10_COMPAT_PRIVATE(_pthread_barrier_wait); -LT10_COMPAT_DEFAULT(pthread_barrier_wait); -LT10_COMPAT_PRIVATE(_pthread_barrier_destroy); -LT10_COMPAT_DEFAULT(pthread_barrier_destroy); - -__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, 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); -} diff --git a/lib/libpthread/thread/thr_barrierattr.c b/lib/libpthread/thread/thr_barrierattr.c deleted file mode 100644 index 3384aee..0000000 --- a/lib/libpthread/thread/thr_barrierattr.c +++ /dev/null @@ -1,102 +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 <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_barrierattr_destroy); -LT10_COMPAT_DEFAULT(pthread_barrierattr_destroy); -LT10_COMPAT_PRIVATE(_pthread_barrierattr_init); -LT10_COMPAT_DEFAULT(pthread_barrierattr_init); -LT10_COMPAT_PRIVATE(_pthread_barrierattr_setpshared); -LT10_COMPAT_DEFAULT(pthread_barrierattr_setpshared); -LT10_COMPAT_PRIVATE(_pthread_barrierattr_getpshared); -LT10_COMPAT_DEFAULT(pthread_barrierattr_getpshared); - -__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); -} diff --git a/lib/libpthread/thread/thr_cancel.c b/lib/libpthread/thread/thr_cancel.c deleted file mode 100644 index bbf6fdf..0000000 --- a/lib/libpthread/thread/thr_cancel.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * David Leonard <d@openbsd.org>, 1999. Public domain. - * $FreeBSD$ - */ -#include <sys/errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_cancel); -LT10_COMPAT_DEFAULT(pthread_cancel); -LT10_COMPAT_PRIVATE(_pthread_setcancelstate); -LT10_COMPAT_DEFAULT(pthread_setcancelstate); -LT10_COMPAT_PRIVATE(_pthread_setcanceltype); -LT10_COMPAT_DEFAULT(pthread_setcanceltype); -LT10_COMPAT_PRIVATE(_pthread_testcancel); -LT10_COMPAT_DEFAULT(pthread_testcancel); - -__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) -{ - 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); -} diff --git a/lib/libpthread/thread/thr_clean.c b/lib/libpthread/thread/thr_clean.c deleted file mode 100644 index 0153e99..0000000 --- a/lib/libpthread/thread/thr_clean.c +++ /dev/null @@ -1,76 +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 <signal.h> -#include <errno.h> -#include <stdlib.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_cleanup_push); -LT10_COMPAT_DEFAULT(pthread_cleanup_push); -LT10_COMPAT_PRIVATE(_pthread_cleanup_pop); -LT10_COMPAT_DEFAULT(pthread_cleanup_pop); - -__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); - } -} diff --git a/lib/libpthread/thread/thr_close.c b/lib/libpthread/thread/thr_close.c deleted file mode 100644 index 66747af..0000000 --- a/lib/libpthread/thread/thr_close.c +++ /dev/null @@ -1,55 +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 <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__close); -LT10_COMPAT_DEFAULT(close); - -__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); -} diff --git a/lib/libpthread/thread/thr_concurrency.c b/lib/libpthread/thread/thr_concurrency.c deleted file mode 100644 index 74e0e11..0000000 --- a/lib/libpthread/thread/thr_concurrency.c +++ /dev/null @@ -1,177 +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 <errno.h> -#include <pthread.h> -#include <sys/types.h> -#include <sys/sysctl.h> - -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_getconcurrency); -LT10_COMPAT_DEFAULT(pthread_getconcurrency); -LT10_COMPAT_PRIVATE(_pthread_setconcurrency); -LT10_COMPAT_DEFAULT(pthread_setconcurrency); - -/*#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); -} - diff --git a/lib/libpthread/thread/thr_cond.c b/lib/libpthread/thread/thr_cond.c deleted file mode 100644 index 589f4b1..0000000 --- a/lib/libpthread/thread/thr_cond.c +++ /dev/null @@ -1,844 +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 <stdlib.h> -#include <errno.h> -#include <string.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__pthread_cond_wait); -LT10_COMPAT_PRIVATE(_pthread_cond_wait); -LT10_COMPAT_DEFAULT(pthread_cond_wait); -LT10_COMPAT_PRIVATE(__pthread_cond_timedwait); -LT10_COMPAT_PRIVATE(_pthread_cond_timedwait); -LT10_COMPAT_DEFAULT(pthread_cond_timedwait); -LT10_COMPAT_PRIVATE(_pthread_cond_init); -LT10_COMPAT_DEFAULT(pthread_cond_init); -LT10_COMPAT_PRIVATE(_pthread_cond_destroy); -LT10_COMPAT_DEFAULT(pthread_cond_destroy); -LT10_COMPAT_PRIVATE(_pthread_cond_signal); -LT10_COMPAT_DEFAULT(pthread_cond_signal); -LT10_COMPAT_PRIVATE(_pthread_cond_broadcast); -LT10_COMPAT_DEFAULT(pthread_cond_broadcast); - -#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 *); - -/* - * 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) != 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; -} diff --git a/lib/libpthread/thread/thr_condattr_destroy.c b/lib/libpthread/thread/thr_condattr_destroy.c deleted file mode 100644 index 3805a62..0000000 --- a/lib/libpthread/thread/thr_condattr_destroy.c +++ /dev/null @@ -1,53 +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 <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_condattr_destroy); -LT10_COMPAT_DEFAULT(pthread_condattr_destroy); - -__weak_reference(_pthread_condattr_destroy, pthread_condattr_destroy); - -int -_pthread_condattr_destroy(pthread_condattr_t *attr) -{ - int ret; - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - free(*attr); - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libpthread/thread/thr_condattr_init.c b/lib/libpthread/thread/thr_condattr_init.c deleted file mode 100644 index 0b86566..0000000 --- a/lib/libpthread/thread/thr_condattr_init.c +++ /dev/null @@ -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 <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_condattr_init); -LT10_COMPAT_DEFAULT(pthread_condattr_init); - -__weak_reference(_pthread_condattr_init, pthread_condattr_init); - -int -_pthread_condattr_init(pthread_condattr_t *attr) -{ - int ret; - pthread_condattr_t pattr; - - if ((pattr = (pthread_condattr_t) - malloc(sizeof(struct pthread_cond_attr))) == NULL) { - ret = ENOMEM; - } else { - memcpy(pattr, &_pthread_condattr_default, - sizeof(struct pthread_cond_attr)); - *attr = pattr; - ret = 0; - } - return (ret); -} diff --git a/lib/libpthread/thread/thr_condattr_pshared.c b/lib/libpthread/thread/thr_condattr_pshared.c deleted file mode 100644 index 7cef4d9..0000000 --- a/lib/libpthread/thread/thr_condattr_pshared.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2005 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 unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must 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 <errno.h> -#include "thr_private.h" - -__weak_reference(_pthread_condattr_getpshared, pthread_condattr_getpshared); -__weak_reference(_pthread_condattr_setpshared, pthread_condattr_setpshared); - -int -_pthread_condattr_getpshared(const pthread_condattr_t *attr, - int *pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - return (0); -} diff --git a/lib/libpthread/thread/thr_connect.c b/lib/libpthread/thread/thr_connect.c deleted file mode 100644 index 225d8b9..0000000 --- a/lib/libpthread/thread/thr_connect.c +++ /dev/null @@ -1,52 +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" - -LT10_COMPAT_PRIVATE(__connect); -LT10_COMPAT_DEFAULT(connect); - -__weak_reference(__connect, connect); - -int -__connect(int fd, const struct sockaddr *name, socklen_t namelen) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - ret = __sys_connect(fd, name, namelen); - _thr_cancel_leave(curthread, ret == -1); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_creat.c b/lib/libpthread/thread/thr_creat.c deleted file mode 100644 index 7528f0b..0000000 --- a/lib/libpthread/thread/thr_creat.c +++ /dev/null @@ -1,58 +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 <fcntl.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(___creat); -LT10_COMPAT_DEFAULT(creat); - -extern int __creat(const char *, mode_t); - -__weak_reference(___creat, creat); - -int -___creat(const char *path, mode_t mode) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __creat(path, mode); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - _thr_cancel_leave(curthread, (ret == -1)); - - return ret; -} diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c deleted file mode 100644 index f4bd4758..0000000 --- a/lib/libpthread/thread/thr_create.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@gdeb.com> - * 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 <errno.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <stddef.h> -#include <sys/time.h> -#include <machine/reg.h> -#include <pthread.h> -#include "thr_private.h" -#include "libc_private.h" - -LT10_COMPAT_PRIVATE(_pthread_create); -LT10_COMPAT_DEFAULT(pthread_create); - -static void free_thread(struct pthread *curthread, struct pthread *thread); -static int create_stack(struct pthread_attr *pattr); -static void free_stack(struct pthread_attr *pattr); -static void thread_start(struct pthread *curthread, - void *(*start_routine) (void *), void *arg); - -__weak_reference(_pthread_create, pthread_create); - -/* - * Some notes on new thread creation and first time initializion - * to enable multi-threading. - * - * There are basically two things that need to be done. - * - * 1) The internal library variables must be initialized. - * 2) Upcalls need to be enabled to allow multiple threads - * to be run. - * - * The first may be done as a result of other pthread functions - * being called. When _thr_initial is null, _libpthread_init is - * called to initialize the internal variables; this also creates - * or sets the initial thread. It'd be nice to automatically - * have _libpthread_init called on program execution so we don't - * have to have checks throughout the library. - * - * The second part is only triggered by the creation of the first - * thread (other than the initial/main thread). If the thread - * being created is a scope system thread, then a new KSE/KSEG - * pair needs to be allocated. Also, if upcalls haven't been - * enabled on the initial thread's KSE, they must be now that - * there is more than one thread; this could be delayed until - * the initial KSEG has more than one thread. - */ -int -_pthread_create(pthread_t * thread, const pthread_attr_t * attr, - void *(*start_routine) (void *), void *arg) -{ - struct pthread *curthread, *new_thread; - struct kse *kse = NULL; - struct kse_group *kseg = NULL; - kse_critical_t crit; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - /* - * Turn on threaded mode, if failed, it is unnecessary to - * do further work. - */ - if (_kse_isthreaded() == 0 && _kse_setthreaded(1)) { - return (EAGAIN); - } - curthread = _get_curthread(); - - /* - * Allocate memory for the thread structure. - * Some functions use malloc, so don't put it - * in a critical region. - */ - if ((new_thread = _thr_alloc(curthread)) == NULL) { - /* Insufficient memory to create a thread: */ - ret = EAGAIN; - } else { - /* Check if default thread attributes are required: */ - if (attr == NULL || *attr == NULL) - /* Use the default thread attributes: */ - new_thread->attr = _pthread_attr_default; - else { - new_thread->attr = *(*attr); - if ((*attr)->sched_inherit == PTHREAD_INHERIT_SCHED) { - /* inherit scheduling contention scop */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else - new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - /* - * scheduling policy and scheduling parameters will be - * inherited in following code. - */ - } - } - if (_thread_scope_system > 0) - new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else if ((_thread_scope_system < 0) - && (thread != &_thr_sig_daemon)) - new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - if (create_stack(&new_thread->attr) != 0) { - /* Insufficient memory to create a stack: */ - ret = EAGAIN; - _thr_free(curthread, new_thread); - } - else if (((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) && - (((kse = _kse_alloc(curthread, 1)) == NULL) - || ((kseg = _kseg_alloc(curthread)) == NULL))) { - /* Insufficient memory to create a new KSE/KSEG: */ - ret = EAGAIN; - if (kse != NULL) { - kse->k_kcb->kcb_kmbx.km_flags |= KMF_DONE; - _kse_free(curthread, kse); - } - free_stack(&new_thread->attr); - _thr_free(curthread, new_thread); - } - else { - if (kseg != NULL) { - /* Add the KSE to the KSEG's list of KSEs. */ - TAILQ_INSERT_HEAD(&kseg->kg_kseq, kse, k_kgqe); - kseg->kg_ksecount = 1; - kse->k_kseg = kseg; - kse->k_schedq = &kseg->kg_schedq; - } - /* - * Write a magic value to the thread structure - * to help identify valid ones: - */ - new_thread->magic = THR_MAGIC; - - new_thread->slice_usec = -1; - new_thread->start_routine = start_routine; - new_thread->arg = arg; - new_thread->cancelflags = PTHREAD_CANCEL_ENABLE | - PTHREAD_CANCEL_DEFERRED; - - /* No thread is wanting to join to this one: */ - new_thread->joiner = NULL; - - /* - * Initialize the machine context. - * Enter a critical region to get consistent context. - */ - crit = _kse_critical_enter(); - THR_GETCONTEXT(&new_thread->tcb->tcb_tmbx.tm_context); - /* Initialize the thread for signals: */ - new_thread->sigmask = curthread->sigmask; - _kse_critical_leave(crit); - - new_thread->tcb->tcb_tmbx.tm_udata = new_thread; - new_thread->tcb->tcb_tmbx.tm_context.uc_sigmask = - new_thread->sigmask; - new_thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size = - new_thread->attr.stacksize_attr; - new_thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp = - new_thread->attr.stackaddr_attr; - makecontext(&new_thread->tcb->tcb_tmbx.tm_context, - (void (*)(void))thread_start, 3, new_thread, - start_routine, arg); - /* - * Check if this thread is to inherit the scheduling - * attributes from its parent: - */ - if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { - /* - * Copy the scheduling attributes. - * Lock the scheduling lock to get consistent - * scheduling parameters. - */ - THR_SCHED_LOCK(curthread, curthread); - new_thread->base_priority = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.prio = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.sched_policy = - curthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, curthread); - } else { - /* - * Use just the thread priority, leaving the - * other scheduling attributes as their - * default values: - */ - new_thread->base_priority = - new_thread->attr.prio; - } - new_thread->active_priority = new_thread->base_priority; - new_thread->inherited_priority = 0; - - /* Initialize the mutex queue: */ - TAILQ_INIT(&new_thread->mutexq); - - /* Initialise hooks in the thread structure: */ - new_thread->specific = NULL; - new_thread->specific_data_count = 0; - new_thread->cleanup = NULL; - new_thread->flags = 0; - new_thread->tlflags = 0; - new_thread->sigbackout = NULL; - new_thread->continuation = NULL; - new_thread->wakeup_time.tv_sec = -1; - new_thread->lock_switch = 0; - sigemptyset(&new_thread->sigpend); - new_thread->check_pending = 0; - new_thread->locklevel = 0; - new_thread->rdlock_count = 0; - new_thread->sigstk.ss_sp = 0; - new_thread->sigstk.ss_size = 0; - new_thread->sigstk.ss_flags = SS_DISABLE; - new_thread->oldsigmask = NULL; - - if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) { - new_thread->state = PS_SUSPENDED; - new_thread->flags = THR_FLAGS_SUSPENDED; - } - else - new_thread->state = PS_RUNNING; - - /* - * System scope threads have their own kse and - * kseg. Process scope threads are all hung - * off the main process kseg. - */ - if ((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) { - new_thread->kseg = _kse_initial->k_kseg; - new_thread->kse = _kse_initial; - } - else { - kse->k_curthread = NULL; - kse->k_kseg->kg_flags |= KGF_SINGLE_THREAD; - new_thread->kse = kse; - new_thread->kseg = kse->k_kseg; - kse->k_kcb->kcb_kmbx.km_udata = kse; - kse->k_kcb->kcb_kmbx.km_curthread = NULL; - } - - /* - * Schedule the new thread starting a new KSEG/KSE - * pair if necessary. - */ - ret = _thr_schedule_add(curthread, new_thread); - if (ret != 0) - free_thread(curthread, new_thread); - else { - /* Return a pointer to the thread structure: */ - (*thread) = new_thread; - } - } - } - - /* Return the status: */ - return (ret); -} - -static void -free_thread(struct pthread *curthread, struct pthread *thread) -{ - free_stack(&thread->attr); - if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - /* Free the KSE and KSEG. */ - _kseg_free(thread->kseg); - _kse_free(curthread, thread->kse); - } - _thr_free(curthread, thread); -} - -static int -create_stack(struct pthread_attr *pattr) -{ - int ret; - - /* Check if a stack was specified in the thread attributes: */ - if ((pattr->stackaddr_attr) != NULL) { - pattr->guardsize_attr = 0; - pattr->flags |= THR_STACK_USER; - ret = 0; - } - else - ret = _thr_stack_alloc(pattr); - return (ret); -} - -static void -free_stack(struct pthread_attr *pattr) -{ - struct kse *curkse; - kse_critical_t crit; - - if ((pattr->flags & THR_STACK_USER) == 0) { - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* Stack routines don't use malloc/free. */ - _thr_stack_free(pattr); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } -} - -static void -thread_start(struct pthread *curthread, void *(*start_routine) (void *), - void *arg) -{ - /* Run the current thread's start routine with argument: */ - pthread_exit(start_routine(arg)); - - /* This point should never be reached. */ - PANIC("Thread has resumed after exit"); -} diff --git a/lib/libpthread/thread/thr_detach.c b/lib/libpthread/thread/thr_detach.c deleted file mode 100644 index 0c0c0c8..0000000 --- a/lib/libpthread/thread/thr_detach.c +++ /dev/null @@ -1,117 +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 <sys/types.h> -#include <machine/atomic.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_detach); -LT10_COMPAT_DEFAULT(pthread_detach); - -__weak_reference(_pthread_detach, pthread_detach); - -int -_pthread_detach(pthread_t pthread) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx = NULL; - struct pthread *joiner; - int rval = 0; - - /* Check for invalid calling parameters: */ - if (pthread == NULL || pthread->magic != THR_MAGIC) - /* Return an invalid argument error: */ - rval = EINVAL; - - else if ((rval = _thr_ref_add(curthread, pthread, - /*include dead*/1)) != 0) { - /* Return an error: */ - } - - /* Check if the thread is already detached: */ - else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) { - /* Return an error: */ - _thr_ref_delete(curthread, pthread); - rval = EINVAL; - } else { - /* Lock the detached thread: */ - THR_SCHED_LOCK(curthread, pthread); - - /* Flag the thread as detached: */ - pthread->attr.flags |= PTHREAD_DETACHED; - - /* Retrieve any joining thread and remove it: */ - joiner = pthread->joiner; - if ((joiner != NULL) && (joiner->kseg == pthread->kseg)) { - /* - * We already own the scheduler lock for the joiner. - * Take advantage of that and make the joiner runnable. - */ - if (joiner->join_status.thread == pthread) { - /* - * Set the return value for the woken thread: - */ - joiner->join_status.error = ESRCH; - joiner->join_status.ret = NULL; - joiner->join_status.thread = NULL; - - kmbx = _thr_setrunnable_unlocked(joiner); - } - joiner = NULL; - } - THR_SCHED_UNLOCK(curthread, pthread); - /* See if there is a thread waiting in pthread_join(): */ - if ((joiner != NULL) && - (_thr_ref_add(curthread, joiner, 0) == 0)) { - /* Lock the joiner before fiddling with it. */ - THR_SCHED_LOCK(curthread, joiner); - if (joiner->join_status.thread == pthread) { - /* - * Set the return value for the woken thread: - */ - joiner->join_status.error = ESRCH; - joiner->join_status.ret = NULL; - joiner->join_status.thread = NULL; - - kmbx = _thr_setrunnable_unlocked(joiner); - } - THR_SCHED_UNLOCK(curthread, joiner); - _thr_ref_delete(curthread, joiner); - } - _thr_ref_delete(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* Return the completion status: */ - return (rval); -} diff --git a/lib/libpthread/thread/thr_equal.c b/lib/libpthread/thread/thr_equal.c deleted file mode 100644 index 0ac747a..0000000 --- a/lib/libpthread/thread/thr_equal.c +++ /dev/null @@ -1,44 +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 <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_equal); -LT10_COMPAT_DEFAULT(pthread_equal); - -__weak_reference(_pthread_equal, pthread_equal); - -int -_pthread_equal(pthread_t t1, pthread_t t2) -{ - /* Compare the two thread pointers: */ - return (t1 == t2); -} diff --git a/lib/libpthread/thread/thr_execve.c b/lib/libpthread/thread/thr_execve.c deleted file mode 100644 index b902981..0000000 --- a/lib/libpthread/thread/thr_execve.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2004 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(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 <errno.h> -#include <pthread.h> -#include <unistd.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_execve); -LT10_COMPAT_DEFAULT(execve); - -__weak_reference(_execve, execve); - -int -_execve(const char *name, char *const *argv, char *const *envp) -{ - struct kse_execve_args args; - struct pthread *curthread = _get_curthread(); - int ret; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - ret = __sys_execve(name, argv, envp); - else { - /* - * When exec'ing, set the kernel signal mask to the thread's - * signal mask to satisfy POSIX requirements. - */ - args.sigmask = curthread->sigmask; - args.sigpend = curthread->sigpend; - args.path = (char *)name; - args.argv = (char **)argv; - args.envp = (char **)envp; - args.reserved = NULL; - ret = kse_thr_interrupt(NULL, KSE_INTR_EXECVE, (long)&args); - } - - return (ret); -} diff --git a/lib/libpthread/thread/thr_exit.c b/lib/libpthread/thread/thr_exit.c deleted file mode 100644 index ba82fd1..0000000 --- a/lib/libpthread/thread/thr_exit.c +++ /dev/null @@ -1,159 +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 <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_exit); -LT10_COMPAT_DEFAULT(pthread_exit); - -void _pthread_exit(void *status); - -__weak_reference(_pthread_exit, pthread_exit); - -void -_thr_exit(char *fname, int lineno, char *msg) -{ - - /* Write an error message to the standard error file descriptor: */ - _thread_printf(2, - "Fatal error '%s' at line %d in file %s (errno = %d)\n", - msg, lineno, fname, errno); - - abort(); -} - -/* - * Only called when a thread is cancelled. It may be more useful - * to call it from pthread_exit() if other ways of asynchronous or - * abnormal thread termination can be found. - */ -void -_thr_exit_cleanup(void) -{ - struct pthread *curthread = _get_curthread(); - - /* - * POSIX states that cancellation/termination of a thread should - * not release any visible resources (such as mutexes) and that - * it is the applications responsibility. Resources that are - * internal to the threads library, including file and fd locks, - * are not visible to the application and need to be released. - */ - /* Unlock all private mutexes: */ - _mutex_unlock_private(curthread); - - /* - * This still isn't quite correct because we don't account - * for held spinlocks (see libc/stdlib/malloc.c). - */ -} - -void -_pthread_exit(void *status) -{ - struct pthread *curthread = _get_curthread(); - kse_critical_t crit; - struct kse *curkse; - - /* Check if this thread is already in the process of exiting: */ - if ((curthread->flags & THR_FLAGS_EXITING) != 0) { - char msg[128]; - snprintf(msg, sizeof(msg), "Thread %p has called " - "pthread_exit() from a destructor. POSIX 1003.1 " - "1996 s16.2.5.2 does not allow this!", curthread); - PANIC(msg); - } - - /* - * Flag this thread as exiting. Threads should now be prevented - * from joining to this thread. - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->flags |= THR_FLAGS_EXITING; - THR_SCHED_UNLOCK(curthread, curthread); - - /* - * To avoid signal-lost problem, if signals had already been - * delivered to us, handle it. we have already set EXITING flag - * so no new signals should be delivered to us. - * XXX this is not enough if signal was delivered just before - * thread called sigprocmask and masked it! in this case, we - * might have to re-post the signal by kill() if the signal - * is targeting process (not for a specified thread). - * Kernel has same signal-lost problem, a signal may be delivered - * to a thread which is on the way to call sigprocmask or thr_exit()! - */ - if (curthread->check_pending) - _thr_sig_check_pending(curthread); - /* Save the return value: */ - curthread->ret = status; - while (curthread->cleanup != NULL) { - pthread_cleanup_pop(1); - } - if (curthread->attr.cleanup_attr != NULL) { - curthread->attr.cleanup_attr(curthread->attr.arg_attr); - } - /* Check if there is thread specific data: */ - if (curthread->specific != NULL) { - /* Run the thread-specific data destructors: */ - _thread_cleanupspecific(); - } - if (!_kse_isthreaded()) - exit(0); - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* Use thread_list_lock */ - _thread_active_threads--; - if ((_thread_scope_system <= 0 && _thread_active_threads == 1) || - (_thread_scope_system > 0 && _thread_active_threads == 0)) { - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - exit(0); - /* Never reach! */ - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - - /* This thread will never be re-scheduled. */ - KSE_LOCK(curkse); - THR_SET_STATE(curthread, PS_DEAD); - _thr_sched_switch_unlocked(curthread); - /* Never reach! */ - - /* This point should not be reached. */ - PANIC("Dead thread has resumed"); -} diff --git a/lib/libpthread/thread/thr_fcntl.c b/lib/libpthread/thread/thr_fcntl.c deleted file mode 100644 index af531b3..0000000 --- a/lib/libpthread/thread/thr_fcntl.c +++ /dev/null @@ -1,78 +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 <stdarg.h> -#include "namespace.h" -#include <fcntl.h> -#include "un-namespace.h" -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__fcntl); -LT10_COMPAT_DEFAULT(fcntl); - -__weak_reference(__fcntl, fcntl); - -int -__fcntl(int fd, int cmd,...) -{ - struct pthread *curthread = _get_curthread(); - int ret, check = 1; - va_list ap; - - _thr_cancel_enter(curthread); - - va_start(ap, cmd); - switch (cmd) { - case F_DUPFD: - ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - check = (ret == -1); - break; - case F_SETFD: - case F_SETFL: - ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); - break; - case F_GETFD: - case F_GETFL: - ret = __sys_fcntl(fd, cmd); - break; - default: - ret = __sys_fcntl(fd, cmd, va_arg(ap, void *)); - } - va_end(ap); - - _thr_cancel_leave(curthread, check); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_find_thread.c b/lib/libpthread/thread/thr_find_thread.c deleted file mode 100644 index 780624e..0000000 --- a/lib/libpthread/thread/thr_find_thread.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -/* - * Find a thread in the linked list of active threads and add a reference - * to it. Threads with positive reference counts will not be deallocated - * until all references are released. - */ -int -_thr_ref_add(struct pthread *curthread, struct pthread *thread, - int include_dead) -{ - kse_critical_t crit; - struct pthread *pthread; - struct kse *curkse; - - if (thread == NULL) - /* Invalid thread: */ - return (EINVAL); - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - pthread = _thr_hash_find(thread); - if (pthread) { - if ((include_dead == 0) && - ((pthread->state == PS_DEAD) || - ((pthread->state == PS_DEADLOCK) || - ((pthread->flags & THR_FLAGS_EXITING) != 0)))) - pthread = NULL; - else { - pthread->refcount++; - if (curthread != NULL) - curthread->critical_count++; - } - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Return zero if the thread exists: */ - return ((pthread != NULL) ? 0 : ESRCH); -} - -void -_thr_ref_delete(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - if (thread != NULL) { - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - thread->refcount--; - if (curthread != NULL) - curthread->critical_count--; - if ((thread->refcount == 0) && - (thread->tlflags & TLFLAGS_GC_SAFE) != 0) - THR_GCLIST_ADD(thread); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } -} diff --git a/lib/libpthread/thread/thr_fork.c b/lib/libpthread/thread/thr_fork.c deleted file mode 100644 index 1fd212e..0000000 --- a/lib/libpthread/thread/thr_fork.c +++ /dev/null @@ -1,128 +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 <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <pthread.h> -#include <spinlock.h> -#include <sys/signalvar.h> - -#include "libc_private.h" -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_fork); -LT10_COMPAT_DEFAULT(fork); - -__weak_reference(_fork, fork); - -pid_t -_fork(void) -{ - sigset_t sigset, oldset; - struct pthread *curthread; - struct pthread_atfork *af; - pid_t ret; - int errsave; - - curthread = _get_curthread(); - - if (!_kse_isthreaded()) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); - ret = __sys_fork(); - if (ret == 0) - /* Child */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, - NULL); - else - __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); - return (ret); - } - - /* - * Masks all signals until we reach a safe point in - * _kse_single_thread, and the signal masks will be - * restored in that function, for M:N thread, all - * signals were already masked in kernel atomically, - * we only need to do this for bound thread. - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); - } - - _pthread_mutex_lock(&_thr_atfork_mutex); - - /* Run down atfork prepare handlers. */ - TAILQ_FOREACH_REVERSE(af, &_thr_atfork_list, atfork_head, qe) { - if (af->prepare != NULL) - af->prepare(); - } - - /* Fork a new process: */ - if (_kse_isthreaded() != 0) { - _malloc_prefork(); - } - if ((ret = __sys_fork()) == 0) { - /* Child process */ - errsave = errno; - - /* Kernel signal mask is restored in _kse_single_thread */ - _kse_single_thread(curthread); - - /* Run down atfork child handlers. */ - TAILQ_FOREACH(af, &_thr_atfork_list, qe) { - if (af->child != NULL) - af->child(); - } - _thr_mutex_reinit(&_thr_atfork_mutex); - } else { - if (_kse_isthreaded() != 0) { - _malloc_postfork(); - } - errsave = errno; - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); - } - /* Run down atfork parent handlers. */ - TAILQ_FOREACH(af, &_thr_atfork_list, qe) { - if (af->parent != NULL) - af->parent(); - } - _pthread_mutex_unlock(&_thr_atfork_mutex); - } - errno = errsave; - - /* Return the process ID: */ - return (ret); -} diff --git a/lib/libpthread/thread/thr_fsync.c b/lib/libpthread/thread/thr_fsync.c deleted file mode 100644 index 9d17050..0000000 --- a/lib/libpthread/thread/thr_fsync.c +++ /dev/null @@ -1,51 +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 <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__fsync); -LT10_COMPAT_DEFAULT(fsync); - -__weak_reference(__fsync, fsync); - -int -__fsync(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_fsync(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_getprio.c b/lib/libpthread/thread/thr_getprio.c deleted file mode 100644 index 426e77d..0000000 --- a/lib/libpthread/thread/thr_getprio.c +++ /dev/null @@ -1,60 +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" - -LT10_COMPAT_PRIVATE(_pthread_getprio); -LT10_COMPAT_DEFAULT(pthread_getprio); - -__weak_reference(_pthread_getprio, pthread_getprio); - -int -_pthread_getprio(pthread_t pthread) -{ - int policy, ret; - struct sched_param param; - - if ((ret = _pthread_getschedparam(pthread, &policy, ¶m)) == 0) - ret = param.sched_priority; - else { - /* Invalid thread: */ - errno = ret; - ret = -1; - } - - /* Return the thread priority or an error status: */ - return (ret); -} diff --git a/lib/libpthread/thread/thr_getschedparam.c b/lib/libpthread/thread/thr_getschedparam.c deleted file mode 100644 index dca342f..0000000 --- a/lib/libpthread/thread/thr_getschedparam.c +++ /dev/null @@ -1,78 +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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_getschedparam); -LT10_COMPAT_DEFAULT(pthread_getschedparam); - -__weak_reference(_pthread_getschedparam, pthread_getschedparam); - -int -_pthread_getschedparam(pthread_t pthread, int *policy, - struct sched_param *param) -{ - struct pthread *curthread = _get_curthread(); - int ret, tmp; - - if ((param == NULL) || (policy == NULL)) - /* Return an invalid argument error: */ - ret = EINVAL; - else if (pthread == curthread) { - /* - * Avoid searching the thread list when it is the current - * thread. - */ - THR_SCHED_LOCK(curthread, curthread); - param->sched_priority = - THR_BASE_PRIORITY(pthread->base_priority); - tmp = pthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, curthread); - *policy = tmp; - ret = 0; - } - /* Find the thread in the list of active threads. */ - else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - THR_SCHED_LOCK(curthread, pthread); - param->sched_priority = - THR_BASE_PRIORITY(pthread->base_priority); - tmp = pthread->attr.sched_policy; - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - *policy = tmp; - } - return (ret); -} diff --git a/lib/libpthread/thread/thr_info.c b/lib/libpthread/thread/thr_info.c deleted file mode 100644 index e8dc506..0000000 --- a/lib/libpthread/thread/thr_info.c +++ /dev/null @@ -1,244 +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 <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include <errno.h> -#include "thr_private.h" - -#ifndef NELEMENTS -#define NELEMENTS(arr) (sizeof(arr) / sizeof(arr[0])) -#endif - -LT10_COMPAT_PRIVATE(_pthread_set_name_np); -LT10_COMPAT_DEFAULT(pthread_set_name_np); - -static void dump_thread(int fd, pthread_t pthread, int long_version); - -__weak_reference(_pthread_set_name_np, pthread_set_name_np); - -struct s_thread_info { - enum pthread_state state; - char *name; -}; - -/* Static variables: */ -static const struct s_thread_info thread_info[] = { - {PS_RUNNING , "Running"}, - {PS_LOCKWAIT , "Waiting on an internal lock"}, - {PS_MUTEX_WAIT , "Waiting on a mutex"}, - {PS_COND_WAIT , "Waiting on a condition variable"}, - {PS_SLEEP_WAIT , "Sleeping"}, - {PS_SIGSUSPEND , "Suspended, waiting for a signal"}, - {PS_SIGWAIT , "Waiting for a signal"}, - {PS_JOIN , "Waiting to join"}, - {PS_SUSPENDED , "Suspended"}, - {PS_DEAD , "Dead"}, - {PS_DEADLOCK , "Deadlocked"}, - {PS_STATE_MAX , "Not a real state!"} -}; - -void -_thread_dump_info(void) -{ - char s[512], tmpfile[128]; - pthread_t pthread; - int fd, i; - - for (i = 0; i < 100000; i++) { - snprintf(tmpfile, sizeof(tmpfile), "/tmp/pthread.dump.%u.%i", - getpid(), i); - /* Open the dump file for append and create it if necessary: */ - if ((fd = __sys_open(tmpfile, O_RDWR | O_CREAT | O_EXCL, - 0666)) < 0) { - /* Can't open the dump file. */ - if (errno == EEXIST) - continue; - /* - * We only need to continue in case of - * EEXIT error. Most other error - * codes means that we will fail all - * the times. - */ - return; - } else { - break; - } - } - if (i==100000) { - /* all 100000 possibilities are in use :( */ - return; - } else { - /* Dump the active threads. */ - strcpy(s, "\n\n========\nACTIVE THREADS\n\n"); - __sys_write(fd, s, strlen(s)); - - /* Enter a loop to report each thread in the global list: */ - TAILQ_FOREACH(pthread, &_thread_list, tle) { - if (pthread->state != PS_DEAD) - dump_thread(fd, pthread, /*long_verson*/ 1); - } - - /* - * Dump the ready threads. - * XXX - We can't easily do this because the run queues - * are per-KSEG. - */ - strcpy(s, "\n\n========\nREADY THREADS - unimplemented\n\n"); - __sys_write(fd, s, strlen(s)); - - - /* - * Dump the waiting threads. - * XXX - We can't easily do this because the wait queues - * are per-KSEG. - */ - strcpy(s, "\n\n========\nWAITING THREADS - unimplemented\n\n"); - __sys_write(fd, s, strlen(s)); - - /* Close the dump file. */ - __sys_close(fd); - } -} - -static void -dump_thread(int fd, pthread_t pthread, int long_version) -{ - struct pthread *curthread = _get_curthread(); - char s[512]; - int i; - - /* Find the state: */ - for (i = 0; i < NELEMENTS(thread_info) - 1; i++) - if (thread_info[i].state == pthread->state) - break; - - /* Output a record for the thread: */ - snprintf(s, sizeof(s), - "--------------------\n" - "Thread %p (%s), scope %s, prio %3d, blocked %s, state %s [%s:%d]\n", - pthread, (pthread->name == NULL) ? "" : pthread->name, - pthread->attr.flags & PTHREAD_SCOPE_SYSTEM ? "system" : "process", - pthread->active_priority, (pthread->blocked != 0) ? "yes" : "no", - thread_info[i].name, pthread->fname, pthread->lineno); - __sys_write(fd, s, strlen(s)); - - if (long_version != 0) { - /* Check if this is the running thread: */ - if (pthread == curthread) { - /* Output a record for the running thread: */ - strcpy(s, "This is the running thread\n"); - __sys_write(fd, s, strlen(s)); - } - /* Check if this is the initial thread: */ - if (pthread == _thr_initial) { - /* Output a record for the initial thread: */ - strcpy(s, "This is the initial thread\n"); - __sys_write(fd, s, strlen(s)); - } - - /* Process according to thread state: */ - switch (pthread->state) { - case PS_SIGWAIT: - snprintf(s, sizeof(s), "sigmask (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->sigmask.__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - - snprintf(s, sizeof(s), "waitset (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->data.sigwait->waitset->__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - break; - /* - * Trap other states that are not explicitly - * coded to dump information: - */ - default: - snprintf(s, sizeof(s), "sigmask (hi) "); - __sys_write(fd, s, strlen(s)); - for (i = _SIG_WORDS - 1; i >= 0; i--) { - snprintf(s, sizeof(s), "%08x ", - pthread->sigmask.__bits[i]); - __sys_write(fd, s, strlen(s)); - } - snprintf(s, sizeof(s), "(lo)\n"); - __sys_write(fd, s, strlen(s)); - break; - } - } -} - -/* Set the thread name for debug: */ -void -_pthread_set_name_np(pthread_t thread, char *name) -{ - struct pthread *curthread = _get_curthread(); - char *new_name; - char *prev_name; - int ret; - - new_name = strdup(name); - /* Add a reference to the target thread. */ - if (_thr_ref_add(curthread, thread, 0) != 0) { - free(new_name); - ret = ESRCH; - } - else { - THR_THREAD_LOCK(curthread, thread); - prev_name = thread->name; - thread->name = new_name; - THR_THREAD_UNLOCK(curthread, thread); - _thr_ref_delete(curthread, thread); - if (prev_name != NULL) { - /* Free space for previous name. */ - free(prev_name); - } - ret = 0; - } -#if 0 - /* XXX - Should return error code. */ - return (ret); -#endif -} diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c deleted file mode 100644 index 5c8aac4..0000000 --- a/lib/libpthread/thread/thr_init.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org> - * 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$ - */ - -/* Allocate space for global thread variables here: */ -#define GLOBAL_PTHREAD_PRIVATE - -#include "namespace.h" -#include <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <machine/reg.h> - -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/event.h> -#include <sys/stat.h> -#include <sys/sysctl.h> -#include <sys/time.h> -#include <sys/ttycom.h> -#include <sys/wait.h> -#include <sys/mman.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <paths.h> -#include <pthread.h> -#include <pthread_np.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "un-namespace.h" - -#include "libc_private.h" -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_libkse_debug); -LT10_COMPAT_PRIVATE(_thread_activated); -LT10_COMPAT_PRIVATE(_thread_active_threads); -LT10_COMPAT_PRIVATE(_thread_list); - -int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); -int __pthread_mutex_lock(pthread_mutex_t *); -int __pthread_mutex_trylock(pthread_mutex_t *); -void _thread_init_hack(void); -extern int _thread_state_running; - -static void init_private(void); -static void init_main_thread(struct pthread *thread); - -/* - * All weak references used within libc should be in this table. - * This is so that static libraries will work. - */ -static void *references[] = { - &_accept, - &_bind, - &_close, - &_connect, - &_dup, - &_dup2, - &_execve, - &_fcntl, - &_flock, - &_flockfile, - &_fstat, - &_fstatfs, - &_fsync, - &_funlockfile, - &_getdirentries, - &_getlogin, - &_getpeername, - &_getsockname, - &_getsockopt, - &_ioctl, - &_kevent, - &_listen, - &_nanosleep, - &_open, - &_pthread_getspecific, - &_pthread_key_create, - &_pthread_key_delete, - &_pthread_mutex_destroy, - &_pthread_mutex_init, - &_pthread_mutex_lock, - &_pthread_mutex_trylock, - &_pthread_mutex_unlock, - &_pthread_mutexattr_init, - &_pthread_mutexattr_destroy, - &_pthread_mutexattr_settype, - &_pthread_once, - &_pthread_setspecific, - &_read, - &_readv, - &_recvfrom, - &_recvmsg, - &_select, - &_sendmsg, - &_sendto, - &_setsockopt, - &_sigaction, - &_sigprocmask, - &_sigsuspend, - &_socket, - &_socketpair, - &_thread_init_hack, - &_wait4, - &_write, - &_writev -}; - -/* - * These are needed when linking statically. All references within - * libgcc (and in the future libc) to these routines are weak, but - * if they are not (strongly) referenced by the application or other - * libraries, then the actual functions will not be loaded. - */ -static void *libgcc_references[] = { - &_pthread_once, - &_pthread_key_create, - &_pthread_key_delete, - &_pthread_getspecific, - &_pthread_setspecific, - &_pthread_mutex_init, - &_pthread_mutex_destroy, - &_pthread_mutex_lock, - &_pthread_mutex_trylock, - &_pthread_mutex_unlock -}; - -#define DUAL_ENTRY(entry) \ - (pthread_func_t)entry, (pthread_func_t)entry - -static pthread_func_t jmp_table[][2] = { - {DUAL_ENTRY(_pthread_atfork)}, /* PJT_ATFORK */ - {DUAL_ENTRY(_pthread_attr_destroy)}, /* PJT_ATTR_DESTROY */ - {DUAL_ENTRY(_pthread_attr_getdetachstate)}, /* PJT_ATTR_GETDETACHSTATE */ - {DUAL_ENTRY(_pthread_attr_getguardsize)}, /* PJT_ATTR_GETGUARDSIZE */ - {DUAL_ENTRY(_pthread_attr_getinheritsched)}, /* PJT_ATTR_GETINHERITSCHED */ - {DUAL_ENTRY(_pthread_attr_getschedparam)}, /* PJT_ATTR_GETSCHEDPARAM */ - {DUAL_ENTRY(_pthread_attr_getschedpolicy)}, /* PJT_ATTR_GETSCHEDPOLICY */ - {DUAL_ENTRY(_pthread_attr_getscope)}, /* PJT_ATTR_GETSCOPE */ - {DUAL_ENTRY(_pthread_attr_getstackaddr)}, /* PJT_ATTR_GETSTACKADDR */ - {DUAL_ENTRY(_pthread_attr_getstacksize)}, /* PJT_ATTR_GETSTACKSIZE */ - {DUAL_ENTRY(_pthread_attr_init)}, /* PJT_ATTR_INIT */ - {DUAL_ENTRY(_pthread_attr_setdetachstate)}, /* PJT_ATTR_SETDETACHSTATE */ - {DUAL_ENTRY(_pthread_attr_setguardsize)}, /* PJT_ATTR_SETGUARDSIZE */ - {DUAL_ENTRY(_pthread_attr_setinheritsched)}, /* PJT_ATTR_SETINHERITSCHED */ - {DUAL_ENTRY(_pthread_attr_setschedparam)}, /* PJT_ATTR_SETSCHEDPARAM */ - {DUAL_ENTRY(_pthread_attr_setschedpolicy)}, /* PJT_ATTR_SETSCHEDPOLICY */ - {DUAL_ENTRY(_pthread_attr_setscope)}, /* PJT_ATTR_SETSCOPE */ - {DUAL_ENTRY(_pthread_attr_setstackaddr)}, /* PJT_ATTR_SETSTACKADDR */ - {DUAL_ENTRY(_pthread_attr_setstacksize)}, /* PJT_ATTR_SETSTACKSIZE */ - {DUAL_ENTRY(_pthread_cancel)}, /* PJT_CANCEL */ - {DUAL_ENTRY(_pthread_cleanup_pop)}, /* PJT_CLEANUP_POP */ - {DUAL_ENTRY(_pthread_cleanup_push)}, /* PJT_CLEANUP_PUSH */ - {DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */ - {DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */ - {DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */ - {DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */ - {DUAL_ENTRY(_pthread_cond_timedwait)}, /* PJT_COND_TIMEDWAIT */ - {(pthread_func_t)__pthread_cond_wait, - (pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */ - {DUAL_ENTRY(_pthread_detach)}, /* PJT_DETACH */ - {DUAL_ENTRY(_pthread_equal)}, /* PJT_EQUAL */ - {DUAL_ENTRY(_pthread_exit)}, /* PJT_EXIT */ - {DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */ - {DUAL_ENTRY(_pthread_join)}, /* PJT_JOIN */ - {DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */ - {DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/ - {DUAL_ENTRY(_pthread_kill)}, /* PJT_KILL */ - {DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */ - {DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */ - {DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */ - {DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */ - {DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */ - {DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */ - {(pthread_func_t)__pthread_mutex_lock, - (pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */ - {(pthread_func_t)__pthread_mutex_trylock, - (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */ - {DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */ - {DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */ - {DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */ - {DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */ - {DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */ - {DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */ - {DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */ - {DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */ - {DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */ - {DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */ - {DUAL_ENTRY(_pthread_setcancelstate)}, /* PJT_SETCANCELSTATE */ - {DUAL_ENTRY(_pthread_setcanceltype)}, /* PJT_SETCANCELTYPE */ - {DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */ - {DUAL_ENTRY(_pthread_sigmask)}, /* PJT_SIGMASK */ - {DUAL_ENTRY(_pthread_testcancel)} /* PJT_TESTCANCEL */ -}; - -static int init_once = 0; - -/* - * Threaded process initialization. - * - * This is only called under two conditions: - * - * 1) Some thread routines have detected that the library hasn't yet - * been initialized (_thr_initial == NULL && curthread == NULL), or - * - * 2) An explicit call to reinitialize after a fork (indicated - * by curthread != NULL) - */ -void -_libpthread_init(struct pthread *curthread) -{ - int fd; - - /* Check if this function has already been called: */ - if ((_thr_initial != NULL) && (curthread == NULL)) - /* Only initialize the threaded application once. */ - return; - - /* - * Make gcc quiescent about {,libgcc_}references not being - * referenced: - */ - if ((references[0] == NULL) || (libgcc_references[0] == NULL)) - PANIC("Failed loading mandatory references in _thread_init"); - - /* Pull debug symbols in for static binary */ - _thread_state_running = PS_RUNNING; - - /* - * Check the size of the jump table to make sure it is preset - * with the correct number of entries. - */ - if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2)) - PANIC("Thread jump table not properly initialized"); - memcpy(__thr_jtable, jmp_table, sizeof(jmp_table)); - - /* - * Check for the special case of this process running as - * or in place of init as pid = 1: - */ - if ((_thr_pid = getpid()) == 1) { - /* - * Setup a new session for this process which is - * assumed to be running as root. - */ - if (setsid() == -1) - PANIC("Can't set session ID"); - if (revoke(_PATH_CONSOLE) != 0) - PANIC("Can't revoke console"); - if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) - PANIC("Can't open console"); - if (setlogin("root") == -1) - PANIC("Can't set login to root"); - if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1) - PANIC("Can't set controlling terminal"); - } - - /* Initialize pthread private data. */ - init_private(); - _kse_init(); - - /* Initialize the initial kse and kseg. */ - _kse_initial = _kse_alloc(NULL, _thread_scope_system > 0); - if (_kse_initial == NULL) - PANIC("Can't allocate initial kse."); - _kse_initial->k_kseg = _kseg_alloc(NULL); - if (_kse_initial->k_kseg == NULL) - PANIC("Can't allocate initial kseg."); - _kse_initial->k_kseg->kg_flags |= KGF_SINGLE_THREAD; - _kse_initial->k_schedq = &_kse_initial->k_kseg->kg_schedq; - - TAILQ_INSERT_TAIL(&_kse_initial->k_kseg->kg_kseq, _kse_initial, k_kgqe); - _kse_initial->k_kseg->kg_ksecount = 1; - - /* Set the initial thread. */ - if (curthread == NULL) { - /* Create and initialize the initial thread. */ - curthread = _thr_alloc(NULL); - if (curthread == NULL) - PANIC("Can't allocate initial thread"); - _thr_initial = curthread; - init_main_thread(curthread); - } else { - /* - * The initial thread is the current thread. It is - * assumed that the current thread is already initialized - * because it is left over from a fork(). - */ - _thr_initial = curthread; - } - _kse_initial->k_kseg->kg_threadcount = 0; - _thr_initial->kse = _kse_initial; - _thr_initial->kseg = _kse_initial->k_kseg; - _thr_initial->active = 1; - - /* - * Add the thread to the thread list and to the KSEG's thread - * queue. - */ - THR_LIST_ADD(_thr_initial); - KSEG_THRQ_ADD(_kse_initial->k_kseg, _thr_initial); - - /* Setup the KSE/thread specific data for the current KSE/thread. */ - _thr_initial->kse->k_curthread = _thr_initial; - _kcb_set(_thr_initial->kse->k_kcb); - _tcb_set(_thr_initial->kse->k_kcb, _thr_initial->tcb); - _thr_initial->kse->k_flags |= KF_INITIALIZED; - - _thr_signal_init(); - _kse_critical_leave(&_thr_initial->tcb->tcb_tmbx); - /* - * activate threaded mode as soon as possible if we are - * being debugged - */ - if (_libkse_debug) - _kse_setthreaded(1); -} - -/* - * This function and pthread_create() do a lot of the same things. - * It'd be nice to consolidate the common stuff in one place. - */ -static void -init_main_thread(struct pthread *thread) -{ - /* Setup the thread attributes. */ - thread->attr = _pthread_attr_default; - thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - /* - * Set up the thread stack. - * - * Create a red zone below the main stack. All other stacks - * are constrained to a maximum size by the parameters - * passed to mmap(), but this stack is only limited by - * resource limits, so this stack needs an explicitly mapped - * red zone to protect the thread stack that is just beyond. - */ - if (mmap((void *)_usrstack - _thr_stack_initial - - _thr_guard_default, _thr_guard_default, 0, MAP_ANON, - -1, 0) == MAP_FAILED) - PANIC("Cannot allocate red zone for initial thread"); - - /* - * Mark the stack as an application supplied stack so that it - * isn't deallocated. - * - * XXX - I'm not sure it would hurt anything to deallocate - * the main thread stack because deallocation doesn't - * actually free() it; it just puts it in the free - * stack queue for later reuse. - */ - thread->attr.stackaddr_attr = (void *)_usrstack - _thr_stack_initial; - thread->attr.stacksize_attr = _thr_stack_initial; - thread->attr.guardsize_attr = _thr_guard_default; - thread->attr.flags |= THR_STACK_USER; - - /* - * Write a magic value to the thread structure - * to help identify valid ones: - */ - thread->magic = THR_MAGIC; - - thread->slice_usec = -1; - thread->cancelflags = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; - thread->name = strdup("initial thread"); - - /* Initialize the thread for signals: */ - SIGEMPTYSET(thread->sigmask); - - /* - * Set up the thread mailbox. The threads saved context - * is also in the mailbox. - */ - thread->tcb->tcb_tmbx.tm_udata = thread; - thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size = - thread->attr.stacksize_attr; - thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp = - thread->attr.stackaddr_attr; - - /* Default the priority of the initial thread: */ - thread->base_priority = THR_DEFAULT_PRIORITY; - thread->active_priority = THR_DEFAULT_PRIORITY; - thread->inherited_priority = 0; - - /* Initialize the mutex queue: */ - TAILQ_INIT(&thread->mutexq); - - /* Initialize hooks in the thread structure: */ - thread->specific = NULL; - thread->cleanup = NULL; - thread->flags = 0; - thread->sigbackout = NULL; - thread->continuation = NULL; - - thread->state = PS_RUNNING; - thread->uniqueid = 0; -} - -static void -init_private(void) -{ - struct clockinfo clockinfo; - size_t len; - int mib[2]; - - /* - * Avoid reinitializing some things if they don't need to be, - * e.g. after a fork(). - */ - if (init_once == 0) { - /* Find the stack top */ - mib[0] = CTL_KERN; - mib[1] = KERN_USRSTACK; - len = sizeof (_usrstack); - if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) - PANIC("Cannot get kern.usrstack from sysctl"); - /* Get the kernel clockrate: */ - mib[0] = CTL_KERN; - mib[1] = KERN_CLOCKRATE; - len = sizeof (struct clockinfo); - if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0) - _clock_res_usec = 1000000 / clockinfo.stathz; - else - _clock_res_usec = CLOCK_RES_USEC; - - _thr_page_size = getpagesize(); - _thr_guard_default = _thr_page_size; - if (sizeof(void *) == 8) { - _thr_stack_default = THR_STACK64_DEFAULT; - _thr_stack_initial = THR_STACK64_INITIAL; - } - else { - _thr_stack_default = THR_STACK32_DEFAULT; - _thr_stack_initial = THR_STACK32_INITIAL; - } - _pthread_attr_default.guardsize_attr = _thr_guard_default; - _pthread_attr_default.stacksize_attr = _thr_stack_default; - TAILQ_INIT(&_thr_atfork_list); - init_once = 1; /* Don't do this again. */ - } else { - /* - * Destroy the locks before creating them. We don't - * know what state they are in so it is better to just - * recreate them. - */ - _lock_destroy(&_thread_signal_lock); - _lock_destroy(&_mutex_static_lock); - _lock_destroy(&_rwlock_static_lock); - _lock_destroy(&_keytable_lock); - } - - /* Initialize everything else. */ - TAILQ_INIT(&_thread_list); - TAILQ_INIT(&_thread_gc_list); - _pthread_mutex_init(&_thr_atfork_mutex, NULL); - - /* - * Initialize the lock for temporary installation of signal - * handlers (to support sigwait() semantics) and for the - * process signal mask and pending signal sets. - */ - if (_lock_init(&_thread_signal_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup) != 0) - PANIC("Cannot initialize _thread_signal_lock"); - if (_lock_init(&_mutex_static_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup) != 0) - PANIC("Cannot initialize mutex static init lock"); - if (_lock_init(&_rwlock_static_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup) != 0) - PANIC("Cannot initialize rwlock static init lock"); - if (_lock_init(&_keytable_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup) != 0) - PANIC("Cannot initialize thread specific keytable lock"); - _thr_spinlock_init(); - - /* Clear pending signals and get the process signal mask. */ - SIGEMPTYSET(_thr_proc_sigpending); - - /* Are we in M:N mode (default) or 1:1 mode? */ -#ifdef SYSTEM_SCOPE_ONLY - _thread_scope_system = 1; -#else - if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL) - _thread_scope_system = 1; - else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL) - _thread_scope_system = -1; -#endif - if (getenv("LIBPTHREAD_DEBUG") != NULL) - _thr_debug_flags |= DBG_INFO_DUMP; - - /* - * _thread_list_lock and _kse_count are initialized - * by _kse_init() - */ -} diff --git a/lib/libpthread/thread/thr_join.c b/lib/libpthread/thread/thr_join.c deleted file mode 100644 index 2396034..0000000 --- a/lib/libpthread/thread/thr_join.c +++ /dev/null @@ -1,162 +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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_join); -LT10_COMPAT_DEFAULT(pthread_join); - -__weak_reference(_pthread_join, pthread_join); - -int -_pthread_join(pthread_t pthread, void **thread_return) -{ - struct pthread *curthread = _get_curthread(); - void *tmp; - kse_critical_t crit; - int ret = 0; - - _thr_cancel_enter(curthread); - - /* Check if the caller has specified an invalid thread: */ - if (pthread == NULL || pthread->magic != THR_MAGIC) { - /* Invalid thread: */ - _thr_cancel_leave(curthread, 1); - return (EINVAL); - } - - /* Check if the caller has specified itself: */ - if (pthread == curthread) { - /* Avoid a deadlock condition: */ - _thr_cancel_leave(curthread, 1); - return (EDEADLK); - } - - /* - * Find the thread in the list of active threads or in the - * list of dead threads: - */ - if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/1)) != 0) { - /* Return an error: */ - _thr_cancel_leave(curthread, 1); - return (ESRCH); - } - - THR_SCHED_LOCK(curthread, pthread); - /* Check if this thread has been detached: */ - if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) { - THR_SCHED_UNLOCK(curthread, pthread); - /* Remove the reference and return an error: */ - _thr_ref_delete(curthread, pthread); - ret = EINVAL; - } else { - /* Lock the target thread while checking its state. */ - if (pthread->state == PS_DEAD) { - /* Return the thread's return value: */ - tmp = pthread->ret; - - /* Detach the thread. */ - pthread->attr.flags |= PTHREAD_DETACHED; - - /* Unlock the thread. */ - THR_SCHED_UNLOCK(curthread, pthread); - - /* - * Remove the thread from the list of active - * threads and add it to the GC list. - */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - THR_LIST_REMOVE(pthread); - THR_GCLIST_ADD(pthread); - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Remove the reference. */ - _thr_ref_delete(curthread, pthread); - if (thread_return != NULL) - *thread_return = tmp; - } - else if (pthread->joiner != NULL) { - /* Unlock the thread and remove the reference. */ - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - - /* Multiple joiners are not supported. */ - ret = ENOTSUP; - } - else { - /* Set the running thread to be the joiner: */ - pthread->joiner = curthread; - - /* Keep track of which thread we're joining to: */ - curthread->join_status.thread = pthread; - - /* Unlock the thread and remove the reference. */ - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - - THR_SCHED_LOCK(curthread, curthread); - while (curthread->join_status.thread == pthread) { - THR_SET_STATE(curthread, PS_JOIN); - THR_SCHED_UNLOCK(curthread, curthread); - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - THR_SCHED_LOCK(curthread, curthread); - } - THR_SCHED_UNLOCK(curthread, curthread); - - if ((curthread->cancelflags & THR_CANCELLING) && - !(curthread->cancelflags & PTHREAD_CANCEL_DISABLE)) { - if (_thr_ref_add(curthread, pthread, 1) == 0) { - THR_SCHED_LOCK(curthread, pthread); - pthread->joiner = NULL; - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - } - pthread_exit(PTHREAD_CANCELED); - } - - /* - * The thread return value and error are set by the - * thread we're joining to when it exits or detaches: - */ - ret = curthread->join_status.error; - if ((ret == 0) && (thread_return != NULL)) - *thread_return = curthread->join_status.ret; - } - } - _thr_cancel_leave(curthread, 1); - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c deleted file mode 100644 index b362fe9..0000000 --- a/lib/libpthread/thread/thr_kern.c +++ /dev/null @@ -1,2549 +0,0 @@ -/* - * Copyright (C) 2003 Daniel M. Eischen <deischen@freebsd.org> - * Copyright (C) 2002 Jonathon Mini <mini@freebsd.org> - * 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. 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. - * - */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/kse.h> -#include <sys/ptrace.h> -#include <sys/signalvar.h> -#include <sys/queue.h> -#include <machine/atomic.h> -#include <machine/sigframe.h> - -#include <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <ucontext.h> -#include <unistd.h> - -#include "atomic_ops.h" -#include "thr_private.h" -#include "libc_private.h" -#ifdef NOTYET -#include "spinlock.h" -#endif - -/* #define DEBUG_THREAD_KERN */ -#ifdef DEBUG_THREAD_KERN -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -/* - * Define a high water mark for the maximum number of threads that - * will be cached. Once this level is reached, any extra threads - * will be free()'d. - */ -#define MAX_CACHED_THREADS 100 -/* - * Define high water marks for the maximum number of KSEs and KSE groups - * that will be cached. Because we support 1:1 threading, there could have - * same number of KSEs and KSE groups as threads. Once these levels are - * reached, any extra KSE and KSE groups will be free()'d. - */ -#define MAX_CACHED_KSES ((_thread_scope_system <= 0) ? 50 : 100) -#define MAX_CACHED_KSEGS ((_thread_scope_system <= 0) ? 50 : 100) - -#define KSE_SET_MBOX(kse, thrd) \ - (kse)->k_kcb->kcb_kmbx.km_curthread = &(thrd)->tcb->tcb_tmbx - -#define KSE_SET_EXITED(kse) (kse)->k_flags |= KF_EXITED - -/* - * Macros for manipulating the run queues. The priority queue - * routines use the thread's pqe link and also handle the setting - * and clearing of the thread's THR_FLAGS_IN_RUNQ flag. - */ -#define KSE_RUNQ_INSERT_HEAD(kse, thrd) \ - _pq_insert_head(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_INSERT_TAIL(kse, thrd) \ - _pq_insert_tail(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_REMOVE(kse, thrd) \ - _pq_remove(&(kse)->k_schedq->sq_runq, thrd) -#define KSE_RUNQ_FIRST(kse) \ - ((_libkse_debug == 0) ? \ - _pq_first(&(kse)->k_schedq->sq_runq) : \ - _pq_first_debug(&(kse)->k_schedq->sq_runq)) - -#define KSE_RUNQ_THREADS(kse) ((kse)->k_schedq->sq_runq.pq_threads) - -#define THR_NEED_CANCEL(thrd) \ - (((thrd)->cancelflags & THR_CANCELLING) != 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_DISABLE) == 0 && \ - (((thrd)->cancelflags & THR_AT_CANCEL_POINT) != 0 || \ - ((thrd)->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) - -#define THR_NEED_ASYNC_CANCEL(thrd) \ - (((thrd)->cancelflags & THR_CANCELLING) != 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_DISABLE) == 0 && \ - (((thrd)->cancelflags & THR_AT_CANCEL_POINT) == 0 && \ - ((thrd)->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) - -/* - * We've got to keep track of everything that is allocated, not only - * to have a speedy free list, but also so they can be deallocated - * after a fork(). - */ -static TAILQ_HEAD(, kse) active_kseq; -static TAILQ_HEAD(, kse) free_kseq; -static TAILQ_HEAD(, kse_group) free_kse_groupq; -static TAILQ_HEAD(, kse_group) active_kse_groupq; -static TAILQ_HEAD(, kse_group) gc_ksegq; -static struct lock kse_lock; /* also used for kseg queue */ -static int free_kse_count = 0; -static int free_kseg_count = 0; -static TAILQ_HEAD(, pthread) free_threadq; -static struct lock thread_lock; -static int free_thread_count = 0; -static int inited = 0; -static int active_kse_count = 0; -static int active_kseg_count = 0; -static u_int64_t next_uniqueid = 1; - -LIST_HEAD(thread_hash_head, pthread); -#define THREAD_HASH_QUEUES 127 -static struct thread_hash_head thr_hashtable[THREAD_HASH_QUEUES]; -#define THREAD_HASH(thrd) ((unsigned long)thrd % THREAD_HASH_QUEUES) - -/* Lock for thread tcb constructor/destructor */ -static pthread_mutex_t _tcb_mutex; - -#ifdef DEBUG_THREAD_KERN -static void dump_queues(struct kse *curkse); -#endif -static void kse_check_completed(struct kse *kse); -static void kse_check_waitq(struct kse *kse); -static void kse_fini(struct kse *curkse); -static void kse_reinit(struct kse *kse, int sys_scope); -static void kse_sched_multi(struct kse_mailbox *kmbx); -static void kse_sched_single(struct kse_mailbox *kmbx); -static void kse_switchout_thread(struct kse *kse, struct pthread *thread); -static void kse_wait(struct kse *kse, struct pthread *td_wait, int sigseq); -static void kse_free_unlocked(struct kse *kse); -static void kse_destroy(struct kse *kse); -static void kseg_free_unlocked(struct kse_group *kseg); -static void kseg_init(struct kse_group *kseg); -static void kseg_reinit(struct kse_group *kseg); -static void kseg_destroy(struct kse_group *kseg); -static void kse_waitq_insert(struct pthread *thread); -static void kse_wakeup_multi(struct kse *curkse); -static struct kse_mailbox *kse_wakeup_one(struct pthread *thread); -static void thr_cleanup(struct kse *kse, struct pthread *curthread); -static void thr_link(struct pthread *thread); -static void thr_resume_wrapper(int sig, siginfo_t *, ucontext_t *); -static void thr_resume_check(struct pthread *curthread, ucontext_t *ucp); -static int thr_timedout(struct pthread *thread, struct timespec *curtime); -static void thr_unlink(struct pthread *thread); -static void thr_destroy(struct pthread *curthread, struct pthread *thread); -static void thread_gc(struct pthread *thread); -static void kse_gc(struct pthread *thread); -static void kseg_gc(struct pthread *thread); - -static void __inline -thr_accounting(struct pthread *thread) -{ - if ((thread->slice_usec != -1) && - (thread->slice_usec <= TIMESLICE_USEC) && - (thread->attr.sched_policy != SCHED_FIFO)) { - thread->slice_usec += (thread->tcb->tcb_tmbx.tm_uticks - + thread->tcb->tcb_tmbx.tm_sticks) * _clock_res_usec; - /* Check for time quantum exceeded: */ - if (thread->slice_usec > TIMESLICE_USEC) - thread->slice_usec = -1; - } - thread->tcb->tcb_tmbx.tm_uticks = 0; - thread->tcb->tcb_tmbx.tm_sticks = 0; -} - -/* - * This is called after a fork(). - * No locks need to be taken here since we are guaranteed to be - * single threaded. - * - * XXX - * POSIX says for threaded process, fork() function is used - * only to run new programs, and the effects of calling functions - * that require certain resources between the call to fork() and - * the call to an exec function are undefined. - * - * It is not safe to free memory after fork(), because these data - * structures may be in inconsistent state. - */ -void -_kse_single_thread(struct pthread *curthread) -{ -#ifdef NOTYET - struct kse *kse; - struct kse_group *kseg; - struct pthread *thread; - - _thr_spinlock_init(); - *__malloc_lock = (spinlock_t)_SPINLOCK_INITIALIZER; - if (__isthreaded) { - _thr_rtld_fini(); - _thr_signal_deinit(); - } - __isthreaded = 0; - /* - * Restore signal mask early, so any memory problems could - * dump core. - */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - _thread_active_threads = 1; - - curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL; - curthread->attr.flags &= ~PTHREAD_SCOPE_PROCESS; - curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - - /* - * Enter a loop to remove and free all threads other than - * the running thread from the active thread list: - */ - while ((thread = TAILQ_FIRST(&_thread_list)) != NULL) { - THR_GCLIST_REMOVE(thread); - /* - * Remove this thread from the list (the current - * thread will be removed but re-added by libpthread - * initialization. - */ - TAILQ_REMOVE(&_thread_list, thread, tle); - /* Make sure this isn't the running thread: */ - if (thread != curthread) { - _thr_stack_free(&thread->attr); - if (thread->specific != NULL) - free(thread->specific); - thr_destroy(curthread, thread); - } - } - - TAILQ_INIT(&curthread->mutexq); /* initialize mutex queue */ - curthread->joiner = NULL; /* no joining threads yet */ - curthread->refcount = 0; - SIGEMPTYSET(curthread->sigpend); /* clear pending signals */ - - /* Don't free thread-specific data as the caller may require it */ - - /* Free the free KSEs: */ - while ((kse = TAILQ_FIRST(&free_kseq)) != NULL) { - TAILQ_REMOVE(&free_kseq, kse, k_qe); - kse_destroy(kse); - } - free_kse_count = 0; - - /* Free the active KSEs: */ - while ((kse = TAILQ_FIRST(&active_kseq)) != NULL) { - TAILQ_REMOVE(&active_kseq, kse, k_qe); - kse_destroy(kse); - } - active_kse_count = 0; - - /* Free the free KSEGs: */ - while ((kseg = TAILQ_FIRST(&free_kse_groupq)) != NULL) { - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - kseg_destroy(kseg); - } - free_kseg_count = 0; - - /* Free the active KSEGs: */ - while ((kseg = TAILQ_FIRST(&active_kse_groupq)) != NULL) { - TAILQ_REMOVE(&active_kse_groupq, kseg, kg_qe); - kseg_destroy(kseg); - } - active_kseg_count = 0; - - /* Free the free threads. */ - while ((thread = TAILQ_FIRST(&free_threadq)) != NULL) { - TAILQ_REMOVE(&free_threadq, thread, tle); - thr_destroy(curthread, thread); - } - free_thread_count = 0; - - /* Free the to-be-gc'd threads. */ - while ((thread = TAILQ_FIRST(&_thread_gc_list)) != NULL) { - TAILQ_REMOVE(&_thread_gc_list, thread, gcle); - thr_destroy(curthread, thread); - } - TAILQ_INIT(&gc_ksegq); - _gc_count = 0; - - if (inited != 0) { - /* - * Destroy these locks; they'll be recreated to assure they - * are in the unlocked state. - */ - _lock_destroy(&kse_lock); - _lock_destroy(&thread_lock); - _lock_destroy(&_thread_list_lock); - inited = 0; - } - - /* We're no longer part of any lists */ - curthread->tlflags = 0; - - /* - * After a fork, we are still operating on the thread's original - * stack. Don't clear the THR_FLAGS_USER from the thread's - * attribute flags. - */ - - /* Initialize the threads library. */ - curthread->kse = NULL; - curthread->kseg = NULL; - _kse_initial = NULL; - _libpthread_init(curthread); -#else - int i; - - /* Reset the current thread and KSE lock data. */ - for (i = 0; i < curthread->locklevel; i++) { - _lockuser_reinit(&curthread->lockusers[i], (void *)curthread); - } - curthread->locklevel = 0; - for (i = 0; i < curthread->kse->k_locklevel; i++) { - _lockuser_reinit(&curthread->kse->k_lockusers[i], - (void *)curthread->kse); - _LCK_SET_PRIVATE2(&curthread->kse->k_lockusers[i], NULL); - } - curthread->kse->k_locklevel = 0; - _thr_spinlock_init(); - if (__isthreaded) { - _thr_rtld_fini(); - _thr_signal_deinit(); - } - __isthreaded = 0; - curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL; - curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - - /* After a fork(), there child should have no pending signals. */ - sigemptyset(&curthread->sigpend); - - /* - * Restore signal mask early, so any memory problems could - * dump core. - */ - sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - _thread_active_threads = 1; -#endif -} - -/* - * This is used to initialize housekeeping and to initialize the - * KSD for the KSE. - */ -void -_kse_init(void) -{ - if (inited == 0) { - TAILQ_INIT(&active_kseq); - TAILQ_INIT(&active_kse_groupq); - TAILQ_INIT(&free_kseq); - TAILQ_INIT(&free_kse_groupq); - TAILQ_INIT(&free_threadq); - TAILQ_INIT(&gc_ksegq); - if (_lock_init(&kse_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup) != 0) - PANIC("Unable to initialize free KSE queue lock"); - if (_lock_init(&thread_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup) != 0) - PANIC("Unable to initialize free thread queue lock"); - if (_lock_init(&_thread_list_lock, LCK_ADAPTIVE, - _kse_lock_wait, _kse_lock_wakeup) != 0) - PANIC("Unable to initialize thread list lock"); - _pthread_mutex_init(&_tcb_mutex, NULL); - active_kse_count = 0; - active_kseg_count = 0; - _gc_count = 0; - inited = 1; - } -} - -/* - * This is called when the first thread (other than the initial - * thread) is created. - */ -int -_kse_setthreaded(int threaded) -{ - sigset_t sigset; - - if ((threaded != 0) && (__isthreaded == 0)) { - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); - - /* - * Tell the kernel to create a KSE for the initial thread - * and enable upcalls in it. - */ - _kse_initial->k_flags |= KF_STARTED; - - if (_thread_scope_system <= 0) { - _thr_initial->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - _kse_initial->k_kseg->kg_flags &= ~KGF_SINGLE_THREAD; - _kse_initial->k_kcb->kcb_kmbx.km_curthread = NULL; - } - else { - /* - * For bound thread, kernel reads mailbox pointer - * once, we'd set it here before calling kse_create. - */ - _tcb_set(_kse_initial->k_kcb, _thr_initial->tcb); - KSE_SET_MBOX(_kse_initial, _thr_initial); - _kse_initial->k_kcb->kcb_kmbx.km_flags |= KMF_BOUND; - } - - /* - * Locking functions in libc are required when there are - * threads other than the initial thread. - */ - _thr_rtld_init(); - - __isthreaded = 1; - if (kse_create(&_kse_initial->k_kcb->kcb_kmbx, 0) != 0) { - _kse_initial->k_flags &= ~KF_STARTED; - __isthreaded = 0; - PANIC("kse_create() failed\n"); - return (-1); - } - _thr_initial->tcb->tcb_tmbx.tm_lwp = - _kse_initial->k_kcb->kcb_kmbx.km_lwp; - _thread_activated = 1; - -#ifndef SYSTEM_SCOPE_ONLY - if (_thread_scope_system <= 0) { - /* Set current thread to initial thread */ - _tcb_set(_kse_initial->k_kcb, _thr_initial->tcb); - KSE_SET_MBOX(_kse_initial, _thr_initial); - _thr_start_sig_daemon(); - _thr_setmaxconcurrency(); - } - else -#endif - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, - NULL); - } - return (0); -} - -/* - * Lock wait and wakeup handlers for KSE locks. These are only used by - * KSEs, and should never be used by threads. KSE locks include the - * KSE group lock (used for locking the scheduling queue) and the - * kse_lock defined above. - * - * When a KSE lock attempt blocks, the entire KSE blocks allowing another - * KSE to run. For the most part, it doesn't make much sense to try and - * schedule another thread because you need to lock the scheduling queue - * in order to do that. And since the KSE lock is used to lock the scheduling - * queue, you would just end up blocking again. - */ -void -_kse_lock_wait(struct lock *lock, struct lockuser *lu) -{ - struct kse *curkse = (struct kse *)_LCK_GET_PRIVATE(lu); - struct timespec ts; - int saved_flags; - - if (curkse->k_kcb->kcb_kmbx.km_curthread != NULL) - PANIC("kse_lock_wait does not disable upcall.\n"); - /* - * Enter a loop to wait until we get the lock. - */ - ts.tv_sec = 0; - ts.tv_nsec = 1000000; /* 1 sec */ - while (!_LCK_GRANTED(lu)) { - /* - * Yield the kse and wait to be notified when the lock - * is granted. - */ - saved_flags = curkse->k_kcb->kcb_kmbx.km_flags; - curkse->k_kcb->kcb_kmbx.km_flags |= KMF_NOUPCALL | - KMF_NOCOMPLETED; - kse_release(&ts); - curkse->k_kcb->kcb_kmbx.km_flags = saved_flags; - } -} - -void -_kse_lock_wakeup(struct lock *lock, struct lockuser *lu) -{ - struct kse *curkse; - struct kse *kse; - struct kse_mailbox *mbx; - - curkse = _get_curkse(); - kse = (struct kse *)_LCK_GET_PRIVATE(lu); - - if (kse == curkse) - PANIC("KSE trying to wake itself up in lock"); - else { - mbx = &kse->k_kcb->kcb_kmbx; - _lock_grant(lock, lu); - /* - * Notify the owning kse that it has the lock. - * It is safe to pass invalid address to kse_wakeup - * even if the mailbox is not in kernel at all, - * and waking up a wrong kse is also harmless. - */ - kse_wakeup(mbx); - } -} - -/* - * Thread wait and wakeup handlers for thread locks. These are only used - * by threads, never by KSEs. Thread locks include the per-thread lock - * (defined in its structure), and condition variable and mutex locks. - */ -void -_thr_lock_wait(struct lock *lock, struct lockuser *lu) -{ - struct pthread *curthread = (struct pthread *)lu->lu_private; - - do { - THR_LOCK_SWITCH(curthread); - THR_SET_STATE(curthread, PS_LOCKWAIT); - _thr_sched_switch_unlocked(curthread); - } while (!_LCK_GRANTED(lu)); -} - -void -_thr_lock_wakeup(struct lock *lock, struct lockuser *lu) -{ - struct pthread *thread; - struct pthread *curthread; - struct kse_mailbox *kmbx; - - curthread = _get_curthread(); - thread = (struct pthread *)_LCK_GET_PRIVATE(lu); - - THR_SCHED_LOCK(curthread, thread); - _lock_grant(lock, lu); - kmbx = _thr_setrunnable_unlocked(thread); - THR_SCHED_UNLOCK(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); -} - -kse_critical_t -_kse_critical_enter(void) -{ - kse_critical_t crit; - - crit = (kse_critical_t)_kcb_critical_enter(); - return (crit); -} - -void -_kse_critical_leave(kse_critical_t crit) -{ - struct pthread *curthread; - - _kcb_critical_leave((struct kse_thr_mailbox *)crit); - if ((crit != NULL) && ((curthread = _get_curthread()) != NULL)) - THR_YIELD_CHECK(curthread); -} - -int -_kse_in_critical(void) -{ - return (_kcb_in_critical()); -} - -void -_thr_critical_enter(struct pthread *thread) -{ - thread->critical_count++; -} - -void -_thr_critical_leave(struct pthread *thread) -{ - thread->critical_count--; - THR_YIELD_CHECK(thread); -} - -void -_thr_sched_switch(struct pthread *curthread) -{ - struct kse *curkse; - - (void)_kse_critical_enter(); - curkse = _get_curkse(); - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - _thr_sched_switch_unlocked(curthread); -} - -/* - * XXX - We may need to take the scheduling lock before calling - * this, or perhaps take the lock within here before - * doing anything else. - */ -void -_thr_sched_switch_unlocked(struct pthread *curthread) -{ - struct kse *curkse; - volatile int resume_once = 0; - ucontext_t *uc; - - /* We're in the scheduler, 5 by 5: */ - curkse = curthread->kse; - - curthread->need_switchout = 1; /* The thread yielded on its own. */ - curthread->critical_yield = 0; /* No need to yield anymore. */ - - /* Thread can unlock the scheduler lock. */ - curthread->lock_switch = 1; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - kse_sched_single(&curkse->k_kcb->kcb_kmbx); - else { - if (__predict_false(_libkse_debug != 0)) { - /* - * Because debugger saves single step status in thread - * mailbox's tm_dflags, we can safely clear single - * step status here. the single step status will be - * restored by kse_switchin when the thread is - * switched in again. This also lets uts run in full - * speed. - */ - ptrace(PT_CLEARSTEP, curkse->k_kcb->kcb_kmbx.km_lwp, - (caddr_t) 1, 0); - } - - KSE_SET_SWITCH(curkse); - _thread_enter_uts(curthread->tcb, curkse->k_kcb); - } - - /* - * Unlock the scheduling queue and leave the - * critical region. - */ - /* Don't trust this after a switch! */ - curkse = curthread->kse; - - curthread->lock_switch = 0; - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* - * This thread is being resumed; check for cancellations. - */ - if (THR_NEED_ASYNC_CANCEL(curthread) && !THR_IN_CRITICAL(curthread)) { - uc = alloca(sizeof(ucontext_t)); - resume_once = 0; - THR_GETCONTEXT(uc); - if (resume_once == 0) { - resume_once = 1; - curthread->check_pending = 0; - thr_resume_check(curthread, uc); - } - } - THR_ACTIVATE_LAST_LOCK(curthread); -} - -/* - * This is the scheduler for a KSE which runs a scope system thread. - * The multi-thread KSE scheduler should also work for a single threaded - * KSE, but we use a separate scheduler so that it can be fine-tuned - * to be more efficient (and perhaps not need a separate stack for - * the KSE, allowing it to use the thread's stack). - */ - -static void -kse_sched_single(struct kse_mailbox *kmbx) -{ - struct kse *curkse; - struct pthread *curthread; - struct timespec ts; - sigset_t sigmask; - int i, sigseqno, level, first = 0; - - curkse = (struct kse *)kmbx->km_udata; - curthread = curkse->k_curthread; - - if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { - /* Setup this KSEs specific data. */ - _kcb_set(curkse->k_kcb); - _tcb_set(curkse->k_kcb, curthread->tcb); - curkse->k_flags |= KF_INITIALIZED; - first = 1; - curthread->active = 1; - - /* Setup kernel signal masks for new thread. */ - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - /* - * Enter critical region, this is meanless for bound thread, - * It is used to let other code work, those code want mailbox - * to be cleared. - */ - (void)_kse_critical_enter(); - } else { - /* - * Bound thread always has tcb set, this prevent some - * code from blindly setting bound thread tcb to NULL, - * buggy code ? - */ - _tcb_set(curkse->k_kcb, curthread->tcb); - } - - curthread->critical_yield = 0; - curthread->need_switchout = 0; - - /* - * Lock the scheduling queue. - * - * There is no scheduling queue for single threaded KSEs, - * but we need a lock for protection regardless. - */ - if (curthread->lock_switch == 0) - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - - /* - * This has to do the job of kse_switchout_thread(), only - * for a single threaded KSE/KSEG. - */ - - switch (curthread->state) { - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - if (THR_NEED_CANCEL(curthread)) { - curthread->interrupted = 1; - curthread->continuation = _thr_finish_cancellation; - THR_SET_STATE(curthread, PS_RUNNING); - } - break; - - case PS_LOCKWAIT: - /* - * This state doesn't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - level = curthread->locklevel - 1; - if (_LCK_GRANTED(&curthread->lockusers[level])) - THR_SET_STATE(curthread, PS_RUNNING); - break; - - case PS_DEAD: - /* Unlock the scheduling queue and exit the KSE and thread. */ - thr_cleanup(curkse, curthread); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - PANIC("bound thread shouldn't get here\n"); - break; - - case PS_JOIN: - if (THR_NEED_CANCEL(curthread)) { - curthread->join_status.thread = NULL; - THR_SET_STATE(curthread, PS_RUNNING); - } else { - /* - * This state doesn't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_SUSPENDED: - if (THR_NEED_CANCEL(curthread)) { - curthread->interrupted = 1; - THR_SET_STATE(curthread, PS_RUNNING); - } else { - /* - * These states don't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_RUNNING: - if ((curthread->flags & THR_FLAGS_SUSPENDED) != 0 && - !THR_NEED_CANCEL(curthread)) { - THR_SET_STATE(curthread, PS_SUSPENDED); - /* - * These states don't timeout. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - break; - - case PS_SIGWAIT: - PANIC("bound thread does not have SIGWAIT state\n"); - - case PS_SLEEP_WAIT: - PANIC("bound thread does not have SLEEP_WAIT state\n"); - - case PS_SIGSUSPEND: - PANIC("bound thread does not have SIGSUSPEND state\n"); - - case PS_DEADLOCK: - /* - * These states don't timeout and don't need - * to be in the waiting queue. - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - break; - - default: - PANIC("Unknown state\n"); - break; - } - - while (curthread->state != PS_RUNNING) { - sigseqno = curkse->k_sigseqno; - if (curthread->check_pending != 0) { - /* - * Install pending signals into the frame, possible - * cause mutex or condvar backout. - */ - curthread->check_pending = 0; - SIGFILLSET(sigmask); - - /* - * Lock out kernel signal code when we are processing - * signals, and get a fresh copy of signal mask. - */ - __sys_sigprocmask(SIG_SETMASK, &sigmask, - &curthread->sigmask); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(curthread->sigmask, i)) - continue; - if (SIGISMEMBER(curthread->sigpend, i)) - (void)_thr_sig_add(curthread, i, - &curthread->siginfo[i-1]); - } - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, - NULL); - /* The above code might make thread runnable */ - if (curthread->state == PS_RUNNING) - break; - } - THR_DEACTIVATE_LAST_LOCK(curthread); - kse_wait(curkse, curthread, sigseqno); - THR_ACTIVATE_LAST_LOCK(curthread); - if (curthread->wakeup_time.tv_sec >= 0) { - KSE_GET_TOD(curkse, &ts); - if (thr_timedout(curthread, &ts)) { - /* Indicate the thread timedout: */ - curthread->timeout = 1; - /* Make the thread runnable. */ - THR_SET_STATE(curthread, PS_RUNNING); - } - } - } - - if (curthread->lock_switch == 0) { - /* Unlock the scheduling queue. */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - } - - DBG_MSG("Continuing bound thread %p\n", curthread); - if (first) { - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - pthread_exit(curthread->start_routine(curthread->arg)); - } -} - -#ifdef DEBUG_THREAD_KERN -static void -dump_queues(struct kse *curkse) -{ - struct pthread *thread; - - DBG_MSG("Threads in waiting queue:\n"); - TAILQ_FOREACH(thread, &curkse->k_kseg->kg_schedq.sq_waitq, pqe) { - DBG_MSG(" thread %p, state %d, blocked %d\n", - thread, thread->state, thread->blocked); - } -} -#endif - -/* - * This is the scheduler for a KSE which runs multiple threads. - */ -static void -kse_sched_multi(struct kse_mailbox *kmbx) -{ - struct kse *curkse; - struct pthread *curthread, *td_wait; - int ret; - - curkse = (struct kse *)kmbx->km_udata; - THR_ASSERT(curkse->k_kcb->kcb_kmbx.km_curthread == NULL, - "Mailbox not null in kse_sched_multi"); - - /* Check for first time initialization: */ - if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { - /* Setup this KSEs specific data. */ - _kcb_set(curkse->k_kcb); - - /* Set this before grabbing the context. */ - curkse->k_flags |= KF_INITIALIZED; - } - - /* - * No current thread anymore, calling _get_curthread in UTS - * should dump core - */ - _tcb_set(curkse->k_kcb, NULL); - - /* If this is an upcall; take the scheduler lock. */ - if (!KSE_IS_SWITCH(curkse)) - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - else - KSE_CLEAR_SWITCH(curkse); - - if (KSE_IS_IDLE(curkse)) { - KSE_CLEAR_IDLE(curkse); - curkse->k_kseg->kg_idle_kses--; - } - - /* - * Now that the scheduler lock is held, get the current - * thread. The KSE's current thread cannot be safely - * examined without the lock because it could have returned - * as completed on another KSE. See kse_check_completed(). - */ - curthread = curkse->k_curthread; - - /* - * If the current thread was completed in another KSE, then - * it will be in the run queue. Don't mark it as being blocked. - */ - if ((curthread != NULL) && - ((curthread->flags & THR_FLAGS_IN_RUNQ) == 0) && - (curthread->need_switchout == 0)) { - /* - * Assume the current thread is blocked; when the - * completed threads are checked and if the current - * thread is among the completed, the blocked flag - * will be cleared. - */ - curthread->blocked = 1; - DBG_MSG("Running thread %p is now blocked in kernel.\n", - curthread); - } - - /* Check for any unblocked threads in the kernel. */ - kse_check_completed(curkse); - - /* - * Check for threads that have timed-out. - */ - kse_check_waitq(curkse); - - /* - * Switchout the current thread, if necessary, as the last step - * so that it is inserted into the run queue (if it's runnable) - * _after_ any other threads that were added to it above. - */ - if (curthread == NULL) - ; /* Nothing to do here. */ - else if ((curthread->need_switchout == 0) && DBG_CAN_RUN(curthread) && - (curthread->blocked == 0) && (THR_IN_CRITICAL(curthread))) { - /* - * Resume the thread and tell it to yield when - * it leaves the critical region. - */ - curthread->critical_yield = 1; - curthread->active = 1; - if ((curthread->flags & THR_FLAGS_IN_RUNQ) != 0) - KSE_RUNQ_REMOVE(curkse, curthread); - curkse->k_curthread = curthread; - curthread->kse = curkse; - DBG_MSG("Continuing thread %p in critical region\n", - curthread); - kse_wakeup_multi(curkse); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - if (ret != 0) - PANIC("Can't resume thread in critical region\n"); - } - else if ((curthread->flags & THR_FLAGS_IN_RUNQ) == 0) { - curthread->tcb->tcb_tmbx.tm_lwp = 0; - kse_switchout_thread(curkse, curthread); - } - curkse->k_curthread = NULL; - -#ifdef DEBUG_THREAD_KERN - dump_queues(curkse); -#endif - - /* Check if there are no threads ready to run: */ - while (((curthread = KSE_RUNQ_FIRST(curkse)) == NULL) && - (curkse->k_kseg->kg_threadcount != 0) && - ((curkse->k_flags & KF_TERMINATED) == 0)) { - /* - * Wait for a thread to become active or until there are - * no more threads. - */ - td_wait = KSE_WAITQ_FIRST(curkse); - kse_wait(curkse, td_wait, 0); - kse_check_completed(curkse); - kse_check_waitq(curkse); - } - - /* Check for no more threads: */ - if ((curkse->k_kseg->kg_threadcount == 0) || - ((curkse->k_flags & KF_TERMINATED) != 0)) { - /* - * Normally this shouldn't return, but it will if there - * are other KSEs running that create new threads that - * are assigned to this KSE[G]. For instance, if a scope - * system thread were to create a scope process thread - * and this kse[g] is the initial kse[g], then that newly - * created thread would be assigned to us (the initial - * kse[g]). - */ - kse_wakeup_multi(curkse); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - kse_fini(curkse); - /* never returns */ - } - - THR_ASSERT(curthread != NULL, - "Return from kse_wait/fini without thread."); - THR_ASSERT(curthread->state != PS_DEAD, - "Trying to resume dead thread!"); - KSE_RUNQ_REMOVE(curkse, curthread); - - /* - * Make the selected thread the current thread. - */ - curkse->k_curthread = curthread; - - /* - * Make sure the current thread's kse points to this kse. - */ - curthread->kse = curkse; - - /* - * Reset the time slice if this thread is running for the first - * time or running again after using its full time slice allocation. - */ - if (curthread->slice_usec == -1) - curthread->slice_usec = 0; - - /* Mark the thread active. */ - curthread->active = 1; - - /* - * The thread's current signal frame will only be NULL if it - * is being resumed after being blocked in the kernel. In - * this case, and if the thread needs to run down pending - * signals or needs a cancellation check, we need to add a - * signal frame to the thread's context. - */ - if (curthread->lock_switch == 0 && curthread->state == PS_RUNNING && - (curthread->check_pending != 0 || - THR_NEED_ASYNC_CANCEL(curthread)) && - !THR_IN_CRITICAL(curthread)) { - curthread->check_pending = 0; - signalcontext(&curthread->tcb->tcb_tmbx.tm_context, 0, - (__sighandler_t *)thr_resume_wrapper); - } - kse_wakeup_multi(curkse); - /* - * Continue the thread at its current frame: - */ - if (curthread->lock_switch != 0) { - /* - * This thread came from a scheduler switch; it will - * unlock the scheduler lock and set the mailbox. - */ - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 0); - } else { - /* This thread won't unlock the scheduler lock. */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - } - if (ret != 0) - PANIC("Thread has returned from _thread_switch"); - - /* This point should not be reached. */ - PANIC("Thread has returned from _thread_switch"); -} - -static void -thr_resume_wrapper(int sig, siginfo_t *siginfo, ucontext_t *ucp) -{ - struct pthread *curthread = _get_curthread(); - struct kse *curkse; - int ret, err_save = errno; - - DBG_MSG(">>> sig wrapper\n"); - if (curthread->lock_switch) - PANIC("thr_resume_wrapper, lock_switch != 0\n"); - thr_resume_check(curthread, ucp); - errno = err_save; - _kse_critical_enter(); - curkse = curthread->kse; - curthread->tcb->tcb_tmbx.tm_context = *ucp; - ret = _thread_switch(curkse->k_kcb, curthread->tcb, 1); - if (ret != 0) - PANIC("thr_resume_wrapper: thread has returned " - "from _thread_switch"); - /* THR_SETCONTEXT(ucp); */ /* not work, why ? */ -} - -static void -thr_resume_check(struct pthread *curthread, ucontext_t *ucp) -{ - _thr_sig_rundown(curthread, ucp); - - if (THR_NEED_ASYNC_CANCEL(curthread)) - pthread_testcancel(); -} - -/* - * Clean up a thread. This must be called with the thread's KSE - * scheduling lock held. The thread must be a thread from the - * KSE's group. - */ -static void -thr_cleanup(struct kse *curkse, struct pthread *thread) -{ - struct pthread *joiner; - struct kse_mailbox *kmbx = NULL; - int sys_scope; - - thread->active = 0; - thread->need_switchout = 0; - thread->lock_switch = 0; - thread->check_pending = 0; - - if ((joiner = thread->joiner) != NULL) { - /* Joinee scheduler lock held; joiner won't leave. */ - if (joiner->kseg == curkse->k_kseg) { - if (joiner->join_status.thread == thread) { - joiner->join_status.thread = NULL; - joiner->join_status.ret = thread->ret; - (void)_thr_setrunnable_unlocked(joiner); - } - } else { - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - /* The joiner may have removed itself and exited. */ - if (_thr_ref_add(thread, joiner, 0) == 0) { - KSE_SCHED_LOCK(curkse, joiner->kseg); - if (joiner->join_status.thread == thread) { - joiner->join_status.thread = NULL; - joiner->join_status.ret = thread->ret; - kmbx = _thr_setrunnable_unlocked(joiner); - } - KSE_SCHED_UNLOCK(curkse, joiner->kseg); - _thr_ref_delete(thread, joiner); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - } - thread->attr.flags |= PTHREAD_DETACHED; - } - - if (!(sys_scope = (thread->attr.flags & PTHREAD_SCOPE_SYSTEM))) { - /* - * Remove the thread from the KSEG's list of threads. - */ - KSEG_THRQ_REMOVE(thread->kseg, thread); - /* - * Migrate the thread to the main KSE so that this - * KSE and KSEG can be cleaned when their last thread - * exits. - */ - thread->kseg = _kse_initial->k_kseg; - thread->kse = _kse_initial; - } - - /* - * We can't hold the thread list lock while holding the - * scheduler lock. - */ - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - DBG_MSG("Adding thread %p to GC list\n", thread); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - thread->tlflags |= TLFLAGS_GC_SAFE; - THR_GCLIST_ADD(thread); - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - if (sys_scope) { - /* - * System scope thread is single thread group, - * when thread is exited, its kse and ksegrp should - * be recycled as well. - * kse upcall stack belongs to thread, clear it here. - */ - curkse->k_stack.ss_sp = 0; - curkse->k_stack.ss_size = 0; - kse_exit(); - PANIC("kse_exit() failed for system scope thread"); - } - KSE_SCHED_LOCK(curkse, curkse->k_kseg); -} - -void -_thr_gc(struct pthread *curthread) -{ - thread_gc(curthread); - kse_gc(curthread); - kseg_gc(curthread); -} - -static void -thread_gc(struct pthread *curthread) -{ - struct pthread *td, *td_next; - kse_critical_t crit; - TAILQ_HEAD(, pthread) worklist; - - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - /* Check the threads waiting for GC. */ - for (td = TAILQ_FIRST(&_thread_gc_list); td != NULL; td = td_next) { - td_next = TAILQ_NEXT(td, gcle); - if ((td->tlflags & TLFLAGS_GC_SAFE) == 0) - continue; - else if (((td->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) && - ((td->kse->k_kcb->kcb_kmbx.km_flags & KMF_DONE) == 0)) { - /* - * The thread and KSE are operating on the same - * stack. Wait for the KSE to exit before freeing - * the thread's stack as well as everything else. - */ - continue; - } - /* - * Remove the thread from the GC list. If the thread - * isn't yet detached, it will get added back to the - * GC list at a later time. - */ - THR_GCLIST_REMOVE(td); - DBG_MSG("Freeing thread %p stack\n", td); - /* - * We can free the thread stack since it's no longer - * in use. - */ - _thr_stack_free(&td->attr); - if (((td->attr.flags & PTHREAD_DETACHED) != 0) && - (td->refcount == 0)) { - /* - * The thread has detached and is no longer - * referenced. It is safe to remove all - * remnants of the thread. - */ - THR_LIST_REMOVE(td); - TAILQ_INSERT_HEAD(&worklist, td, gcle); - } - } - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); - - while ((td = TAILQ_FIRST(&worklist)) != NULL) { - TAILQ_REMOVE(&worklist, td, gcle); - /* - * XXX we don't free initial thread and its kse - * (if thread is a bound thread), because there might - * have some code referencing initial thread and kse. - */ - if (td == _thr_initial) { - DBG_MSG("Initial thread won't be freed\n"); - continue; - } - - if ((td->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - kse_free_unlocked(td->kse); - kseg_free_unlocked(td->kseg); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } - DBG_MSG("Freeing thread %p\n", td); - _thr_free(curthread, td); - } -} - -static void -kse_gc(struct pthread *curthread) -{ - kse_critical_t crit; - TAILQ_HEAD(, kse) worklist; - struct kse *kse; - - if (free_kse_count <= MAX_CACHED_KSES) - return; - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - while (free_kse_count > MAX_CACHED_KSES) { - kse = TAILQ_FIRST(&free_kseq); - TAILQ_REMOVE(&free_kseq, kse, k_qe); - TAILQ_INSERT_HEAD(&worklist, kse, k_qe); - free_kse_count--; - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - - while ((kse = TAILQ_FIRST(&worklist))) { - TAILQ_REMOVE(&worklist, kse, k_qe); - kse_destroy(kse); - } -} - -static void -kseg_gc(struct pthread *curthread) -{ - kse_critical_t crit; - TAILQ_HEAD(, kse_group) worklist; - struct kse_group *kseg; - - if (free_kseg_count <= MAX_CACHED_KSEGS) - return; - TAILQ_INIT(&worklist); - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - while (free_kseg_count > MAX_CACHED_KSEGS) { - kseg = TAILQ_FIRST(&free_kse_groupq); - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - free_kseg_count--; - TAILQ_INSERT_HEAD(&worklist, kseg, kg_qe); - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - - while ((kseg = TAILQ_FIRST(&worklist))) { - TAILQ_REMOVE(&worklist, kseg, kg_qe); - kseg_destroy(kseg); - } -} - -/* - * Only new threads that are running or suspended may be scheduled. - */ -int -_thr_schedule_add(struct pthread *curthread, struct pthread *newthread) -{ - kse_critical_t crit; - int ret; - - /* Add the new thread. */ - thr_link(newthread); - - /* - * If this is the first time creating a thread, make sure - * the mailbox is set for the current thread. - */ - if ((newthread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) { - /* We use the thread's stack as the KSE's stack. */ - newthread->kse->k_kcb->kcb_kmbx.km_stack.ss_sp = - newthread->attr.stackaddr_attr; - newthread->kse->k_kcb->kcb_kmbx.km_stack.ss_size = - newthread->attr.stacksize_attr; - - /* - * No need to lock the scheduling queue since the - * KSE/KSEG pair have not yet been started. - */ - KSEG_THRQ_ADD(newthread->kseg, newthread); - /* this thread never gives up kse */ - newthread->active = 1; - newthread->kse->k_curthread = newthread; - newthread->kse->k_kcb->kcb_kmbx.km_flags = KMF_BOUND; - newthread->kse->k_kcb->kcb_kmbx.km_func = - (kse_func_t *)kse_sched_single; - newthread->kse->k_kcb->kcb_kmbx.km_quantum = 0; - KSE_SET_MBOX(newthread->kse, newthread); - /* - * This thread needs a new KSE and KSEG. - */ - newthread->kse->k_flags &= ~KF_INITIALIZED; - newthread->kse->k_flags |= KF_STARTED; - /* Fire up! */ - ret = kse_create(&newthread->kse->k_kcb->kcb_kmbx, 1); - if (ret != 0) - ret = errno; - } - else { - /* - * Lock the KSE and add the new thread to its list of - * assigned threads. If the new thread is runnable, also - * add it to the KSE's run queue. - */ - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, newthread->kseg); - KSEG_THRQ_ADD(newthread->kseg, newthread); - if (newthread->state == PS_RUNNING) - THR_RUNQ_INSERT_TAIL(newthread); - if ((newthread->kse->k_flags & KF_STARTED) == 0) { - /* - * This KSE hasn't been started yet. Start it - * outside of holding the lock. - */ - newthread->kse->k_flags |= KF_STARTED; - newthread->kse->k_kcb->kcb_kmbx.km_func = - (kse_func_t *)kse_sched_multi; - newthread->kse->k_kcb->kcb_kmbx.km_flags = 0; - kse_create(&newthread->kse->k_kcb->kcb_kmbx, 0); - } else if ((newthread->state == PS_RUNNING) && - KSE_IS_IDLE(newthread->kse)) { - /* - * The thread is being scheduled on another KSEG. - */ - kse_wakeup_one(newthread); - } - KSE_SCHED_UNLOCK(curthread->kse, newthread->kseg); - _kse_critical_leave(crit); - ret = 0; - } - if (ret != 0) - thr_unlink(newthread); - - return (ret); -} - -void -kse_waitq_insert(struct pthread *thread) -{ - struct pthread *td; - - if (thread->wakeup_time.tv_sec == -1) - TAILQ_INSERT_TAIL(&thread->kse->k_schedq->sq_waitq, thread, - pqe); - else { - td = TAILQ_FIRST(&thread->kse->k_schedq->sq_waitq); - while ((td != NULL) && (td->wakeup_time.tv_sec != -1) && - ((td->wakeup_time.tv_sec < thread->wakeup_time.tv_sec) || - ((td->wakeup_time.tv_sec == thread->wakeup_time.tv_sec) && - (td->wakeup_time.tv_nsec <= thread->wakeup_time.tv_nsec)))) - td = TAILQ_NEXT(td, pqe); - if (td == NULL) - TAILQ_INSERT_TAIL(&thread->kse->k_schedq->sq_waitq, - thread, pqe); - else - TAILQ_INSERT_BEFORE(td, thread, pqe); - } - thread->flags |= THR_FLAGS_IN_WAITQ; -} - -/* - * This must be called with the scheduling lock held. - */ -static void -kse_check_completed(struct kse *kse) -{ - struct pthread *thread; - struct kse_thr_mailbox *completed; - int sig; - - if ((completed = kse->k_kcb->kcb_kmbx.km_completed) != NULL) { - kse->k_kcb->kcb_kmbx.km_completed = NULL; - while (completed != NULL) { - thread = completed->tm_udata; - DBG_MSG("Found completed thread %p, name %s\n", - thread, - (thread->name == NULL) ? "none" : thread->name); - thread->blocked = 0; - if (thread != kse->k_curthread) { - thr_accounting(thread); - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else - KSE_RUNQ_INSERT_TAIL(kse, thread); - if ((thread->kse != kse) && - (thread->kse->k_curthread == thread)) { - /* - * Remove this thread from its - * previous KSE so that it (the KSE) - * doesn't think it is still active. - */ - thread->kse->k_curthread = NULL; - thread->active = 0; - } - } - if ((sig = thread->tcb->tcb_tmbx.tm_syncsig.si_signo) - != 0) { - if (SIGISMEMBER(thread->sigmask, sig)) - SIGADDSET(thread->sigpend, sig); - else if (THR_IN_CRITICAL(thread)) - kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); - else - (void)_thr_sig_add(thread, sig, - &thread->tcb->tcb_tmbx.tm_syncsig); - thread->tcb->tcb_tmbx.tm_syncsig.si_signo = 0; - } - completed = completed->tm_next; - } - } -} - -/* - * This must be called with the scheduling lock held. - */ -static void -kse_check_waitq(struct kse *kse) -{ - struct pthread *pthread; - struct timespec ts; - - KSE_GET_TOD(kse, &ts); - - /* - * Wake up threads that have timedout. This has to be - * done before adding the current thread to the run queue - * so that a CPU intensive thread doesn't get preference - * over waiting threads. - */ - while (((pthread = KSE_WAITQ_FIRST(kse)) != NULL) && - thr_timedout(pthread, &ts)) { - /* Remove the thread from the wait queue: */ - KSE_WAITQ_REMOVE(kse, pthread); - DBG_MSG("Found timedout thread %p in waitq\n", pthread); - - /* Indicate the thread timedout: */ - pthread->timeout = 1; - - /* Add the thread to the priority queue: */ - if ((pthread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(pthread, PS_SUSPENDED); - else { - THR_SET_STATE(pthread, PS_RUNNING); - KSE_RUNQ_INSERT_TAIL(kse, pthread); - } - } -} - -static int -thr_timedout(struct pthread *thread, struct timespec *curtime) -{ - if (thread->wakeup_time.tv_sec < 0) - return (0); - else if (thread->wakeup_time.tv_sec > curtime->tv_sec) - return (0); - else if ((thread->wakeup_time.tv_sec == curtime->tv_sec) && - (thread->wakeup_time.tv_nsec > curtime->tv_nsec)) - return (0); - else - return (1); -} - -/* - * This must be called with the scheduling lock held. - * - * Each thread has a time slice, a wakeup time (used when it wants - * to wait for a specified amount of time), a run state, and an - * active flag. - * - * When a thread gets run by the scheduler, the active flag is - * set to non-zero (1). When a thread performs an explicit yield - * or schedules a state change, it enters the scheduler and the - * active flag is cleared. When the active flag is still seen - * set in the scheduler, that means that the thread is blocked in - * the kernel (because it is cleared before entering the scheduler - * in all other instances). - * - * The wakeup time is only set for those states that can timeout. - * It is set to (-1, -1) for all other instances. - * - * The thread's run state, aside from being useful when debugging, - * is used to place the thread in an appropriate queue. There - * are 2 basic queues: - * - * o run queue - queue ordered by priority for all threads - * that are runnable - * o waiting queue - queue sorted by wakeup time for all threads - * that are not otherwise runnable (not blocked - * in kernel, not waiting for locks) - * - * The thread's time slice is used for round-robin scheduling - * (the default scheduling policy). While a SCHED_RR thread - * is runnable it's time slice accumulates. When it reaches - * the time slice interval, it gets reset and added to the end - * of the queue of threads at its priority. When a thread no - * longer becomes runnable (blocks in kernel, waits, etc), its - * time slice is reset. - * - * The job of kse_switchout_thread() is to handle all of the above. - */ -static void -kse_switchout_thread(struct kse *kse, struct pthread *thread) -{ - int level; - int i; - int restart; - siginfo_t siginfo; - - /* - * Place the currently running thread into the - * appropriate queue(s). - */ - DBG_MSG("Switching out thread %p, state %d\n", thread, thread->state); - - THR_DEACTIVATE_LAST_LOCK(thread); - if (thread->blocked != 0) { - thread->active = 0; - thread->need_switchout = 0; - /* This thread must have blocked in the kernel. */ - /* - * Check for pending signals and cancellation for - * this thread to see if we need to interrupt it - * in the kernel. - */ - if (THR_NEED_CANCEL(thread)) { - kse_thr_interrupt(&thread->tcb->tcb_tmbx, - KSE_INTR_INTERRUPT, 0); - } else if (thread->check_pending != 0) { - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(thread->sigpend, i) && - !SIGISMEMBER(thread->sigmask, i)) { - restart = _thread_sigact[i - 1].sa_flags & SA_RESTART; - kse_thr_interrupt(&thread->tcb->tcb_tmbx, - restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); - break; - } - } - } - } - else { - switch (thread->state) { - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - thread->continuation = _thr_finish_cancellation; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_LOCKWAIT: - /* - * This state doesn't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - level = thread->locklevel - 1; - if (!_LCK_GRANTED(&thread->lockusers[level])) - KSE_WAITQ_INSERT(kse, thread); - else - THR_SET_STATE(thread, PS_RUNNING); - break; - - case PS_SLEEP_WAIT: - case PS_SIGWAIT: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - THR_SET_STATE(thread, PS_RUNNING); - } else { - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_JOIN: - if (THR_NEED_CANCEL(thread)) { - thread->join_status.thread = NULL; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* - * This state doesn't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_SIGSUSPEND: - case PS_SUSPENDED: - if (THR_NEED_CANCEL(thread)) { - thread->interrupted = 1; - THR_SET_STATE(thread, PS_RUNNING); - } else { - /* - * These states don't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - } - break; - - case PS_DEAD: - /* - * The scheduler is operating on a different - * stack. It is safe to do garbage collecting - * here. - */ - thr_cleanup(kse, thread); - return; - break; - - case PS_RUNNING: - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0 && - !THR_NEED_CANCEL(thread)) - THR_SET_STATE(thread, PS_SUSPENDED); - break; - - case PS_DEADLOCK: - /* - * These states don't timeout. - */ - thread->wakeup_time.tv_sec = -1; - thread->wakeup_time.tv_nsec = -1; - - /* Insert into the waiting queue: */ - KSE_WAITQ_INSERT(kse, thread); - break; - - default: - PANIC("Unknown state\n"); - break; - } - - thr_accounting(thread); - if (thread->state == PS_RUNNING) { - if (thread->slice_usec == -1) { - /* - * The thread exceeded its time quantum or - * it yielded the CPU; place it at the tail - * of the queue for its priority. - */ - KSE_RUNQ_INSERT_TAIL(kse, thread); - } else { - /* - * The thread hasn't exceeded its interval - * Place it at the head of the queue for its - * priority. - */ - KSE_RUNQ_INSERT_HEAD(kse, thread); - } - } - } - thread->active = 0; - thread->need_switchout = 0; - if (thread->check_pending != 0) { - /* Install pending signals into the frame. */ - thread->check_pending = 0; - KSE_LOCK_ACQUIRE(kse, &_thread_signal_lock); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(thread->sigmask, i)) - continue; - if (SIGISMEMBER(thread->sigpend, i)) - (void)_thr_sig_add(thread, i, - &thread->siginfo[i-1]); - else if (SIGISMEMBER(_thr_proc_sigpending, i) && - _thr_getprocsig_unlocked(i, &siginfo)) { - (void)_thr_sig_add(thread, i, &siginfo); - } - } - KSE_LOCK_RELEASE(kse, &_thread_signal_lock); - } -} - -/* - * This function waits for the smallest timeout value of any waiting - * thread, or until it receives a message from another KSE. - * - * This must be called with the scheduling lock held. - */ -static void -kse_wait(struct kse *kse, struct pthread *td_wait, int sigseqno) -{ - struct timespec ts, ts_sleep; - int saved_flags; - - if ((td_wait == NULL) || (td_wait->wakeup_time.tv_sec < 0)) { - /* Limit sleep to no more than 1 minute. */ - ts_sleep.tv_sec = 60; - ts_sleep.tv_nsec = 0; - } else { - KSE_GET_TOD(kse, &ts); - TIMESPEC_SUB(&ts_sleep, &td_wait->wakeup_time, &ts); - if (ts_sleep.tv_sec > 60) { - ts_sleep.tv_sec = 60; - ts_sleep.tv_nsec = 0; - } - } - /* Don't sleep for negative times. */ - if ((ts_sleep.tv_sec >= 0) && (ts_sleep.tv_nsec >= 0)) { - KSE_SET_IDLE(kse); - kse->k_kseg->kg_idle_kses++; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - if ((kse->k_kseg->kg_flags & KGF_SINGLE_THREAD) && - (kse->k_sigseqno != sigseqno)) - ; /* don't sleep */ - else { - saved_flags = kse->k_kcb->kcb_kmbx.km_flags; - kse->k_kcb->kcb_kmbx.km_flags |= KMF_NOUPCALL; - kse_release(&ts_sleep); - kse->k_kcb->kcb_kmbx.km_flags = saved_flags; - } - KSE_SCHED_LOCK(kse, kse->k_kseg); - if (KSE_IS_IDLE(kse)) { - KSE_CLEAR_IDLE(kse); - kse->k_kseg->kg_idle_kses--; - } - } -} - -/* - * Avoid calling this kse_exit() so as not to confuse it with the - * system call of the same name. - */ -static void -kse_fini(struct kse *kse) -{ - /* struct kse_group *free_kseg = NULL; */ - struct timespec ts; - struct pthread *td; - - /* - * Check to see if this is one of the main kses. - */ - if (kse->k_kseg != _kse_initial->k_kseg) { - PANIC("shouldn't get here"); - /* This is for supporting thread groups. */ -#ifdef NOT_YET - /* Remove this KSE from the KSEG's list of KSEs. */ - KSE_SCHED_LOCK(kse, kse->k_kseg); - TAILQ_REMOVE(&kse->k_kseg->kg_kseq, kse, k_kgqe); - kse->k_kseg->kg_ksecount--; - if (TAILQ_EMPTY(&kse->k_kseg->kg_kseq)) - free_kseg = kse->k_kseg; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - - /* - * Add this KSE to the list of free KSEs along with - * the KSEG if is now orphaned. - */ - KSE_LOCK_ACQUIRE(kse, &kse_lock); - if (free_kseg != NULL) - kseg_free_unlocked(free_kseg); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(kse, &kse_lock); - kse_exit(); - /* Never returns. */ - PANIC("kse_exit()"); -#endif - } else { - /* - * We allow program to kill kse in initial group (by - * lowering the concurrency). - */ - if ((kse != _kse_initial) && - ((kse->k_flags & KF_TERMINATED) != 0)) { - KSE_SCHED_LOCK(kse, kse->k_kseg); - TAILQ_REMOVE(&kse->k_kseg->kg_kseq, kse, k_kgqe); - kse->k_kseg->kg_ksecount--; - /* - * Migrate thread to _kse_initial if its lastest - * kse it ran on is the kse. - */ - td = TAILQ_FIRST(&kse->k_kseg->kg_threadq); - while (td != NULL) { - if (td->kse == kse) - td->kse = _kse_initial; - td = TAILQ_NEXT(td, kle); - } - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - KSE_LOCK_ACQUIRE(kse, &kse_lock); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(kse, &kse_lock); - /* Make sure there is always at least one is awake */ - KSE_WAKEUP(_kse_initial); - kse_exit(); - /* Never returns. */ - PANIC("kse_exit() failed for initial kseg"); - } - KSE_SCHED_LOCK(kse, kse->k_kseg); - KSE_SET_IDLE(kse); - kse->k_kseg->kg_idle_kses++; - KSE_SCHED_UNLOCK(kse, kse->k_kseg); - ts.tv_sec = 120; - ts.tv_nsec = 0; - kse->k_kcb->kcb_kmbx.km_flags = 0; - kse_release(&ts); - /* Never reach */ - } -} - -void -_thr_set_timeout(const struct timespec *timeout) -{ - struct pthread *curthread = _get_curthread(); - struct timespec ts; - - /* Reset the timeout flag for the running thread: */ - curthread->timeout = 0; - - /* Check if the thread is to wait forever: */ - if (timeout == NULL) { - /* - * Set the wakeup time to something that can be recognised as - * different to an actual time of day: - */ - curthread->wakeup_time.tv_sec = -1; - curthread->wakeup_time.tv_nsec = -1; - } - /* Check if no waiting is required: */ - else if ((timeout->tv_sec == 0) && (timeout->tv_nsec == 0)) { - /* Set the wake up time to 'immediately': */ - curthread->wakeup_time.tv_sec = 0; - curthread->wakeup_time.tv_nsec = 0; - } else { - /* Calculate the time for the current thread to wakeup: */ - KSE_GET_TOD(curthread->kse, &ts); - TIMESPEC_ADD(&curthread->wakeup_time, &ts, timeout); - } -} - -void -_thr_panic_exit(char *file, int line, char *msg) -{ - char buf[256]; - - snprintf(buf, sizeof(buf), "(%s:%d) %s\n", file, line, msg); - __sys_write(2, buf, strlen(buf)); - abort(); -} - -void -_thr_setrunnable(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - struct kse_mailbox *kmbx; - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, thread->kseg); - kmbx = _thr_setrunnable_unlocked(thread); - KSE_SCHED_UNLOCK(curthread->kse, thread->kseg); - _kse_critical_leave(crit); - if ((kmbx != NULL) && (__isthreaded != 0)) - kse_wakeup(kmbx); -} - -struct kse_mailbox * -_thr_setrunnable_unlocked(struct pthread *thread) -{ - struct kse_mailbox *kmbx = NULL; - - if ((thread->kseg->kg_flags & KGF_SINGLE_THREAD) != 0) { - /* No silly queues for these threads. */ - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else { - THR_SET_STATE(thread, PS_RUNNING); - kmbx = kse_wakeup_one(thread); - } - - } else if (thread->state != PS_RUNNING) { - if ((thread->flags & THR_FLAGS_IN_WAITQ) != 0) - KSE_WAITQ_REMOVE(thread->kse, thread); - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(thread, PS_SUSPENDED); - else { - THR_SET_STATE(thread, PS_RUNNING); - if ((thread->blocked == 0) && (thread->active == 0) && - (thread->flags & THR_FLAGS_IN_RUNQ) == 0) - THR_RUNQ_INSERT_TAIL(thread); - /* - * XXX - Threads are not yet assigned to specific - * KSEs; they are assigned to the KSEG. So - * the fact that a thread's KSE is waiting - * doesn't necessarily mean that it will be - * the KSE that runs the thread after the - * lock is granted. But we don't know if the - * other KSEs within the same KSEG are also - * in a waiting state or not so we err on the - * side of caution and wakeup the thread's - * last known KSE. We ensure that the - * threads KSE doesn't change while it's - * scheduling lock is held so it is safe to - * reference it (the KSE). If the KSE wakes - * up and doesn't find any more work it will - * again go back to waiting so no harm is - * done. - */ - kmbx = kse_wakeup_one(thread); - } - } - return (kmbx); -} - -static struct kse_mailbox * -kse_wakeup_one(struct pthread *thread) -{ - struct kse *ke; - - if (KSE_IS_IDLE(thread->kse)) { - KSE_CLEAR_IDLE(thread->kse); - thread->kseg->kg_idle_kses--; - return (&thread->kse->k_kcb->kcb_kmbx); - } else { - TAILQ_FOREACH(ke, &thread->kseg->kg_kseq, k_kgqe) { - if (KSE_IS_IDLE(ke)) { - KSE_CLEAR_IDLE(ke); - ke->k_kseg->kg_idle_kses--; - return (&ke->k_kcb->kcb_kmbx); - } - } - } - return (NULL); -} - -static void -kse_wakeup_multi(struct kse *curkse) -{ - struct kse *ke; - int tmp; - - if ((tmp = KSE_RUNQ_THREADS(curkse)) && curkse->k_kseg->kg_idle_kses) { - TAILQ_FOREACH(ke, &curkse->k_kseg->kg_kseq, k_kgqe) { - if (KSE_IS_IDLE(ke)) { - KSE_CLEAR_IDLE(ke); - ke->k_kseg->kg_idle_kses--; - KSE_WAKEUP(ke); - if (--tmp == 0) - break; - } - } - } -} - -/* - * Allocate a new KSEG. - * - * We allow the current thread to be NULL in the case that this - * is the first time a KSEG is being created (library initialization). - * In this case, we don't need to (and can't) take any locks. - */ -struct kse_group * -_kseg_alloc(struct pthread *curthread) -{ - struct kse_group *kseg = NULL; - kse_critical_t crit; - - if ((curthread != NULL) && (free_kseg_count > 0)) { - /* Use the kse lock for the kseg queue. */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - if ((kseg = TAILQ_FIRST(&free_kse_groupq)) != NULL) { - TAILQ_REMOVE(&free_kse_groupq, kseg, kg_qe); - free_kseg_count--; - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, kseg, kg_qe); - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - if (kseg) - kseg_reinit(kseg); - } - - /* - * If requested, attempt to allocate a new KSE group only if the - * KSE allocation was successful and a KSE group wasn't found in - * the free list. - */ - if ((kseg == NULL) && - ((kseg = (struct kse_group *)malloc(sizeof(*kseg))) != NULL)) { - if (_pq_alloc(&kseg->kg_schedq.sq_runq, - THR_MIN_PRIORITY, THR_LAST_PRIORITY) != 0) { - free(kseg); - kseg = NULL; - } else { - kseg_init(kseg); - /* Add the KSEG to the list of active KSEGs. */ - if (curthread != NULL) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, - kseg, kg_qe); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } else { - active_kseg_count++; - TAILQ_INSERT_TAIL(&active_kse_groupq, - kseg, kg_qe); - } - } - } - return (kseg); -} - -static void -kseg_init(struct kse_group *kseg) -{ - kseg_reinit(kseg); - _lock_init(&kseg->kg_lock, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup); -} - -static void -kseg_reinit(struct kse_group *kseg) -{ - TAILQ_INIT(&kseg->kg_kseq); - TAILQ_INIT(&kseg->kg_threadq); - TAILQ_INIT(&kseg->kg_schedq.sq_waitq); - kseg->kg_threadcount = 0; - kseg->kg_ksecount = 0; - kseg->kg_idle_kses = 0; - kseg->kg_flags = 0; -} - -/* - * This must be called with the kse lock held and when there are - * no more threads that reference it. - */ -static void -kseg_free_unlocked(struct kse_group *kseg) -{ - TAILQ_REMOVE(&active_kse_groupq, kseg, kg_qe); - TAILQ_INSERT_HEAD(&free_kse_groupq, kseg, kg_qe); - free_kseg_count++; - active_kseg_count--; -} - -void -_kseg_free(struct kse_group *kseg) -{ - struct kse *curkse; - kse_critical_t crit; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &kse_lock); - kseg_free_unlocked(kseg); - KSE_LOCK_RELEASE(curkse, &kse_lock); - _kse_critical_leave(crit); -} - -static void -kseg_destroy(struct kse_group *kseg) -{ - _lock_destroy(&kseg->kg_lock); - _pq_free(&kseg->kg_schedq.sq_runq); - free(kseg); -} - -/* - * Allocate a new KSE. - * - * We allow the current thread to be NULL in the case that this - * is the first time a KSE is being created (library initialization). - * In this case, we don't need to (and can't) take any locks. - */ -struct kse * -_kse_alloc(struct pthread *curthread, int sys_scope) -{ - struct kse *kse = NULL; - char *stack; - kse_critical_t crit; - int i; - - if ((curthread != NULL) && (free_kse_count > 0)) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - /* Search for a finished KSE. */ - kse = TAILQ_FIRST(&free_kseq); - while ((kse != NULL) && - ((kse->k_kcb->kcb_kmbx.km_flags & KMF_DONE) == 0)) { - kse = TAILQ_NEXT(kse, k_qe); - } - if (kse != NULL) { - DBG_MSG("found an unused kse.\n"); - TAILQ_REMOVE(&free_kseq, kse, k_qe); - free_kse_count--; - TAILQ_INSERT_TAIL(&active_kseq, kse, k_qe); - active_kse_count++; - } - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - if (kse != NULL) - kse_reinit(kse, sys_scope); - } - if ((kse == NULL) && - ((kse = (struct kse *)malloc(sizeof(*kse))) != NULL)) { - if (sys_scope != 0) - stack = NULL; - else if ((stack = malloc(KSE_STACKSIZE)) == NULL) { - free(kse); - return (NULL); - } - bzero(kse, sizeof(*kse)); - - /* Initialize KCB without the lock. */ - if ((kse->k_kcb = _kcb_ctor(kse)) == NULL) { - if (stack != NULL) - free(stack); - free(kse); - return (NULL); - } - - /* Initialize the lockusers. */ - for (i = 0; i < MAX_KSE_LOCKLEVEL; i++) { - _lockuser_init(&kse->k_lockusers[i], (void *)kse); - _LCK_SET_PRIVATE2(&kse->k_lockusers[i], NULL); - } - /* _lock_init(kse->k_lock, ...) */ - - if (curthread != NULL) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - } - kse->k_flags = 0; - TAILQ_INSERT_TAIL(&active_kseq, kse, k_qe); - active_kse_count++; - if (curthread != NULL) { - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } - /* - * Create the KSE context. - * Scope system threads (one thread per KSE) are not required - * to have a stack for an unneeded kse upcall. - */ - if (!sys_scope) { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_multi; - kse->k_stack.ss_sp = stack; - kse->k_stack.ss_size = KSE_STACKSIZE; - } else { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_single; - kse->k_stack.ss_sp = NULL; - kse->k_stack.ss_size = 0; - } - kse->k_kcb->kcb_kmbx.km_udata = (void *)kse; - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - /* - * We need to keep a copy of the stack in case it - * doesn't get used; a KSE running a scope system - * thread will use that thread's stack. - */ - kse->k_kcb->kcb_kmbx.km_stack = kse->k_stack; - } - return (kse); -} - -static void -kse_reinit(struct kse *kse, int sys_scope) -{ - if (!sys_scope) { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_multi; - if (kse->k_stack.ss_sp == NULL) { - /* XXX check allocation failure */ - kse->k_stack.ss_sp = (char *) malloc(KSE_STACKSIZE); - kse->k_stack.ss_size = KSE_STACKSIZE; - } - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - } else { - kse->k_kcb->kcb_kmbx.km_func = (kse_func_t *)kse_sched_single; - if (kse->k_stack.ss_sp) - free(kse->k_stack.ss_sp); - kse->k_stack.ss_sp = NULL; - kse->k_stack.ss_size = 0; - kse->k_kcb->kcb_kmbx.km_quantum = 0; - } - kse->k_kcb->kcb_kmbx.km_stack = kse->k_stack; - kse->k_kcb->kcb_kmbx.km_udata = (void *)kse; - kse->k_kcb->kcb_kmbx.km_curthread = NULL; - kse->k_kcb->kcb_kmbx.km_flags = 0; - kse->k_curthread = NULL; - kse->k_kseg = 0; - kse->k_schedq = 0; - kse->k_locklevel = 0; - kse->k_flags = 0; - kse->k_error = 0; - kse->k_cpu = 0; - kse->k_sigseqno = 0; -} - -void -kse_free_unlocked(struct kse *kse) -{ - TAILQ_REMOVE(&active_kseq, kse, k_qe); - active_kse_count--; - kse->k_kseg = NULL; - kse->k_kcb->kcb_kmbx.km_quantum = 20000; - kse->k_flags = 0; - TAILQ_INSERT_HEAD(&free_kseq, kse, k_qe); - free_kse_count++; -} - -void -_kse_free(struct pthread *curthread, struct kse *kse) -{ - kse_critical_t crit; - - if (curthread == NULL) - kse_free_unlocked(kse); - else { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); - kse_free_unlocked(kse); - KSE_LOCK_RELEASE(curthread->kse, &kse_lock); - _kse_critical_leave(crit); - } -} - -static void -kse_destroy(struct kse *kse) -{ - int i; - - if (kse->k_stack.ss_sp != NULL) - free(kse->k_stack.ss_sp); - _kcb_dtor(kse->k_kcb); - for (i = 0; i < MAX_KSE_LOCKLEVEL; ++i) - _lockuser_destroy(&kse->k_lockusers[i]); - _lock_destroy(&kse->k_lock); - free(kse); -} - -struct pthread * -_thr_alloc(struct pthread *curthread) -{ - kse_critical_t crit; - struct pthread *thread = NULL; - int i; - - if (curthread != NULL) { - if (GC_NEEDED()) - _thr_gc(curthread); - if (free_thread_count > 0) { - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &thread_lock); - if ((thread = TAILQ_FIRST(&free_threadq)) != NULL) { - TAILQ_REMOVE(&free_threadq, thread, tle); - free_thread_count--; - } - KSE_LOCK_RELEASE(curthread->kse, &thread_lock); - _kse_critical_leave(crit); - } - } - if ((thread == NULL) && - ((thread = malloc(sizeof(struct pthread))) != NULL)) { - bzero(thread, sizeof(struct pthread)); - thread->siginfo = calloc(_SIG_MAXSIG, sizeof(siginfo_t)); - if (thread->siginfo == NULL) { - free(thread); - return (NULL); - } - if (curthread) { - _pthread_mutex_lock(&_tcb_mutex); - thread->tcb = _tcb_ctor(thread, 0 /* not initial tls */); - _pthread_mutex_unlock(&_tcb_mutex); - } else { - thread->tcb = _tcb_ctor(thread, 1 /* initial tls */); - } - if (thread->tcb == NULL) { - free(thread->siginfo); - free(thread); - return (NULL); - } - /* - * Initialize thread locking. - * Lock initializing needs malloc, so don't - * enter critical region before doing this! - */ - if (_lock_init(&thread->lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup) != 0) - PANIC("Cannot initialize thread lock"); - for (i = 0; i < MAX_THR_LOCKLEVEL; i++) { - _lockuser_init(&thread->lockusers[i], (void *)thread); - _LCK_SET_PRIVATE2(&thread->lockusers[i], - (void *)thread); - } - } - return (thread); -} - -void -_thr_free(struct pthread *curthread, struct pthread *thread) -{ - kse_critical_t crit; - - DBG_MSG("Freeing thread %p\n", thread); - if (thread->name) { - free(thread->name); - thread->name = NULL; - } - if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) { - thr_destroy(curthread, thread); - } else { - /* Add the thread to the free thread list. */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &thread_lock); - TAILQ_INSERT_TAIL(&free_threadq, thread, tle); - free_thread_count++; - KSE_LOCK_RELEASE(curthread->kse, &thread_lock); - _kse_critical_leave(crit); - } -} - -static void -thr_destroy(struct pthread *curthread, struct pthread *thread) -{ - int i; - - for (i = 0; i < MAX_THR_LOCKLEVEL; i++) - _lockuser_destroy(&thread->lockusers[i]); - _lock_destroy(&thread->lock); - if (curthread) { - _pthread_mutex_lock(&_tcb_mutex); - _tcb_dtor(thread->tcb); - _pthread_mutex_unlock(&_tcb_mutex); - } else { - _tcb_dtor(thread->tcb); - } - free(thread->siginfo); - free(thread); -} - -/* - * Add an active thread: - * - * o Assign the thread a unique id (which GDB uses to track - * threads. - * o Add the thread to the list of all threads and increment - * number of active threads. - */ -static void -thr_link(struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* - * Initialize the unique id (which GDB uses to track - * threads), add the thread to the list of all threads, - * and - */ - thread->uniqueid = next_uniqueid++; - THR_LIST_ADD(thread); - _thread_active_threads++; - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -/* - * Remove an active thread. - */ -static void -thr_unlink(struct pthread *thread) -{ - kse_critical_t crit; - struct kse *curkse; - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - THR_LIST_REMOVE(thread); - _thread_active_threads--; - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -void -_thr_hash_add(struct pthread *thread) -{ - struct thread_hash_head *head; - - head = &thr_hashtable[THREAD_HASH(thread)]; - LIST_INSERT_HEAD(head, thread, hle); -} - -void -_thr_hash_remove(struct pthread *thread) -{ - LIST_REMOVE(thread, hle); -} - -struct pthread * -_thr_hash_find(struct pthread *thread) -{ - struct pthread *td; - struct thread_hash_head *head; - - head = &thr_hashtable[THREAD_HASH(thread)]; - LIST_FOREACH(td, head, hle) { - if (td == thread) - return (thread); - } - return (NULL); -} - -void -_thr_debug_check_yield(struct pthread *curthread) -{ - /* - * Note that TMDF_SUSPEND is set after process is suspended. - * When we are being debugged, every suspension in process - * will cause all KSEs to schedule an upcall in kernel, unless the - * KSE is in critical region. - * If the function is being called, it means the KSE is no longer - * in critical region, if the TMDF_SUSPEND is set by debugger - * before KSE leaves critical region, we will catch it here, else - * if the flag is changed during testing, it also not a problem, - * because the change only occurs after a process suspension event - * occurs. A suspension event will always cause KSE to schedule an - * upcall, in the case, because we are not in critical region, - * upcall will be scheduled sucessfully, the flag will be checked - * again in kse_sched_multi, we won't back until the flag - * is cleared by debugger, the flag will be cleared in next - * suspension event. - */ - if (!DBG_CAN_RUN(curthread)) { - if ((curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) - _thr_sched_switch(curthread); - else - kse_thr_interrupt(&curthread->tcb->tcb_tmbx, - KSE_INTR_DBSUSPEND, 0); - } -} diff --git a/lib/libpthread/thread/thr_kill.c b/lib/libpthread/thread/thr_kill.c deleted file mode 100644 index 2aee0ac..0000000 --- a/lib/libpthread/thread/thr_kill.c +++ /dev/null @@ -1,66 +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 <errno.h> -#include <signal.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_kill); -LT10_COMPAT_DEFAULT(pthread_kill); - -__weak_reference(_pthread_kill, pthread_kill); - -int -_pthread_kill(pthread_t pthread, int sig) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* Check for invalid signal numbers: */ - if (sig < 0 || sig > _SIG_MAXSIG) - /* Invalid signal: */ - ret = EINVAL; - /* - * Ensure the thread is in the list of active threads, and the - * signal is valid (signal 0 specifies error checking only) and - * not being ignored: - */ - else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - if ((sig > 0) && - (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) - _thr_sig_send(pthread, sig); - _thr_ref_delete(curthread, pthread); - } - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libpthread/thread/thr_main_np.c b/lib/libpthread/thread/thr_main_np.c deleted file mode 100644 index 50fb9c8..0000000 --- a/lib/libpthread/thread/thr_main_np.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2001 Alfred Perlstein - * Author: Alfred Perlstein <alfred@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <pthread.h> -#include <pthread_np.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_main_np); -LT10_COMPAT_DEFAULT(pthread_main_np); - -__weak_reference(_pthread_main_np, pthread_main_np); - -/* - * Provide the equivelant to Solaris thr_main() function - */ -int -_pthread_main_np() -{ - - if (!_thr_initial) - return (-1); - else - return (pthread_equal(pthread_self(), _thr_initial) ? 1 : 0); -} diff --git a/lib/libpthread/thread/thr_mattr_init.c b/lib/libpthread/thread/thr_mattr_init.c deleted file mode 100644 index b273bab..0000000 --- a/lib/libpthread/thread/thr_mattr_init.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1996 Jeffrey Hsu <hsu@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. - * 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$ - */ -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_mutexattr_init); -LT10_COMPAT_DEFAULT(pthread_mutexattr_init); - -__weak_reference(_pthread_mutexattr_init, pthread_mutexattr_init); - -int -_pthread_mutexattr_init(pthread_mutexattr_t *attr) -{ - int ret; - pthread_mutexattr_t pattr; - - if ((pattr = (pthread_mutexattr_t) - malloc(sizeof(struct pthread_mutex_attr))) == NULL) { - ret = ENOMEM; - } else { - memcpy(pattr, &_pthread_mutexattr_default, - sizeof(struct pthread_mutex_attr)); - *attr = pattr; - ret = 0; - } - return (ret); -} diff --git a/lib/libpthread/thread/thr_mattr_kind_np.c b/lib/libpthread/thread/thr_mattr_kind_np.c deleted file mode 100644 index f90f31a..0000000 --- a/lib/libpthread/thread/thr_mattr_kind_np.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 1996 Jeffrey Hsu <hsu@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. - * 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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_mutexattr_setkind_np); -LT10_COMPAT_DEFAULT(pthread_mutexattr_setkind_np); -LT10_COMPAT_PRIVATE(_pthread_mutexattr_getkind_np); -LT10_COMPAT_DEFAULT(pthread_mutexattr_getkind_np); -LT10_COMPAT_PRIVATE(_pthread_mutexattr_gettype); -LT10_COMPAT_DEFAULT(pthread_mutexattr_gettype); -LT10_COMPAT_PRIVATE(_pthread_mutexattr_settype); -LT10_COMPAT_DEFAULT(pthread_mutexattr_settype); - -__weak_reference(_pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np); -__weak_reference(_pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np); -__weak_reference(_pthread_mutexattr_gettype, pthread_mutexattr_gettype); -__weak_reference(_pthread_mutexattr_settype, pthread_mutexattr_settype); - -int -_pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind) -{ - int ret; - if (attr == NULL || *attr == NULL) { - errno = EINVAL; - ret = -1; - } else { - (*attr)->m_type = kind; - ret = 0; - } - return(ret); -} - -int -_pthread_mutexattr_getkind_np(pthread_mutexattr_t attr) -{ - int ret; - if (attr == NULL) { - errno = EINVAL; - ret = -1; - } else { - ret = attr->m_type; - } - return(ret); -} - -int -_pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) -{ - int ret; - if (attr == NULL || *attr == NULL || type >= PTHREAD_MUTEX_TYPE_MAX) { - errno = EINVAL; - ret = -1; - } else { - (*attr)->m_type = type; - ret = 0; - } - return(ret); -} - -int -_pthread_mutexattr_gettype(pthread_mutexattr_t *attr, int *type) -{ - int ret; - - if (attr == NULL || *attr == NULL || (*attr)->m_type >= - PTHREAD_MUTEX_TYPE_MAX) { - ret = EINVAL; - } else { - *type = (*attr)->m_type; - ret = 0; - } - return ret; -} diff --git a/lib/libpthread/thread/thr_mattr_pshared.c b/lib/libpthread/thread/thr_mattr_pshared.c deleted file mode 100644 index 03aff41..0000000 --- a/lib/libpthread/thread/thr_mattr_pshared.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2005 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 unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must 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 <errno.h> -#include "thr_private.h" - -__weak_reference(_pthread_mutexattr_getpshared, pthread_mutexattr_getpshared); -__weak_reference(_pthread_mutexattr_setpshared, pthread_mutexattr_setpshared); - -int -_pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, - int *pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - pshared = PTHREAD_PROCESS_PRIVATE; - return (0); -} - -int -_pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) -{ - if (attr == NULL || *attr == NULL) - return (EINVAL); - - if (pshared != PTHREAD_PROCESS_PRIVATE) - return (EINVAL); - return (0); -} diff --git a/lib/libpthread/thread/thr_msync.c b/lib/libpthread/thread/thr_msync.c deleted file mode 100644 index 66e88c5..0000000 --- a/lib/libpthread/thread/thr_msync.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * David Leonard <d@openbsd.org>, 1999. Public Domain. - * - * $OpenBSD: uthread_msync.c,v 1.2 1999/06/09 07:16:17 d Exp $ - * - * $FreeBSD$ - */ - -#include <sys/types.h> -#include <sys/mman.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__msync); -LT10_COMPAT_DEFAULT(msync); - -__weak_reference(__msync, msync); - -int -__msync(void *addr, size_t len, int flags) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* - * XXX This is quite pointless unless we know how to get the - * file descriptor associated with the memory, and lock it for - * write. The only real use of this wrapper is to guarantee - * a cancellation point, as per the standard. sigh. - */ - _thr_cancel_enter(curthread); - ret = __sys_msync(addr, len, flags); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_multi_np.c b/lib/libpthread/thread/thr_multi_np.c deleted file mode 100644 index f2bdd24..0000000 --- a/lib/libpthread/thread/thr_multi_np.c +++ /dev/null @@ -1,52 +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 <pthread.h> -#include <pthread_np.h> - -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_multi_np); -LT10_COMPAT_DEFAULT(pthread_multi_np); - -__weak_reference(_pthread_multi_np, pthread_multi_np); - -int -_pthread_multi_np() -{ - - /* Return to multi-threaded scheduling mode: */ - /* - * XXX - Do we want to do this? - * __is_threaded = 1; - */ - pthread_resume_all_np(); - return (0); -} diff --git a/lib/libpthread/thread/thr_mutex.c b/lib/libpthread/thread/thr_mutex.c deleted file mode 100644 index 564bc20..0000000 --- a/lib/libpthread/thread/thr_mutex.c +++ /dev/null @@ -1,1829 +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 <stdlib.h> -#include <errno.h> -#include <string.h> -#include <sys/param.h> -#include <sys/queue.h> -#include <pthread.h> -#include "thr_private.h" - -#if defined(_PTHREADS_INVARIANTS) -#define MUTEX_INIT_LINK(m) do { \ - (m)->m_qe.tqe_prev = NULL; \ - (m)->m_qe.tqe_next = NULL; \ -} while (0) -#define MUTEX_ASSERT_IS_OWNED(m) do { \ - if ((m)->m_qe.tqe_prev == NULL) \ - PANIC("mutex is not on list"); \ -} while (0) -#define MUTEX_ASSERT_NOT_OWNED(m) do { \ - if (((m)->m_qe.tqe_prev != NULL) || \ - ((m)->m_qe.tqe_next != NULL)) \ - PANIC("mutex is on list"); \ -} while (0) -#define THR_ASSERT_NOT_IN_SYNCQ(thr) do { \ - THR_ASSERT(((thr)->sflags & THR_FLAGS_IN_SYNCQ) == 0, \ - "thread in syncq when it shouldn't be."); \ -} while (0); -#else -#define MUTEX_INIT_LINK(m) -#define MUTEX_ASSERT_IS_OWNED(m) -#define MUTEX_ASSERT_NOT_OWNED(m) -#define THR_ASSERT_NOT_IN_SYNCQ(thr) -#endif - -#define THR_IN_MUTEXQ(thr) (((thr)->sflags & THR_FLAGS_IN_SYNCQ) != 0) -#define MUTEX_DESTROY(m) do { \ - _lock_destroy(&(m)->m_lock); \ - free(m); \ -} while (0) - - -/* - * Prototypes - */ -static struct kse_mailbox *mutex_handoff(struct pthread *, - struct pthread_mutex *); -static inline int mutex_self_trylock(struct pthread *, pthread_mutex_t); -static inline int mutex_self_lock(struct pthread *, pthread_mutex_t); -static int mutex_unlock_common(pthread_mutex_t *, int); -static void mutex_priority_adjust(struct pthread *, pthread_mutex_t); -static void mutex_rescan_owned (struct pthread *, struct pthread *, - struct pthread_mutex *); -static inline pthread_t mutex_queue_deq(pthread_mutex_t); -static inline void mutex_queue_remove(pthread_mutex_t, pthread_t); -static inline void mutex_queue_enq(pthread_mutex_t, pthread_t); -static void mutex_lock_backout(void *arg); - -static struct pthread_mutex_attr static_mutex_attr = - PTHREAD_MUTEXATTR_STATIC_INITIALIZER; -static pthread_mutexattr_t static_mattr = &static_mutex_attr; - -LT10_COMPAT_PRIVATE(__pthread_mutex_init); -LT10_COMPAT_PRIVATE(_pthread_mutex_init); -LT10_COMPAT_DEFAULT(pthread_mutex_init); -LT10_COMPAT_PRIVATE(__pthread_mutex_lock); -LT10_COMPAT_PRIVATE(_pthread_mutex_lock); -LT10_COMPAT_DEFAULT(pthread_mutex_lock); -LT10_COMPAT_PRIVATE(__pthread_mutex_timedlock); -LT10_COMPAT_PRIVATE(_pthread_mutex_timedlock); -LT10_COMPAT_DEFAULT(pthread_mutex_timedlock); -LT10_COMPAT_PRIVATE(__pthread_mutex_trylock); -LT10_COMPAT_PRIVATE(_pthread_mutex_trylock); -LT10_COMPAT_DEFAULT(pthread_mutex_trylock); -LT10_COMPAT_PRIVATE(_pthread_mutex_destroy); -LT10_COMPAT_DEFAULT(pthread_mutex_destroy); -LT10_COMPAT_PRIVATE(_pthread_mutex_unlock); -LT10_COMPAT_DEFAULT(pthread_mutex_unlock); - -/* Single underscore versions provided for libc internal usage: */ -__weak_reference(__pthread_mutex_init, pthread_mutex_init); -__weak_reference(__pthread_mutex_lock, pthread_mutex_lock); -__weak_reference(__pthread_mutex_timedlock, pthread_mutex_timedlock); -__weak_reference(__pthread_mutex_trylock, pthread_mutex_trylock); - -/* No difference between libc and application usage of these: */ -__weak_reference(_pthread_mutex_destroy, pthread_mutex_destroy); -__weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock); - - - -int -__pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr) -{ - struct pthread_mutex *pmutex; - enum pthread_mutextype type; - int protocol; - int ceiling; - int flags; - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* Check if default mutex attributes: */ - else if (mutex_attr == NULL || *mutex_attr == NULL) { - /* Default to a (error checking) POSIX mutex: */ - type = PTHREAD_MUTEX_ERRORCHECK; - protocol = PTHREAD_PRIO_NONE; - ceiling = THR_MAX_PRIORITY; - flags = 0; - } - - /* Check mutex type: */ - else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) || - ((*mutex_attr)->m_type >= PTHREAD_MUTEX_TYPE_MAX)) - /* Return an invalid argument error: */ - ret = EINVAL; - - /* Check mutex protocol: */ - else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) || - ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE)) - /* Return an invalid argument error: */ - ret = EINVAL; - - else { - /* Use the requested mutex type and protocol: */ - type = (*mutex_attr)->m_type; - protocol = (*mutex_attr)->m_protocol; - ceiling = (*mutex_attr)->m_ceiling; - flags = (*mutex_attr)->m_flags; - } - - /* Check no errors so far: */ - if (ret == 0) { - if ((pmutex = (pthread_mutex_t) - malloc(sizeof(struct pthread_mutex))) == NULL) - ret = ENOMEM; - else if (_lock_init(&pmutex->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup) != 0) { - free(pmutex); - *mutex = NULL; - ret = ENOMEM; - } else { - /* Set the mutex flags: */ - pmutex->m_flags = flags; - - /* Process according to mutex type: */ - switch (type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_NORMAL: - /* Nothing to do here. */ - break; - - /* Single UNIX Spec 2 recursive mutex: */ - case PTHREAD_MUTEX_RECURSIVE: - /* Reset the mutex count: */ - pmutex->m_count = 0; - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - if (ret == 0) { - /* Initialise the rest of the mutex: */ - TAILQ_INIT(&pmutex->m_queue); - pmutex->m_flags |= MUTEX_FLAGS_INITED; - pmutex->m_owner = NULL; - pmutex->m_type = type; - pmutex->m_protocol = protocol; - pmutex->m_refcount = 0; - if (protocol == PTHREAD_PRIO_PROTECT) - pmutex->m_prio = ceiling; - else - pmutex->m_prio = -1; - pmutex->m_saved_prio = 0; - MUTEX_INIT_LINK(pmutex); - *mutex = pmutex; - } else { - /* Free the mutex lock structure: */ - MUTEX_DESTROY(pmutex); - *mutex = NULL; - } - } - } - /* Return the completion status: */ - return (ret); -} - -int -_pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *mutex_attr) -{ - struct pthread_mutex_attr mattr, *mattrp; - - if ((mutex_attr == NULL) || (*mutex_attr == NULL)) - return (__pthread_mutex_init(mutex, &static_mattr)); - else { - mattr = **mutex_attr; - mattr.m_flags |= MUTEX_FLAGS_PRIVATE; - mattrp = &mattr; - return (__pthread_mutex_init(mutex, &mattrp)); - } -} - -void -_thr_mutex_reinit(pthread_mutex_t *mutex) -{ - _lock_reinit(&(*mutex)->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup); - TAILQ_INIT(&(*mutex)->m_queue); - (*mutex)->m_owner = NULL; - (*mutex)->m_count = 0; - (*mutex)->m_refcount = 0; - (*mutex)->m_prio = 0; - (*mutex)->m_saved_prio = 0; -} - -int -_pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - pthread_mutex_t m; - int ret = 0; - - if (mutex == NULL || *mutex == NULL) - ret = EINVAL; - else { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock); - - /* - * Check to see if this mutex is in use: - */ - if (((*mutex)->m_owner != NULL) || - (!TAILQ_EMPTY(&(*mutex)->m_queue)) || - ((*mutex)->m_refcount != 0)) { - ret = EBUSY; - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock); - } else { - /* - * Save a pointer to the mutex so it can be free'd - * and set the caller's pointer to NULL: - */ - m = *mutex; - *mutex = NULL; - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* - * Free the memory allocated for the mutex - * structure: - */ - MUTEX_ASSERT_NOT_OWNED(m); - MUTEX_DESTROY(m); - } - } - - /* Return the completion status: */ - return (ret); -} - -static int -init_static(struct pthread *thread, pthread_mutex_t *mutex) -{ - int ret; - - THR_LOCK_ACQUIRE(thread, &_mutex_static_lock); - - if (*mutex == NULL) - ret = pthread_mutex_init(mutex, NULL); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_mutex_static_lock); - - return (ret); -} - -static int -init_static_private(struct pthread *thread, pthread_mutex_t *mutex) -{ - int ret; - - THR_LOCK_ACQUIRE(thread, &_mutex_static_lock); - - if (*mutex == NULL) - ret = pthread_mutex_init(mutex, &static_mattr); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_mutex_static_lock); - - return (ret); -} - -static int -mutex_trylock_common(struct pthread *curthread, pthread_mutex_t *mutex) -{ - int private; - int ret = 0; - - THR_ASSERT((mutex != NULL) && (*mutex != NULL), - "Uninitialized mutex in pthread_mutex_trylock_basic"); - - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock); - private = (*mutex)->m_flags & MUTEX_FLAGS_PRIVATE; - - /* - * If the mutex was statically allocated, properly - * initialize the tail queue. - */ - if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*mutex)->m_queue); - MUTEX_INIT_LINK(*mutex); - (*mutex)->m_flags |= MUTEX_FLAGS_INITED; - } - - /* Process according to mutex type: */ - switch ((*mutex)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - /* Check if this mutex is not locked: */ - if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(curthread, *mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* Check if this mutex is not locked: */ - if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The mutex takes on the attributes of the - * running thread when there are no waiters. - */ - (*mutex)->m_prio = curthread->active_priority; - (*mutex)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(curthread, *mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* POSIX priority protection mutex: */ - case PTHREAD_PRIO_PROTECT: - /* Check for a priority ceiling violation: */ - if (curthread->active_priority > (*mutex)->m_prio) - ret = EINVAL; - - /* Check if this mutex is not locked: */ - else if ((*mutex)->m_owner == NULL) { - /* Lock the mutex for the running thread: */ - (*mutex)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The running thread inherits the ceiling - * priority of the mutex and executes at that - * priority. - */ - curthread->active_priority = (*mutex)->m_prio; - (*mutex)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = - (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*mutex); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*mutex), m_qe); - } else if ((*mutex)->m_owner == curthread) - ret = mutex_self_trylock(curthread, *mutex); - else - /* Return a busy error: */ - ret = EBUSY; - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - if (ret == 0 && private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock); - - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*mutex != NULL) || - ((ret = init_static(curthread, mutex)) == 0)) - ret = mutex_trylock_common(curthread, mutex); - - return (ret); -} - -int -_pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if (mutex == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking the mutex private (delete safe): - */ - else if ((*mutex != NULL) || - ((ret = init_static_private(curthread, mutex)) == 0)) - ret = mutex_trylock_common(curthread, mutex); - - return (ret); -} - -static int -mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, - const struct timespec * abstime) -{ - int private; - int ret = 0; - - THR_ASSERT((m != NULL) && (*m != NULL), - "Uninitialized mutex in pthread_mutex_trylock_basic"); - - if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || - abstime->tv_nsec >= 1000000000)) - return (EINVAL); - - /* Reset the interrupted flag: */ - curthread->interrupted = 0; - curthread->timeout = 0; - curthread->wakeup_time.tv_sec = -1; - - private = (*m)->m_flags & MUTEX_FLAGS_PRIVATE; - - /* - * Enter a loop waiting to become the mutex owner. We need a - * loop 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. - */ - do { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - - /* - * If the mutex was statically allocated, properly - * initialize the tail queue. - */ - if (((*m)->m_flags & MUTEX_FLAGS_INITED) == 0) { - TAILQ_INIT(&(*m)->m_queue); - (*m)->m_flags |= MUTEX_FLAGS_INITED; - MUTEX_INIT_LINK(*m); - } - - /* Process according to mutex type: */ - switch ((*m)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - if ((*m)->m_owner == NULL) { - /* Lock the mutex for this thread: */ - (*m)->m_owner = curthread; - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - } - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* Check if this mutex is not locked: */ - if ((*m)->m_owner == NULL) { - /* Lock the mutex for this thread: */ - (*m)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The mutex takes on attributes of the - * running thread when there are no waiters. - * Make sure the thread's scheduling lock is - * held while priorities are adjusted. - */ - (*m)->m_prio = curthread->active_priority; - (*m)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - if (curthread->active_priority > (*m)->m_prio) - /* Adjust priorities: */ - mutex_priority_adjust(curthread, *m); - - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - } - break; - - /* POSIX priority protection mutex: */ - case PTHREAD_PRIO_PROTECT: - /* Check for a priority ceiling violation: */ - if (curthread->active_priority > (*m)->m_prio) { - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - ret = EINVAL; - } - /* Check if this mutex is not locked: */ - else if ((*m)->m_owner == NULL) { - /* - * Lock the mutex for the running - * thread: - */ - (*m)->m_owner = curthread; - - THR_SCHED_LOCK(curthread, curthread); - /* Track number of priority mutexes owned: */ - curthread->priority_mutex_count++; - - /* - * The running thread inherits the ceiling - * priority of the mutex and executes at that - * priority. Make sure the thread's - * scheduling lock is held while priorities - * are adjusted. - */ - curthread->active_priority = (*m)->m_prio; - (*m)->m_saved_prio = - curthread->inherited_priority; - curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(*m); - TAILQ_INSERT_TAIL(&curthread->mutexq, - (*m), m_qe); - if (private) - THR_CRITICAL_ENTER(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else if ((*m)->m_owner == curthread) { - ret = mutex_self_lock(curthread, *m); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } else { - /* - * Join the queue of threads waiting to lock - * the mutex and save a pointer to the mutex. - */ - mutex_queue_enq(*m, curthread); - curthread->data.mutex = *m; - curthread->sigbackout = mutex_lock_backout; - - /* Clear any previous error: */ - curthread->error = 0; - - /* - * This thread is active and is in a critical - * region (holding the mutex lock); we should - * be able to safely set the state. - */ - - THR_SCHED_LOCK(curthread, curthread); - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - - if (THR_IN_MUTEXQ(curthread)) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - /* - * Only clear these after assuring the - * thread is dequeued. - */ - curthread->data.mutex = NULL; - curthread->sigbackout = NULL; - - /* - * The threads priority may have changed while - * waiting for the mutex causing a ceiling - * violation. - */ - ret = curthread->error; - curthread->error = 0; - } - break; - - /* Trap invalid mutex types: */ - default: - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - } while (((*m)->m_owner != curthread) && (ret == 0) && - (curthread->interrupted == 0) && (curthread->timeout == 0)); - - if (ret == 0 && (*m)->m_owner != curthread && curthread->timeout) - ret = ETIMEDOUT; - - /* - * Check to see if this thread was interrupted and - * is still in the mutex queue of waiting threads: - */ - if (curthread->interrupted != 0) { - /* Remove this thread from the mutex queue. */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - if (THR_IN_SYNCQ(curthread)) - mutex_queue_remove(*m, curthread); - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - /* Check for asynchronous cancellation. */ - if (curthread->continuation != NULL) - curthread->continuation((void *) curthread); - } - - /* Return the completion status: */ - return (ret); -} - -int -__pthread_mutex_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - curthread = _get_curthread(); - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, NULL); - - return (ret); -} - -__strong_reference(__pthread_mutex_lock, _thr_mutex_lock); - -int -_pthread_mutex_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking it private (delete safe): - */ - else if ((*m != NULL) || - ((ret = init_static_private(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, NULL); - - return (ret); -} - -int -__pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - - curthread = _get_curthread(); - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization: - */ - else if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, abs_timeout); - - return (ret); -} - -int -_pthread_mutex_timedlock(pthread_mutex_t *m, - const struct timespec *abs_timeout) -{ - struct pthread *curthread; - int ret = 0; - - if (_thr_initial == NULL) - _libpthread_init(NULL); - curthread = _get_curthread(); - - if (m == NULL) - ret = EINVAL; - - /* - * If the mutex is statically initialized, perform the dynamic - * initialization marking it private (delete safe): - */ - else if ((*m != NULL) || - ((ret = init_static_private(curthread, m)) == 0)) - ret = mutex_lock_common(curthread, m, abs_timeout); - - return (ret); -} - -int -_pthread_mutex_unlock(pthread_mutex_t *m) -{ - return (mutex_unlock_common(m, /* add reference */ 0)); -} - -__strong_reference(_pthread_mutex_unlock, _thr_mutex_unlock); - -int -_mutex_cv_unlock(pthread_mutex_t *m) -{ - return (mutex_unlock_common(m, /* add reference */ 1)); -} - -int -_mutex_cv_lock(pthread_mutex_t *m) -{ - struct pthread *curthread; - int ret; - - curthread = _get_curthread(); - if ((ret = _pthread_mutex_lock(m)) == 0) { - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - (*m)->m_refcount--; - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - } - return (ret); -} - -static inline int -mutex_self_trylock(struct pthread *curthread, pthread_mutex_t m) -{ - int ret = 0; - - switch (m->m_type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - case PTHREAD_MUTEX_NORMAL: - ret = EBUSY; - break; - - case PTHREAD_MUTEX_RECURSIVE: - /* Increment the lock count: */ - m->m_count++; - break; - - default: - /* Trap invalid mutex types; */ - ret = EINVAL; - } - - return (ret); -} - -static inline int -mutex_self_lock(struct pthread *curthread, pthread_mutex_t m) -{ - int ret = 0; - - /* - * Don't allow evil recursive mutexes for private use - * in libc and libpthread. - */ - if (m->m_flags & MUTEX_FLAGS_PRIVATE) - PANIC("Recurse on a private mutex."); - - switch (m->m_type) { - /* case PTHREAD_MUTEX_DEFAULT: */ - case PTHREAD_MUTEX_ERRORCHECK: - /* - * POSIX specifies that mutexes should return EDEADLK if a - * recursive lock is detected. - */ - ret = EDEADLK; - break; - - case PTHREAD_MUTEX_NORMAL: - /* - * What SS2 define as a 'normal' mutex. Intentionally - * deadlock on attempts to get a lock you already own. - */ - - THR_SCHED_LOCK(curthread, curthread); - THR_SET_STATE(curthread, PS_DEADLOCK); - THR_SCHED_UNLOCK(curthread, curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - break; - - case PTHREAD_MUTEX_RECURSIVE: - /* Increment the lock count: */ - m->m_count++; - break; - - default: - /* Trap invalid mutex types; */ - ret = EINVAL; - } - - return (ret); -} - -static int -mutex_unlock_common(pthread_mutex_t *m, int add_reference) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx = NULL; - int ret = 0; - - if (m == NULL || *m == NULL) - ret = EINVAL; - else { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); - - /* Process according to mutex type: */ - switch ((*m)->m_protocol) { - /* Default POSIX mutex: */ - case PTHREAD_PRIO_NONE: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is a recursive - * mutex. - */ - (*m)->m_count = 0; - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* POSIX priority inheritence mutex: */ - case PTHREAD_PRIO_INHERIT: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is recursive - * mutex. - */ - (*m)->m_count = 0; - - /* - * Restore the threads inherited priority and - * recompute the active priority (being careful - * not to override changes in the threads base - * priority subsequent to locking the mutex). - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->inherited_priority = - (*m)->m_saved_prio; - curthread->active_priority = - MAX(curthread->inherited_priority, - curthread->base_priority); - - /* - * This thread now owns one less priority mutex. - */ - curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* POSIX priority ceiling mutex: */ - case PTHREAD_PRIO_PROTECT: - /* - * Check if the running thread is not the owner of the - * mutex: - */ - if ((*m)->m_owner != curthread) - ret = EPERM; - else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) && - ((*m)->m_count > 0)) - /* Decrement the count: */ - (*m)->m_count--; - else { - /* - * Clear the count in case this is a recursive - * mutex. - */ - (*m)->m_count = 0; - - /* - * Restore the threads inherited priority and - * recompute the active priority (being careful - * not to override changes in the threads base - * priority subsequent to locking the mutex). - */ - THR_SCHED_LOCK(curthread, curthread); - curthread->inherited_priority = - (*m)->m_saved_prio; - curthread->active_priority = - MAX(curthread->inherited_priority, - curthread->base_priority); - - /* - * This thread now owns one less priority mutex. - */ - curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); - - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(*m); - TAILQ_REMOVE(&(*m)->m_owner->mutexq, - (*m), m_qe); - MUTEX_INIT_LINK(*m); - - /* - * Hand off the mutex to the next waiting - * thread: - */ - kmbx = mutex_handoff(curthread, *m); - } - break; - - /* Trap invalid mutex types: */ - default: - /* Return an invalid argument error: */ - ret = EINVAL; - break; - } - - if ((ret == 0) && (add_reference != 0)) - /* Increment the reference count: */ - (*m)->m_refcount++; - - /* Leave the critical region if this is a private mutex. */ - if ((ret == 0) && ((*m)->m_flags & MUTEX_FLAGS_PRIVATE)) - THR_CRITICAL_LEAVE(curthread); - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - - if (kmbx != NULL) - kse_wakeup(kmbx); - } - - /* Return the completion status: */ - return (ret); -} - - -/* - * This function is called when a change in base priority occurs for - * a thread that is holding or waiting for a priority protection or - * inheritence mutex. A change in a threads base priority can effect - * changes to active priorities of other threads and to the ordering - * of mutex locking by waiting threads. - * - * This must be called without the target thread's scheduling lock held. - */ -void -_mutex_notify_priochange(struct pthread *curthread, struct pthread *pthread, - int propagate_prio) -{ - struct pthread_mutex *m; - - /* Adjust the priorites of any owned priority mutexes: */ - if (pthread->priority_mutex_count > 0) { - /* - * Rescan the mutexes owned by this thread and correct - * their priorities to account for this threads change - * in priority. This has the side effect of changing - * the threads active priority. - * - * Be sure to lock the first mutex in the list of owned - * mutexes. This acts as a barrier against another - * simultaneous call to change the threads priority - * and from the owning thread releasing the mutex. - */ - m = TAILQ_FIRST(&pthread->mutexq); - if (m != NULL) { - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - /* - * Make sure the thread still owns the lock. - */ - if (m == TAILQ_FIRST(&pthread->mutexq)) - mutex_rescan_owned(curthread, pthread, - /* rescan all owned */ NULL); - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } - - /* - * If this thread is waiting on a priority inheritence mutex, - * check for priority adjustments. A change in priority can - * also cause a ceiling violation(*) for a thread waiting on - * a priority protection mutex; we don't perform the check here - * as it is done in pthread_mutex_unlock. - * - * (*) It should be noted that a priority change to a thread - * _after_ taking and owning a priority ceiling mutex - * does not affect ownership of that mutex; the ceiling - * priority is only checked before mutex ownership occurs. - */ - if (propagate_prio != 0) { - /* - * Lock the thread's scheduling queue. This is a bit - * convoluted; the "in synchronization queue flag" can - * only be cleared with both the thread's scheduling and - * mutex locks held. The thread's pointer to the wanted - * mutex is guaranteed to be valid during this time. - */ - THR_SCHED_LOCK(curthread, pthread); - - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) == 0) || - ((m = pthread->data.mutex) == NULL)) - THR_SCHED_UNLOCK(curthread, pthread); - else { - /* - * This thread is currently waiting on a mutex; unlock - * the scheduling queue lock and lock the mutex. We - * can't hold both at the same time because the locking - * order could cause a deadlock. - */ - THR_SCHED_UNLOCK(curthread, pthread); - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - /* - * Check to make sure this thread is still in the - * same state (the lock above can yield the CPU to - * another thread or the thread may be running on - * another CPU). - */ - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - (pthread->data.mutex == m)) { - /* - * Remove and reinsert this thread into - * the list of waiting threads to preserve - * decreasing priority order. - */ - mutex_queue_remove(m, pthread); - mutex_queue_enq(m, pthread); - - if (m->m_protocol == PTHREAD_PRIO_INHERIT) - /* Adjust priorities: */ - mutex_priority_adjust(curthread, m); - } - - /* Unlock the mutex structure: */ - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } -} - -/* - * Called when a new thread is added to the mutex waiting queue or - * when a threads priority changes that is already in the mutex - * waiting queue. - * - * This must be called with the mutex locked by the current thread. - */ -static void -mutex_priority_adjust(struct pthread *curthread, pthread_mutex_t mutex) -{ - pthread_mutex_t m = mutex; - struct pthread *pthread_next, *pthread = mutex->m_owner; - int done, temp_prio; - - /* - * Calculate the mutex priority as the maximum of the highest - * active priority of any waiting threads and the owning threads - * active priority(*). - * - * (*) Because the owning threads current active priority may - * reflect priority inherited from this mutex (and the mutex - * priority may have changed) we must recalculate the active - * priority based on the threads saved inherited priority - * and its base priority. - */ - pthread_next = TAILQ_FIRST(&m->m_queue); /* should never be NULL */ - temp_prio = MAX(pthread_next->active_priority, - MAX(m->m_saved_prio, pthread->base_priority)); - - /* See if this mutex really needs adjusting: */ - if (temp_prio == m->m_prio) - /* No need to propagate the priority: */ - return; - - /* Set new priority of the mutex: */ - m->m_prio = temp_prio; - - /* - * Don't unlock the mutex passed in as an argument. It is - * expected to be locked and unlocked by the caller. - */ - done = 1; - do { - /* - * Save the threads priority before rescanning the - * owned mutexes: - */ - temp_prio = pthread->active_priority; - - /* - * Fix the priorities for all mutexes held by the owning - * thread since taking this mutex. This also has a - * potential side-effect of changing the threads priority. - * - * At this point the mutex is locked by the current thread. - * The owning thread can't release the mutex until it is - * unlocked, so we should be able to safely walk its list - * of owned mutexes. - */ - mutex_rescan_owned(curthread, pthread, m); - - /* - * If this isn't the first time through the loop, - * the current mutex needs to be unlocked. - */ - if (done == 0) - THR_LOCK_RELEASE(curthread, &m->m_lock); - - /* Assume we're done unless told otherwise: */ - done = 1; - - /* - * If the thread is currently waiting on a mutex, check - * to see if the threads new priority has affected the - * priority of the mutex. - */ - if ((temp_prio != pthread->active_priority) && - ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - ((m = pthread->data.mutex) != NULL) && - (m->m_protocol == PTHREAD_PRIO_INHERIT)) { - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - /* - * Make sure the thread is still waiting on the - * mutex: - */ - if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) && - (m == pthread->data.mutex)) { - /* - * The priority for this thread has changed. - * Remove and reinsert this thread into the - * list of waiting threads to preserve - * decreasing priority order. - */ - mutex_queue_remove(m, pthread); - mutex_queue_enq(m, pthread); - - /* - * Grab the waiting thread with highest - * priority: - */ - pthread_next = TAILQ_FIRST(&m->m_queue); - - /* - * Calculate the mutex priority as the maximum - * of the highest active priority of any - * waiting threads and the owning threads - * active priority. - */ - temp_prio = MAX(pthread_next->active_priority, - MAX(m->m_saved_prio, - m->m_owner->base_priority)); - - if (temp_prio != m->m_prio) { - /* - * The priority needs to be propagated - * to the mutex this thread is waiting - * on and up to the owner of that mutex. - */ - m->m_prio = temp_prio; - pthread = m->m_owner; - - /* We're not done yet: */ - done = 0; - } - } - /* Only release the mutex if we're done: */ - if (done != 0) - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } while (done == 0); -} - -static void -mutex_rescan_owned(struct pthread *curthread, struct pthread *pthread, - struct pthread_mutex *mutex) -{ - struct pthread_mutex *m; - struct pthread *pthread_next; - int active_prio, inherited_prio; - - /* - * Start walking the mutexes the thread has taken since - * taking this mutex. - */ - if (mutex == NULL) { - /* - * A null mutex means start at the beginning of the owned - * mutex list. - */ - m = TAILQ_FIRST(&pthread->mutexq); - - /* There is no inherited priority yet. */ - inherited_prio = 0; - } else { - /* - * The caller wants to start after a specific mutex. It - * is assumed that this mutex is a priority inheritence - * mutex and that its priority has been correctly - * calculated. - */ - m = TAILQ_NEXT(mutex, m_qe); - - /* Start inheriting priority from the specified mutex. */ - inherited_prio = mutex->m_prio; - } - active_prio = MAX(inherited_prio, pthread->base_priority); - - for (; m != NULL; m = TAILQ_NEXT(m, m_qe)) { - /* - * We only want to deal with priority inheritence - * mutexes. This might be optimized by only placing - * priority inheritence mutexes into the owned mutex - * list, but it may prove to be useful having all - * owned mutexes in this list. Consider a thread - * exiting while holding mutexes... - */ - if (m->m_protocol == PTHREAD_PRIO_INHERIT) { - /* - * Fix the owners saved (inherited) priority to - * reflect the priority of the previous mutex. - */ - m->m_saved_prio = inherited_prio; - - if ((pthread_next = TAILQ_FIRST(&m->m_queue)) != NULL) - /* Recalculate the priority of the mutex: */ - m->m_prio = MAX(active_prio, - pthread_next->active_priority); - else - m->m_prio = active_prio; - - /* Recalculate new inherited and active priorities: */ - inherited_prio = m->m_prio; - active_prio = MAX(m->m_prio, pthread->base_priority); - } - } - - /* - * Fix the threads inherited priority and recalculate its - * active priority. - */ - pthread->inherited_priority = inherited_prio; - active_prio = MAX(inherited_prio, pthread->base_priority); - - if (active_prio != pthread->active_priority) { - /* Lock the thread's scheduling queue: */ - THR_SCHED_LOCK(curthread, pthread); - - if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) { - /* - * This thread is not in a run queue. Just set - * its active priority. - */ - pthread->active_priority = active_prio; - } - else { - /* - * This thread is in a run queue. Remove it from - * the queue before changing its priority: - */ - THR_RUNQ_REMOVE(pthread); - - /* - * POSIX states that if the priority is being - * lowered, the thread must be inserted at the - * head of the queue for its priority if it owns - * any priority protection or inheritence mutexes. - */ - if ((active_prio < pthread->active_priority) && - (pthread->priority_mutex_count > 0)) { - /* Set the new active priority. */ - pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_HEAD(pthread); - } else { - /* Set the new active priority. */ - pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_TAIL(pthread); - } - } - THR_SCHED_UNLOCK(curthread, pthread); - } -} - -void -_mutex_unlock_private(pthread_t pthread) -{ - struct pthread_mutex *m, *m_next; - - for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) { - m_next = TAILQ_NEXT(m, m_qe); - if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0) - pthread_mutex_unlock(&m); - } -} - -/* - * This is called by the current thread when it wants to back out of a - * mutex_lock in order to run a signal handler. - */ -static void -mutex_lock_backout(void *arg) -{ - struct pthread *curthread = (struct pthread *)arg; - struct pthread_mutex *m; - - if ((curthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) { - /* - * Any other thread may clear the "in sync queue flag", - * but only the current thread can clear the pointer - * to the mutex. So if the flag is set, we can - * guarantee that the pointer to the mutex is valid. - * The only problem may be if the mutex is destroyed - * out from under us, but that should be considered - * an application bug. - */ - m = curthread->data.mutex; - - /* Lock the mutex structure: */ - THR_LOCK_ACQUIRE(curthread, &m->m_lock); - - - /* - * Check to make sure this thread doesn't already own - * the mutex. Since mutexes are unlocked with direct - * handoffs, it is possible the previous owner gave it - * to us after we checked the sync queue flag and before - * we locked the mutex structure. - */ - if (m->m_owner == curthread) { - THR_LOCK_RELEASE(curthread, &m->m_lock); - mutex_unlock_common(&m, /* add_reference */ 0); - } else { - /* - * Remove ourselves from the mutex queue and - * clear the pointer to the mutex. We may no - * longer be in the mutex queue, but the removal - * function will DTRT. - */ - mutex_queue_remove(m, curthread); - curthread->data.mutex = NULL; - THR_LOCK_RELEASE(curthread, &m->m_lock); - } - } - /* No need to call this again. */ - curthread->sigbackout = NULL; -} - -/* - * Dequeue a waiting thread from the head of a mutex queue in descending - * priority order. - * - * In order to properly dequeue a thread from the mutex queue and - * make it runnable without the possibility of errant wakeups, it - * is necessary to lock the thread's scheduling queue while also - * holding the mutex lock. - */ -static struct kse_mailbox * -mutex_handoff(struct pthread *curthread, struct pthread_mutex *mutex) -{ - struct kse_mailbox *kmbx = NULL; - struct pthread *pthread; - - /* Keep dequeueing until we find a valid thread: */ - mutex->m_owner = NULL; - pthread = TAILQ_FIRST(&mutex->m_queue); - while (pthread != NULL) { - /* Take the thread's scheduling lock: */ - THR_SCHED_LOCK(curthread, pthread); - - /* Remove the thread from the mutex queue: */ - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - - /* - * Only exit the loop if the thread hasn't been - * cancelled. - */ - switch (mutex->m_protocol) { - case PTHREAD_PRIO_NONE: - /* - * Assign the new owner and add the mutex to the - * thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, mutex, m_qe); - break; - - case PTHREAD_PRIO_INHERIT: - /* - * Assign the new owner and add the mutex to the - * thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, mutex, m_qe); - - /* Track number of priority mutexes owned: */ - pthread->priority_mutex_count++; - - /* - * Set the priority of the mutex. Since our waiting - * threads are in descending priority order, the - * priority of the mutex becomes the active priority - * of the thread we just dequeued. - */ - mutex->m_prio = pthread->active_priority; - - /* Save the owning threads inherited priority: */ - mutex->m_saved_prio = pthread->inherited_priority; - - /* - * The owning threads inherited priority now becomes - * his active priority (the priority of the mutex). - */ - pthread->inherited_priority = mutex->m_prio; - break; - - case PTHREAD_PRIO_PROTECT: - if (pthread->active_priority > mutex->m_prio) { - /* - * Either the mutex ceiling priority has - * been lowered and/or this threads priority - * has been raised subsequent to the thread - * being queued on the waiting list. - */ - pthread->error = EINVAL; - } - else { - /* - * Assign the new owner and add the mutex - * to the thread's list of owned mutexes. - */ - mutex->m_owner = pthread; - TAILQ_INSERT_TAIL(&pthread->mutexq, - mutex, m_qe); - - /* Track number of priority mutexes owned: */ - pthread->priority_mutex_count++; - - /* - * Save the owning threads inherited - * priority: - */ - mutex->m_saved_prio = - pthread->inherited_priority; - - /* - * The owning thread inherits the ceiling - * priority of the mutex and executes at - * that priority: - */ - pthread->inherited_priority = mutex->m_prio; - pthread->active_priority = mutex->m_prio; - - } - break; - } - - /* Make the thread runnable and unlock the scheduling queue: */ - kmbx = _thr_setrunnable_unlocked(pthread); - - /* Add a preemption point. */ - if ((curthread->kseg == pthread->kseg) && - (pthread->active_priority > curthread->active_priority)) - curthread->critical_yield = 1; - - if (mutex->m_owner == pthread) { - /* We're done; a valid owner was found. */ - if (mutex->m_flags & MUTEX_FLAGS_PRIVATE) - THR_CRITICAL_ENTER(pthread); - THR_SCHED_UNLOCK(curthread, pthread); - break; - } - THR_SCHED_UNLOCK(curthread, pthread); - /* Get the next thread from the waiting queue: */ - pthread = TAILQ_NEXT(pthread, sqe); - } - - if ((pthread == NULL) && (mutex->m_protocol == PTHREAD_PRIO_INHERIT)) - /* This mutex has no priority: */ - mutex->m_prio = 0; - return (kmbx); -} - -/* - * Dequeue a waiting thread from the head of a mutex queue in descending - * priority order. - */ -static inline pthread_t -mutex_queue_deq(struct pthread_mutex *mutex) -{ - pthread_t pthread; - - while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) { - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - - /* - * Only exit the loop if the thread hasn't been - * cancelled. - */ - if (pthread->interrupted == 0) - break; - } - - return (pthread); -} - -/* - * Remove a waiting thread from a mutex queue in descending priority order. - */ -static inline void -mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread) -{ - if ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) { - TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); - pthread->sflags &= ~THR_FLAGS_IN_SYNCQ; - } -} - -/* - * Enqueue a waiting thread to a queue in descending priority order. - */ -static inline void -mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread) -{ - pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head); - - THR_ASSERT_NOT_IN_SYNCQ(pthread); - /* - * 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(&mutex->m_queue, pthread, sqe); - else { - tid = TAILQ_FIRST(&mutex->m_queue); - while (pthread->active_priority <= tid->active_priority) - tid = TAILQ_NEXT(tid, sqe); - TAILQ_INSERT_BEFORE(tid, pthread, sqe); - } - pthread->sflags |= THR_FLAGS_IN_SYNCQ; -} diff --git a/lib/libpthread/thread/thr_mutex_prioceiling.c b/lib/libpthread/thread/thr_mutex_prioceiling.c deleted file mode 100644 index f254346..0000000 --- a/lib/libpthread/thread/thr_mutex_prioceiling.c +++ /dev/null @@ -1,124 +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 <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_mutexattr_getprioceiling); -LT10_COMPAT_DEFAULT(pthread_mutexattr_getprioceiling); -LT10_COMPAT_PRIVATE(_pthread_mutexattr_setprioceiling); -LT10_COMPAT_DEFAULT(pthread_mutexattr_setprioceiling); -LT10_COMPAT_PRIVATE(_pthread_mutex_getprioceiling); -LT10_COMPAT_DEFAULT(pthread_mutex_getprioceiling); -LT10_COMPAT_PRIVATE(_pthread_mutex_setprioceiling); -LT10_COMPAT_DEFAULT(pthread_mutex_setprioceiling); - -__weak_reference(_pthread_mutexattr_getprioceiling, pthread_mutexattr_getprioceiling); -__weak_reference(_pthread_mutexattr_setprioceiling, pthread_mutexattr_setprioceiling); -__weak_reference(_pthread_mutex_getprioceiling, pthread_mutex_getprioceiling); -__weak_reference(_pthread_mutex_setprioceiling, pthread_mutex_setprioceiling); - -int -_pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else - *prioceiling = (*mattr)->m_ceiling; - - return(ret); -} - -int -_pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else - (*mattr)->m_ceiling = prioceiling; - - return(ret); -} - -int -_pthread_mutex_getprioceiling(pthread_mutex_t *mutex, - int *prioceiling) -{ - int ret; - - if ((mutex == NULL) || (*mutex == NULL)) - ret = EINVAL; - else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - else - ret = (*mutex)->m_prio; - - return(ret); -} - -int -_pthread_mutex_setprioceiling(pthread_mutex_t *mutex, - int prioceiling, int *old_ceiling) -{ - int ret = 0; - int tmp; - - if ((mutex == NULL) || (*mutex == NULL)) - ret = EINVAL; - else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT) - ret = EINVAL; - /* Lock the mutex: */ - else if ((ret = pthread_mutex_lock(mutex)) == 0) { - tmp = (*mutex)->m_prio; - /* Set the new ceiling: */ - (*mutex)->m_prio = prioceiling; - - /* Unlock the mutex: */ - ret = pthread_mutex_unlock(mutex); - - /* Return the old ceiling: */ - *old_ceiling = tmp; - } - return(ret); -} diff --git a/lib/libpthread/thread/thr_mutex_protocol.c b/lib/libpthread/thread/thr_mutex_protocol.c deleted file mode 100644 index 9e3e46b..0000000 --- a/lib/libpthread/thread/thr_mutex_protocol.c +++ /dev/null @@ -1,75 +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 <string.h> -#include <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_mutexattr_getprotocol); -LT10_COMPAT_DEFAULT(pthread_mutexattr_getprotocol); -LT10_COMPAT_PRIVATE(_pthread_mutexattr_setprotocol); -LT10_COMPAT_DEFAULT(pthread_mutexattr_setprotocol); - -__weak_reference(_pthread_mutexattr_getprotocol, pthread_mutexattr_getprotocol); -__weak_reference(_pthread_mutexattr_setprotocol, pthread_mutexattr_setprotocol); - -int -_pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL)) - ret = EINVAL; - else - *protocol = (*mattr)->m_protocol; - - return(ret); -} - -int -_pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol) -{ - int ret = 0; - - if ((mattr == NULL) || (*mattr == NULL) || - (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT)) - ret = EINVAL; - else { - (*mattr)->m_protocol = protocol; - (*mattr)->m_ceiling = THR_MAX_PRIORITY; - } - return(ret); -} - diff --git a/lib/libpthread/thread/thr_mutexattr_destroy.c b/lib/libpthread/thread/thr_mutexattr_destroy.c deleted file mode 100644 index 86c051d..0000000 --- a/lib/libpthread/thread/thr_mutexattr_destroy.c +++ /dev/null @@ -1,53 +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 <stdlib.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_mutexattr_destroy); -LT10_COMPAT_DEFAULT(pthread_mutexattr_destroy); - -__weak_reference(_pthread_mutexattr_destroy, pthread_mutexattr_destroy); - -int -_pthread_mutexattr_destroy(pthread_mutexattr_t *attr) -{ - int ret; - if (attr == NULL || *attr == NULL) { - ret = EINVAL; - } else { - free(*attr); - *attr = NULL; - ret = 0; - } - return(ret); -} diff --git a/lib/libpthread/thread/thr_nanosleep.c b/lib/libpthread/thread/thr_nanosleep.c deleted file mode 100644 index 974cc20..0000000 --- a/lib/libpthread/thread/thr_nanosleep.c +++ /dev/null @@ -1,132 +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 <stdio.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__nanosleep); -LT10_COMPAT_PRIVATE(_nanosleep); -LT10_COMPAT_DEFAULT(nanosleep); - -__weak_reference(__nanosleep, nanosleep); - -int -_nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - struct timespec ts, ts1; - struct timespec remaining_time; - struct timespec wakeup_time; - - /* Check if the time to sleep is legal: */ - if ((time_to_sleep == NULL) || (time_to_sleep->tv_sec < 0) || - (time_to_sleep->tv_nsec < 0) || - (time_to_sleep->tv_nsec >= 1000000000)) { - /* Return an EINVAL error : */ - errno = EINVAL; - ret = -1; - } else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_nanosleep(time_to_sleep, time_remaining)); - - KSE_GET_TOD(curthread->kse, &ts); - - /* Calculate the time for the current thread to wake up: */ - TIMESPEC_ADD(&wakeup_time, &ts, time_to_sleep); - - THR_LOCK_SWITCH(curthread); - curthread->interrupted = 0; - curthread->wakeup_time = wakeup_time; - THR_SET_STATE(curthread, PS_SLEEP_WAIT); - - /* Reschedule the current thread to sleep: */ - _thr_sched_switch_unlocked(curthread); - - /* Calculate the remaining time to sleep: */ - KSE_GET_TOD(curthread->kse, &ts1); - remaining_time.tv_sec = time_to_sleep->tv_sec - + ts.tv_sec - ts1.tv_sec; - remaining_time.tv_nsec = time_to_sleep->tv_nsec - + ts.tv_nsec - ts1.tv_nsec; - - /* Check if the nanosecond field has underflowed: */ - if (remaining_time.tv_nsec < 0) { - /* Handle the underflow: */ - remaining_time.tv_sec -= 1; - remaining_time.tv_nsec += 1000000000; - } - /* Check if the nanosecond field has overflowed: */ - else if (remaining_time.tv_nsec >= 1000000000) { - /* Handle the overflow: */ - remaining_time.tv_sec += 1; - remaining_time.tv_nsec -= 1000000000; - } - - /* Check if the sleep was longer than the required time: */ - if (remaining_time.tv_sec < 0) { - /* Reset the time left: */ - remaining_time.tv_sec = 0; - remaining_time.tv_nsec = 0; - } - - /* Check if the time remaining is to be returned: */ - if (time_remaining != NULL) { - /* Return the actual time slept: */ - time_remaining->tv_sec = remaining_time.tv_sec; - time_remaining->tv_nsec = remaining_time.tv_nsec; - } - - /* Check if the sleep was interrupted: */ - if (curthread->interrupted) { - /* Return an EINTR error : */ - errno = EINTR; - ret = -1; - } - } - return (ret); -} - -int -__nanosleep(const struct timespec *time_to_sleep, - struct timespec *time_remaining) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _nanosleep(time_to_sleep, time_remaining); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_once.c b/lib/libpthread/thread/thr_once.c deleted file mode 100644 index cd69cd6..0000000 --- a/lib/libpthread/thread/thr_once.c +++ /dev/null @@ -1,98 +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 <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_once); -LT10_COMPAT_DEFAULT(pthread_once); - -__weak_reference(_pthread_once, pthread_once); - -#define ONCE_NEVER_DONE PTHREAD_NEEDS_INIT -#define ONCE_DONE PTHREAD_DONE_INIT -#define ONCE_IN_PROGRESS 0x02 -#define ONCE_MASK 0x03 - -static pthread_mutex_t once_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t once_cv = PTHREAD_COND_INITIALIZER; - -/* - * POSIX: - * The pthread_once() function is not a cancellation point. However, - * if init_routine is a cancellation point and is canceled, the effect - * on once_control shall be as if pthread_once() was never called. - */ - -static void -once_cancel_handler(void *arg) -{ - pthread_once_t *once_control = arg; - - _pthread_mutex_lock(&once_lock); - once_control->state = ONCE_NEVER_DONE; - _pthread_mutex_unlock(&once_lock); - _pthread_cond_broadcast(&once_cv); -} - -int -_pthread_once(pthread_once_t *once_control, void (*init_routine) (void)) -{ - struct pthread *curthread; - int wakeup = 0; - - if (once_control->state == ONCE_DONE) - return (0); - _pthread_mutex_lock(&once_lock); - while (*(volatile int *)&(once_control->state) == ONCE_IN_PROGRESS) - _pthread_cond_wait(&once_cv, &once_lock); - /* - * If previous thread was canceled, then the state still - * could be ONCE_NEVER_DONE, we need to check it again. - */ - if (*(volatile int *)&(once_control->state) == ONCE_NEVER_DONE) { - once_control->state = ONCE_IN_PROGRESS; - _pthread_mutex_unlock(&once_lock); - curthread = _get_curthread(); - THR_CLEANUP_PUSH(curthread, once_cancel_handler, once_control); - init_routine(); - THR_CLEANUP_POP(curthread, 0); - _pthread_mutex_lock(&once_lock); - once_control->state = ONCE_DONE; - wakeup = 1; - } - _pthread_mutex_unlock(&once_lock); - if (wakeup) - _pthread_cond_broadcast(&once_cv); - return (0); -} - diff --git a/lib/libpthread/thread/thr_open.c b/lib/libpthread/thread/thr_open.c deleted file mode 100644 index 7d5035f..0000000 --- a/lib/libpthread/thread/thr_open.c +++ /dev/null @@ -1,71 +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 <stdarg.h> -#include <unistd.h> -#include <fcntl.h> -#include <dirent.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__open); -LT10_COMPAT_DEFAULT(open); - -__weak_reference(__open, open); - -int -__open(const char *path, int flags,...) -{ - struct pthread *curthread = _get_curthread(); - int ret; - int mode = 0; - va_list ap; - - _thr_cancel_enter(curthread); - - /* Check if the file is being created: */ - if (flags & O_CREAT) { - /* Get the creation mode: */ - va_start(ap, flags); - mode = va_arg(ap, int); - va_end(ap); - } - - ret = __sys_open(path, flags, mode); - /* - * To avoid possible file handle leak, - * only check cancellation point if it is failure - */ - _thr_cancel_leave(curthread, (ret == -1)); - - return ret; -} diff --git a/lib/libpthread/thread/thr_pause.c b/lib/libpthread/thread/thr_pause.c deleted file mode 100644 index b3f0fe5..0000000 --- a/lib/libpthread/thread/thr_pause.c +++ /dev/null @@ -1,54 +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 <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -extern int __pause(void); - -LT10_COMPAT_PRIVATE(_pause); -LT10_COMPAT_DEFAULT(pause); - -__weak_reference(_pause, pause); - -int -_pause(void) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __pause(); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_poll.c b/lib/libpthread/thread/thr_poll.c deleted file mode 100644 index 5e3890b..0000000 --- a/lib/libpthread/thread/thr_poll.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1999 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 <unistd.h> -#include <errno.h> -#include <string.h> -#include <poll.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/fcntl.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__poll); -LT10_COMPAT_DEFAULT(poll); - -__weak_reference(__poll, poll); - -int -__poll(struct pollfd *fds, unsigned int nfds, int timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __sys_poll(fds, nfds, timeout); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_printf.c b/lib/libpthread/thread/thr_printf.c deleted file mode 100644 index 2a4b12b..0000000 --- a/lib/libpthread/thread/thr_printf.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 2002 Jonathan Mini <mini@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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdarg.h> -#include <string.h> -#include <unistd.h> - -#include "thr_private.h" - -static void pchar(int fd, char c); -static void pstr(int fd, const char *s); - -/* - * Write formatted output to stdout, in a thread-safe manner. - * - * Recognises the following conversions: - * %c -> char - * %d -> signed int (base 10) - * %s -> string - * %u -> unsigned int (base 10) - * %x -> unsigned int (base 16) - * %p -> unsigned int (base 16) - */ -void -_thread_printf(int fd, const char *fmt, ...) -{ - static const char digits[16] = "0123456789abcdef"; - va_list ap; - char buf[20]; - char *s; - unsigned long r, u; - int c; - long d; - int islong; - - va_start(ap, fmt); - while ((c = *fmt++)) { - islong = 0; - if (c == '%') { -next: c = *fmt++; - if (c == '\0') - goto out; - switch (c) { - case 'c': - pchar(fd, va_arg(ap, int)); - continue; - case 's': - pstr(fd, va_arg(ap, char *)); - continue; - case 'l': - islong = 1; - goto next; - case 'p': - islong = 1; - case 'd': - case 'u': - case 'x': - r = ((c == 'u') || (c == 'd')) ? 10 : 16; - if (c == 'd') { - if (islong) - d = va_arg(ap, unsigned long); - else - d = va_arg(ap, unsigned); - if (d < 0) { - pchar(fd, '-'); - u = (unsigned long)(d * -1); - } else - u = (unsigned long)d; - } else { - if (islong) - u = va_arg(ap, unsigned long); - else - u = va_arg(ap, unsigned); - } - s = buf; - do { - *s++ = digits[u % r]; - } while (u /= r); - while (--s >= buf) - pchar(fd, *s); - continue; - } - } - pchar(fd, c); - } -out: - va_end(ap); -} - -/* - * Write a single character to stdout, in a thread-safe manner. - */ -static void -pchar(int fd, char c) -{ - - __sys_write(fd, &c, 1); -} - -/* - * Write a string to stdout, in a thread-safe manner. - */ -static void -pstr(int fd, const char *s) -{ - - __sys_write(fd, s, strlen(s)); -} - diff --git a/lib/libpthread/thread/thr_priority_queue.c b/lib/libpthread/thread/thr_priority_queue.c deleted file mode 100644 index f750a01..0000000 --- a/lib/libpthread/thread/thr_priority_queue.c +++ /dev/null @@ -1,324 +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 <stdlib.h> -#include <sys/queue.h> -#include <string.h> -#include <pthread.h> -#include "thr_private.h" - -/* Prototypes: */ -static void pq_insert_prio_list(pq_queue_t *pq, int prio); - -#if defined(_PTHREADS_INVARIANTS) - -#define PQ_IN_SCHEDQ (THR_FLAGS_IN_RUNQ | THR_FLAGS_IN_WAITQ) - -#define PQ_SET_ACTIVE(pq) (pq)->pq_flags |= PQF_ACTIVE -#define PQ_CLEAR_ACTIVE(pq) (pq)->pq_flags &= ~PQF_ACTIVE -#define PQ_ASSERT_ACTIVE(pq, msg) do { \ - if (((pq)->pq_flags & PQF_ACTIVE) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_INACTIVE(pq, msg) do { \ - if (((pq)->pq_flags & PQF_ACTIVE) != 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_IN_WAITQ(thrd, msg) do { \ - if (((thrd)->flags & THR_FLAGS_IN_WAITQ) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_IN_RUNQ(thrd, msg) do { \ - if (((thrd)->flags & THR_FLAGS_IN_RUNQ) == 0) \ - PANIC(msg); \ -} while (0) -#define PQ_ASSERT_NOT_QUEUED(thrd, msg) do { \ - if (((thrd)->flags & PQ_IN_SCHEDQ) != 0) \ - PANIC(msg); \ -} while (0) - -#else - -#define PQ_SET_ACTIVE(pq) -#define PQ_CLEAR_ACTIVE(pq) -#define PQ_ASSERT_ACTIVE(pq, msg) -#define PQ_ASSERT_INACTIVE(pq, msg) -#define PQ_ASSERT_IN_WAITQ(thrd, msg) -#define PQ_ASSERT_IN_RUNQ(thrd, msg) -#define PQ_ASSERT_NOT_QUEUED(thrd, msg) - -#endif - -int -_pq_alloc(pq_queue_t *pq, int minprio, int maxprio) -{ - int ret = 0; - int prioslots = maxprio - minprio + 1; - - if (pq == NULL) - ret = -1; - - /* Create the priority queue with (maxprio - minprio + 1) slots: */ - else if ((pq->pq_lists = - (pq_list_t *) malloc(sizeof(pq_list_t) * prioslots)) == NULL) - ret = -1; - - else { - /* Remember the queue size: */ - pq->pq_size = prioslots; - ret = _pq_init(pq); - } - return (ret); -} - -void -_pq_free(pq_queue_t *pq) -{ - if ((pq != NULL) && (pq->pq_lists != NULL)) - free(pq->pq_lists); -} - -int -_pq_init(pq_queue_t *pq) -{ - int i, ret = 0; - - if ((pq == NULL) || (pq->pq_lists == NULL)) - ret = -1; - - else { - /* Initialize the queue for each priority slot: */ - for (i = 0; i < pq->pq_size; i++) { - TAILQ_INIT(&pq->pq_lists[i].pl_head); - pq->pq_lists[i].pl_prio = i; - pq->pq_lists[i].pl_queued = 0; - } - /* Initialize the priority queue: */ - TAILQ_INIT(&pq->pq_queue); - pq->pq_flags = 0; - pq->pq_threads = 0; - } - return (ret); -} - -void -_pq_remove(pq_queue_t *pq, pthread_t pthread) -{ - int prio = pthread->active_priority; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_remove: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_IN_RUNQ(pthread, "_pq_remove: Not in priority queue"); - - /* - * Remove this thread from priority list. Note that if - * the priority list becomes empty, it is not removed - * from the priority queue because another thread may be - * added to the priority list (resulting in a needless - * removal/insertion). Priority lists are only removed - * from the priority queue when _pq_first is called. - */ - TAILQ_REMOVE(&pq->pq_lists[prio].pl_head, pthread, pqe); - pq->pq_threads--; - /* This thread is now longer in the priority queue. */ - pthread->flags &= ~THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -void -_pq_insert_head(pq_queue_t *pq, pthread_t pthread) -{ - int prio; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_insert_head: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_NOT_QUEUED(pthread, - "_pq_insert_head: Already in priority queue"); - - prio = pthread->active_priority; - TAILQ_INSERT_HEAD(&pq->pq_lists[prio].pl_head, pthread, pqe); - if (pq->pq_lists[prio].pl_queued == 0) - /* Insert the list into the priority queue: */ - pq_insert_prio_list(pq, prio); - pq->pq_threads++; - /* Mark this thread as being in the priority queue. */ - pthread->flags |= THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -void -_pq_insert_tail(pq_queue_t *pq, pthread_t pthread) -{ - int prio; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_insert_tail: pq_active"); - PQ_SET_ACTIVE(pq); - PQ_ASSERT_NOT_QUEUED(pthread, - "_pq_insert_tail: Already in priority queue"); - - prio = pthread->active_priority; - TAILQ_INSERT_TAIL(&pq->pq_lists[prio].pl_head, pthread, pqe); - if (pq->pq_lists[prio].pl_queued == 0) - /* Insert the list into the priority queue: */ - pq_insert_prio_list(pq, prio); - pq->pq_threads++; - /* Mark this thread as being in the priority queue. */ - pthread->flags |= THR_FLAGS_IN_RUNQ; - - PQ_CLEAR_ACTIVE(pq); -} - - -pthread_t -_pq_first(pq_queue_t *pq) -{ - pq_list_t *pql; - pthread_t pthread = NULL; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_first: pq_active"); - PQ_SET_ACTIVE(pq); - - while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) && - (pthread == NULL)) { - if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) { - /* - * The priority list is empty; remove the list - * from the queue. - */ - TAILQ_REMOVE(&pq->pq_queue, pql, pl_link); - - /* Mark the list as not being in the queue: */ - pql->pl_queued = 0; - } - } - - PQ_CLEAR_ACTIVE(pq); - return (pthread); -} - -/* - * Select a thread which is allowed to run by debugger, we probably - * should merge the function into _pq_first if that function is only - * used by scheduler to select a thread. - */ -pthread_t -_pq_first_debug(pq_queue_t *pq) -{ - pq_list_t *pql, *pqlnext = NULL; - pthread_t pthread = NULL; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_INACTIVE(pq, "_pq_first: pq_active"); - PQ_SET_ACTIVE(pq); - - for (pql = TAILQ_FIRST(&pq->pq_queue); - pql != NULL && pthread == NULL; pql = pqlnext) { - if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) { - /* - * The priority list is empty; remove the list - * from the queue. - */ - pqlnext = TAILQ_NEXT(pql, pl_link); - TAILQ_REMOVE(&pq->pq_queue, pql, pl_link); - - /* Mark the list as not being in the queue: */ - pql->pl_queued = 0; - } else { - /* - * note there may be a suspension event during this - * test, If TMDF_SUSPEND is set after we tested it, - * we will run the thread, this seems be a problem, - * fortunatly, when we are being debugged, all context - * switch will be done by kse_switchin, that is a - * syscall, kse_switchin will check the flag again, - * the thread will be returned via upcall, so next - * time, UTS won't run the thread. - */ - while (pthread != NULL && !DBG_CAN_RUN(pthread)) { - pthread = TAILQ_NEXT(pthread, pqe); - } - if (pthread == NULL) - pqlnext = TAILQ_NEXT(pql, pl_link); - } - } - - PQ_CLEAR_ACTIVE(pq); - return (pthread); -} - -static void -pq_insert_prio_list(pq_queue_t *pq, int prio) -{ - pq_list_t *pql; - - /* - * Make some assertions when debugging is enabled: - */ - PQ_ASSERT_ACTIVE(pq, "pq_insert_prio_list: pq_active"); - - /* - * The priority queue is in descending priority order. Start at - * the beginning of the queue and find the list before which the - * new list should be inserted. - */ - pql = TAILQ_FIRST(&pq->pq_queue); - while ((pql != NULL) && (pql->pl_prio > prio)) - pql = TAILQ_NEXT(pql, pl_link); - - /* Insert the list: */ - if (pql == NULL) - TAILQ_INSERT_TAIL(&pq->pq_queue, &pq->pq_lists[prio], pl_link); - else - TAILQ_INSERT_BEFORE(pql, &pq->pq_lists[prio], pl_link); - - /* Mark this list as being in the queue: */ - pq->pq_lists[prio].pl_queued = 1; -} diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h deleted file mode 100644 index 878c0cf..0000000 --- a/lib/libpthread/thread/thr_private.h +++ /dev/null @@ -1,1324 +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. - * - * Private thread definitions for the uthread kernel. - * - * $FreeBSD$ - */ - -#ifndef _THR_PRIVATE_H -#define _THR_PRIVATE_H - -/* - * Include files. - */ -#include <setjmp.h> -#include <signal.h> -#include <stdio.h> -#include <sys/queue.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/cdefs.h> -#include <sys/kse.h> -#include <sched.h> -#include <ucontext.h> -#include <unistd.h> -#include <pthread.h> -#include <pthread_np.h> - -#ifndef LIBTHREAD_DB -#include "lock.h" -#include "pthread_md.h" -#endif - -/* - * Unfortunately, libpthread had symbol versioning before libc. - * But now libc has symbol versioning, we need to occupy the - * same version namespace in order to override some libc functions. - * So in order to avoid breaking binaries requiring symbols from - * LIBTHREAD_1_0, we need to provide a compatible interface for - * those symbols. - */ -#if 0 -#define SYM_LT10(sym) __CONCAT(sym, _lt10) -#define SYM_FB10(sym) __CONCAT(sym, _fb10) -#define SYM_FBP10(sym) __CONCAT(sym, _fbp10) -#define WEAK_REF(sym, alias) __weak_reference(sym, alias) -#define SYM_COMPAT(sym, impl, ver) __sym_compat(sym, impl, ver) -#define SYM_DEFAULT(sym, impl, ver) __sym_default(sym, impl, ver) - -#define LT10_COMPAT(sym) \ - WEAK_REF(sym, SYM_LT10(sym)); \ - SYM_COMPAT(sym, SYM_LT10(sym), LIBTHREAD_1_0) - -#define LT10_COMPAT_DEFAULT(sym) \ - LT10_COMPAT(sym); \ - WEAK_REF(sym, SYM_FB10(sym)); \ - SYM_DEFAULT(sym, SYM_FB10(sym), FBSD_1.0) - -#define LT10_COMPAT_PRIVATE(sym) \ - LT10_COMPAT(sym); \ - WEAK_REF(sym, SYM_FBP10(sym)); \ - SYM_DEFAULT(sym, SYM_FBP10(sym), FBSDprivate_1.0) -#else -#define LT10_COMPAT_DEFAULT(sym) -#define LT10_COMPAT_PRIVATE(sym) -#endif - -/* - * Evaluate the storage class specifier. - */ -#ifdef GLOBAL_PTHREAD_PRIVATE -#define SCLASS -#define SCLASS_PRESET(x...) = x -#else -#define SCLASS extern -#define SCLASS_PRESET(x...) -#endif - -/* - * Kernel fatal error handler macro. - */ -#define PANIC(string) _thr_exit(__FILE__, __LINE__, string) - - -/* Output debug messages like this: */ -#ifdef STDOUT_FILENO -#define stdout_debug(...) _thread_printf(STDOUT_FILENO, __VA_ARGS__) -#endif -#ifdef STDERR_FILENO -#define stderr_debug(...) _thread_printf(STDERR_FILENO, __VA_ARGS__) -#endif - -#define DBG_MUTEX 0x0001 -#define DBG_SIG 0x0002 -#define DBG_INFO_DUMP 0x0004 - -#ifdef _PTHREADS_INVARIANTS -#define THR_ASSERT(cond, msg) do { \ - if (!(cond)) \ - PANIC(msg); \ -} while (0) -#else -#define THR_ASSERT(cond, msg) -#endif - -/* - * State change macro without scheduling queue change: - */ -#define THR_SET_STATE(thrd, newstate) do { \ - (thrd)->state = newstate; \ - (thrd)->fname = __FILE__; \ - (thrd)->lineno = __LINE__; \ -} while (0) - - -#define TIMESPEC_ADD(dst, src, val) \ - do { \ - (dst)->tv_sec = (src)->tv_sec + (val)->tv_sec; \ - (dst)->tv_nsec = (src)->tv_nsec + (val)->tv_nsec; \ - if ((dst)->tv_nsec >= 1000000000) { \ - (dst)->tv_sec++; \ - (dst)->tv_nsec -= 1000000000; \ - } \ - } while (0) - -#define TIMESPEC_SUB(dst, src, val) \ - do { \ - (dst)->tv_sec = (src)->tv_sec - (val)->tv_sec; \ - (dst)->tv_nsec = (src)->tv_nsec - (val)->tv_nsec; \ - if ((dst)->tv_nsec < 0) { \ - (dst)->tv_sec--; \ - (dst)->tv_nsec += 1000000000; \ - } \ - } while (0) - -/* - * Priority queues. - * - * XXX It'd be nice if these were contained in uthread_priority_queue.[ch]. - */ -typedef struct pq_list { - TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */ - TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */ - int pl_prio; /* the priority of this list */ - int pl_queued; /* is this in the priority queue */ -} pq_list_t; - -typedef struct pq_queue { - TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */ - pq_list_t *pq_lists; /* array of all priority lists */ - int pq_size; /* number of priority lists */ -#define PQF_ACTIVE 0x0001 - int pq_flags; - int pq_threads; -} pq_queue_t; - -/* - * Each KSEG has a scheduling queue. For now, threads that exist in their - * own KSEG (system scope) will get a full priority queue. In the future - * this can be optimized for the single thread per KSEG case. - */ -struct sched_queue { - pq_queue_t sq_runq; - TAILQ_HEAD(, pthread) sq_waitq; /* waiting in userland */ -}; - -typedef struct kse_thr_mailbox *kse_critical_t; - -struct kse_group; - -#define MAX_KSE_LOCKLEVEL 5 -struct kse { - /* -- location and order specific items for gdb -- */ - struct kcb *k_kcb; - struct pthread *k_curthread; /* current thread */ - struct kse_group *k_kseg; /* parent KSEG */ - struct sched_queue *k_schedq; /* scheduling queue */ - /* -- end of location and order specific items -- */ - TAILQ_ENTRY(kse) k_qe; /* KSE list link entry */ - TAILQ_ENTRY(kse) k_kgqe; /* KSEG's KSE list entry */ - /* - * Items that are only modified by the kse, or that otherwise - * don't need to be locked when accessed - */ - struct lock k_lock; - struct lockuser k_lockusers[MAX_KSE_LOCKLEVEL]; - int k_locklevel; - stack_t k_stack; - int k_flags; -#define KF_STARTED 0x0001 /* kernel kse created */ -#define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */ -#define KF_TERMINATED 0x0004 /* kse is terminated */ -#define KF_IDLE 0x0008 /* kse is idle */ -#define KF_SWITCH 0x0010 /* thread switch in UTS */ - int k_error; /* syscall errno in critical */ - int k_cpu; /* CPU ID when bound */ - int k_sigseqno; /* signal buffered count */ -}; - -#define KSE_SET_IDLE(kse) ((kse)->k_flags |= KF_IDLE) -#define KSE_CLEAR_IDLE(kse) ((kse)->k_flags &= ~KF_IDLE) -#define KSE_IS_IDLE(kse) (((kse)->k_flags & KF_IDLE) != 0) -#define KSE_SET_SWITCH(kse) ((kse)->k_flags |= KF_SWITCH) -#define KSE_CLEAR_SWITCH(kse) ((kse)->k_flags &= ~KF_SWITCH) -#define KSE_IS_SWITCH(kse) (((kse)->k_flags & KF_SWITCH) != 0) - -/* - * Each KSE group contains one or more KSEs in which threads can run. - * At least for now, there is one scheduling queue per KSE group; KSEs - * within the same KSE group compete for threads from the same scheduling - * queue. A scope system thread has one KSE in one KSE group; the group - * does not use its scheduling queue. - */ -struct kse_group { - TAILQ_HEAD(, kse) kg_kseq; /* list of KSEs in group */ - TAILQ_HEAD(, pthread) kg_threadq; /* list of threads in group */ - TAILQ_ENTRY(kse_group) kg_qe; /* link entry */ - struct sched_queue kg_schedq; /* scheduling queue */ - struct lock kg_lock; - int kg_threadcount; /* # of assigned threads */ - int kg_ksecount; /* # of assigned KSEs */ - int kg_idle_kses; - int kg_flags; -#define KGF_SINGLE_THREAD 0x0001 /* scope system kse group */ -#define KGF_SCHEDQ_INITED 0x0002 /* has an initialized schedq */ -}; - -/* - * Add/remove threads from a KSE's scheduling queue. - * For now the scheduling queue is hung off the KSEG. - */ -#define KSEG_THRQ_ADD(kseg, thr) \ -do { \ - TAILQ_INSERT_TAIL(&(kseg)->kg_threadq, thr, kle);\ - (kseg)->kg_threadcount++; \ -} while (0) - -#define KSEG_THRQ_REMOVE(kseg, thr) \ -do { \ - TAILQ_REMOVE(&(kseg)->kg_threadq, thr, kle); \ - (kseg)->kg_threadcount--; \ -} while (0) - - -/* - * Lock acquire and release for KSEs. - */ -#define KSE_LOCK_ACQUIRE(kse, lck) \ -do { \ - if ((kse)->k_locklevel < MAX_KSE_LOCKLEVEL) { \ - (kse)->k_locklevel++; \ - _lock_acquire((lck), \ - &(kse)->k_lockusers[(kse)->k_locklevel - 1], 0); \ - } \ - else \ - PANIC("Exceeded maximum lock level"); \ -} while (0) - -#define KSE_LOCK_RELEASE(kse, lck) \ -do { \ - if ((kse)->k_locklevel > 0) { \ - _lock_release((lck), \ - &(kse)->k_lockusers[(kse)->k_locklevel - 1]); \ - (kse)->k_locklevel--; \ - } \ -} while (0) - -/* - * Lock our own KSEG. - */ -#define KSE_LOCK(curkse) \ - KSE_LOCK_ACQUIRE(curkse, &(curkse)->k_kseg->kg_lock) -#define KSE_UNLOCK(curkse) \ - KSE_LOCK_RELEASE(curkse, &(curkse)->k_kseg->kg_lock) - -/* - * Lock a potentially different KSEG. - */ -#define KSE_SCHED_LOCK(curkse, kseg) \ - KSE_LOCK_ACQUIRE(curkse, &(kseg)->kg_lock) -#define KSE_SCHED_UNLOCK(curkse, kseg) \ - KSE_LOCK_RELEASE(curkse, &(kseg)->kg_lock) - -/* - * Waiting queue manipulation macros (using pqe link): - */ -#define KSE_WAITQ_REMOVE(kse, thrd) \ -do { \ - if (((thrd)->flags & THR_FLAGS_IN_WAITQ) != 0) { \ - TAILQ_REMOVE(&(kse)->k_schedq->sq_waitq, thrd, pqe); \ - (thrd)->flags &= ~THR_FLAGS_IN_WAITQ; \ - } \ -} while (0) -#define KSE_WAITQ_INSERT(kse, thrd) kse_waitq_insert(thrd) -#define KSE_WAITQ_FIRST(kse) TAILQ_FIRST(&(kse)->k_schedq->sq_waitq) - -#define KSE_WAKEUP(kse) kse_wakeup(&(kse)->k_kcb->kcb_kmbx) - -/* - * TailQ initialization values. - */ -#define TAILQ_INITIALIZER { NULL, NULL } - -/* - * lock initialization values. - */ -#define LCK_INITIALIZER { NULL, NULL, LCK_DEFAULT } - -struct pthread_mutex { - /* - * Lock for accesses to this structure. - */ - struct lock m_lock; - enum pthread_mutextype m_type; - int m_protocol; - TAILQ_HEAD(mutex_head, pthread) m_queue; - struct pthread *m_owner; - long m_flags; - int m_count; - int m_refcount; - - /* - * Used for priority inheritence and protection. - * - * m_prio - For priority inheritence, the highest active - * priority (threads locking the mutex inherit - * this priority). For priority protection, the - * ceiling priority of this mutex. - * m_saved_prio - mutex owners inherited priority before - * taking the mutex, restored when the owner - * unlocks the mutex. - */ - int m_prio; - int m_saved_prio; - - /* - * Link for list of all mutexes a thread currently owns. - */ - TAILQ_ENTRY(pthread_mutex) m_qe; -}; - -/* - * Flags for mutexes. - */ -#define MUTEX_FLAGS_PRIVATE 0x01 -#define MUTEX_FLAGS_INITED 0x02 -#define MUTEX_FLAGS_BUSY 0x04 - -/* - * Static mutex initialization values. - */ -#define PTHREAD_MUTEX_STATIC_INITIALIZER \ - { LCK_INITIALIZER, PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, \ - TAILQ_INITIALIZER, NULL, MUTEX_FLAGS_PRIVATE, 0, 0, 0, 0, \ - TAILQ_INITIALIZER } - -struct pthread_mutex_attr { - enum pthread_mutextype m_type; - int m_protocol; - int m_ceiling; - long m_flags; -}; - -#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ - { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } - -/* - * Condition variable definitions. - */ -enum pthread_cond_type { - COND_TYPE_FAST, - COND_TYPE_MAX -}; - -struct pthread_cond { - /* - * Lock for accesses to this structure. - */ - struct lock c_lock; - enum pthread_cond_type c_type; - TAILQ_HEAD(cond_head, pthread) c_queue; - struct pthread_mutex *c_mutex; - long c_flags; - long c_seqno; -}; - -struct pthread_cond_attr { - enum pthread_cond_type c_type; - long c_flags; -}; - -struct pthread_barrier { - pthread_mutex_t b_lock; - pthread_cond_t b_cond; - int b_count; - int b_waiters; - int b_generation; -}; - -struct pthread_barrierattr { - int pshared; -}; - -struct pthread_spinlock { - volatile int s_lock; - pthread_t s_owner; -}; - -/* - * Flags for condition variables. - */ -#define COND_FLAGS_PRIVATE 0x01 -#define COND_FLAGS_INITED 0x02 -#define COND_FLAGS_BUSY 0x04 - -/* - * Static cond initialization values. - */ -#define PTHREAD_COND_STATIC_INITIALIZER \ - { LCK_INITIALIZER, COND_TYPE_FAST, TAILQ_INITIALIZER, \ - NULL, NULL, 0, 0 } - -/* - * Cleanup definitions. - */ -struct pthread_cleanup { - struct pthread_cleanup *next; - void (*routine) (void *); - void *routine_arg; - int onstack; -}; - -#define THR_CLEANUP_PUSH(td, func, arg) { \ - struct pthread_cleanup __cup; \ - \ - __cup.routine = func; \ - __cup.routine_arg = arg; \ - __cup.onstack = 1; \ - __cup.next = (td)->cleanup; \ - (td)->cleanup = &__cup; - -#define THR_CLEANUP_POP(td, exec) \ - (td)->cleanup = __cup.next; \ - if ((exec) != 0) \ - __cup.routine(__cup.routine_arg); \ -} - -struct pthread_atfork { - TAILQ_ENTRY(pthread_atfork) qe; - void (*prepare)(void); - void (*parent)(void); - void (*child)(void); -}; - -struct pthread_attr { - int sched_policy; - int sched_inherit; - int sched_interval; - int prio; - int suspend; -#define THR_STACK_USER 0x100 /* 0xFF reserved for <pthread.h> */ -#define THR_SIGNAL_THREAD 0x200 /* This is a signal thread */ - int flags; - void *arg_attr; - void (*cleanup_attr) (void *); - void *stackaddr_attr; - size_t stacksize_attr; - size_t guardsize_attr; -}; - -/* - * Thread creation state attributes. - */ -#define THR_CREATE_RUNNING 0 -#define THR_CREATE_SUSPENDED 1 - -/* - * Miscellaneous definitions. - */ -#define THR_STACK32_DEFAULT (1 * 1024 * 1024) -#define THR_STACK64_DEFAULT (2 * 1024 * 1024) - -/* - * Maximum size of initial thread's stack. This perhaps deserves to be larger - * than the stacks of other threads, since many applications are likely to run - * almost entirely on this stack. - */ -#define THR_STACK32_INITIAL (2 * 1024 * 1024) -#define THR_STACK64_INITIAL (4 * 1024 * 1024) - -/* - * Define the different priority ranges. All applications have thread - * priorities constrained within 0-31. The threads library raises the - * priority when delivering signals in order to ensure that signal - * delivery happens (from the POSIX spec) "as soon as possible". - * In the future, the threads library will also be able to map specific - * threads into real-time (cooperating) processes or kernel threads. - * The RT and SIGNAL priorities will be used internally and added to - * thread base priorities so that the scheduling queue can handle both - * normal and RT priority threads with and without signal handling. - * - * The approach taken is that, within each class, signal delivery - * always has priority over thread execution. - */ -#define THR_DEFAULT_PRIORITY 15 -#define THR_MIN_PRIORITY 0 -#define THR_MAX_PRIORITY 31 /* 0x1F */ -#define THR_SIGNAL_PRIORITY 32 /* 0x20 */ -#define THR_RT_PRIORITY 64 /* 0x40 */ -#define THR_FIRST_PRIORITY THR_MIN_PRIORITY -#define THR_LAST_PRIORITY \ - (THR_MAX_PRIORITY + THR_SIGNAL_PRIORITY + THR_RT_PRIORITY) -#define THR_BASE_PRIORITY(prio) ((prio) & THR_MAX_PRIORITY) - -/* - * Clock resolution in microseconds. - */ -#define CLOCK_RES_USEC 10000 - -/* - * Time slice period in microseconds. - */ -#define TIMESLICE_USEC 20000 - -/* - * XXX - Define a thread-safe macro to get the current time of day - * which is updated at regular intervals by something. - * - * For now, we just make the system call to get the time. - */ -#define KSE_GET_TOD(curkse, tsp) \ -do { \ - *tsp = (curkse)->k_kcb->kcb_kmbx.km_timeofday; \ - if ((tsp)->tv_sec == 0) \ - clock_gettime(CLOCK_REALTIME, tsp); \ -} while (0) - -struct pthread_rwlockattr { - int pshared; -}; - -struct pthread_rwlock { - pthread_mutex_t lock; /* monitor lock */ - pthread_cond_t read_signal; - pthread_cond_t write_signal; - int state; /* 0 = idle >0 = # of readers -1 = writer */ - int blocked_writers; -}; - -/* - * Thread states. - */ -enum pthread_state { - PS_RUNNING, - PS_LOCKWAIT, - PS_MUTEX_WAIT, - PS_COND_WAIT, - PS_SLEEP_WAIT, - PS_SIGSUSPEND, - PS_SIGWAIT, - PS_JOIN, - PS_SUSPENDED, - PS_DEAD, - PS_DEADLOCK, - PS_STATE_MAX -}; - -struct sigwait_data { - sigset_t *waitset; - siginfo_t *siginfo; /* used to save siginfo for sigwaitinfo() */ -}; - -union pthread_wait_data { - pthread_mutex_t mutex; - pthread_cond_t cond; - struct lock *lock; - struct sigwait_data *sigwait; -}; - -/* - * Define a continuation routine that can be used to perform a - * transfer of control: - */ -typedef void (*thread_continuation_t) (void *); - -/* - * This stores a thread's state prior to running a signal handler. - * It is used when a signal is delivered to a thread blocked in - * userland. If the signal handler returns normally, the thread's - * state is restored from here. - */ -struct pthread_sigframe { - int psf_valid; - int psf_flags; - int psf_cancelflags; - int psf_interrupted; - int psf_timeout; - int psf_signo; - enum pthread_state psf_state; - union pthread_wait_data psf_wait_data; - struct timespec psf_wakeup_time; - sigset_t psf_sigset; - sigset_t psf_sigmask; - int psf_seqno; - thread_continuation_t psf_continuation; -}; - -struct join_status { - struct pthread *thread; - void *ret; - int error; -}; - -struct pthread_specific_elem { - const void *data; - int seqno; -}; - -struct pthread_key { - volatile int allocated; - volatile int count; - int seqno; - void (*destructor) (void *); -}; - -#define MAX_THR_LOCKLEVEL 5 -/* - * Thread structure. - */ -struct pthread { - /* Thread control block */ - struct tcb *tcb; - - /* - * Magic value to help recognize a valid thread structure - * from an invalid one: - */ -#define THR_MAGIC ((u_int32_t) 0xd09ba115) - u_int32_t magic; - char *name; - u_int64_t uniqueid; /* for gdb */ - - /* Queue entry for list of all threads: */ - TAILQ_ENTRY(pthread) tle; /* link for all threads in process */ - TAILQ_ENTRY(pthread) kle; /* link for all threads in KSE/KSEG */ - - /* Queue entry for GC lists: */ - TAILQ_ENTRY(pthread) gcle; - - /* Hash queue entry */ - LIST_ENTRY(pthread) hle; - - /* - * Lock for accesses to this thread structure. - */ - struct lock lock; - struct lockuser lockusers[MAX_THR_LOCKLEVEL]; - int locklevel; - kse_critical_t critical[MAX_KSE_LOCKLEVEL]; - struct kse *kse; - struct kse_group *kseg; - - /* - * Thread start routine, argument, stack pointer and thread - * attributes. - */ - void *(*start_routine)(void *); - void *arg; - struct pthread_attr attr; - - int active; /* thread running */ - int blocked; /* thread blocked in kernel */ - int need_switchout; - - /* - * Used for tracking delivery of signal handlers. - */ - siginfo_t *siginfo; - thread_continuation_t sigbackout; - - /* - * Cancelability flags - the lower 2 bits are used by cancel - * definitions in pthread.h - */ -#define THR_AT_CANCEL_POINT 0x0004 -#define THR_CANCELLING 0x0008 -#define THR_CANCEL_NEEDED 0x0010 - int cancelflags; - - thread_continuation_t continuation; - - /* - * The thread's base and pending signal masks. The active - * signal mask is stored in the thread's context (in mailbox). - */ - sigset_t sigmask; - sigset_t sigpend; - sigset_t *oldsigmask; - volatile int check_pending; - int refcount; - - /* Thread state: */ - enum pthread_state state; - volatile int lock_switch; - - /* - * Number of microseconds accumulated by this thread when - * time slicing is active. - */ - long slice_usec; - - /* - * Time to wake up thread. This is used for sleeping threads and - * for any operation which may time out (such as select). - */ - struct timespec wakeup_time; - - /* TRUE if operation has timed out. */ - int timeout; - - /* - * Error variable used instead of errno. The function __error() - * returns a pointer to this. - */ - int error; - - /* - * The joiner is the thread that is joining to this thread. The - * join status keeps track of a join operation to another thread. - */ - struct pthread *joiner; - struct join_status join_status; - - /* - * The current thread can belong to only one scheduling queue at - * a time (ready or waiting queue). It can also belong to: - * - * o A queue of threads waiting for a mutex - * o A queue of threads waiting for a condition variable - * - * It is possible for a thread to belong to more than one of the - * above queues if it is handling a signal. A thread may only - * enter a mutex or condition variable queue when it is not - * being called from a signal handler. If a thread is a member - * of one of these queues when a signal handler is invoked, it - * must be removed from the queue before invoking the handler - * and then added back to the queue after return from the handler. - * - * Use pqe for the scheduling queue link (both ready and waiting), - * sqe for synchronization (mutex, condition variable, and join) - * queue links, and qe for all other links. - */ - TAILQ_ENTRY(pthread) pqe; /* priority, wait queues link */ - TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */ - - /* Wait data. */ - union pthread_wait_data data; - - /* - * Set to TRUE if a blocking operation was - * interrupted by a signal: - */ - int interrupted; - - /* - * Set to non-zero when this thread has entered a critical - * region. We allow for recursive entries into critical regions. - */ - int critical_count; - - /* - * Set to TRUE if this thread should yield after leaving a - * critical region to check for signals, messages, etc. - */ - int critical_yield; - - int sflags; -#define THR_FLAGS_IN_SYNCQ 0x0001 - - /* Miscellaneous flags; only set with scheduling lock held. */ - int flags; -#define THR_FLAGS_PRIVATE 0x0001 -#define THR_FLAGS_IN_WAITQ 0x0002 /* in waiting queue using pqe link */ -#define THR_FLAGS_IN_RUNQ 0x0004 /* in run queue using pqe link */ -#define THR_FLAGS_EXITING 0x0008 /* thread is exiting */ -#define THR_FLAGS_SUSPENDED 0x0010 /* thread is suspended */ - - /* Thread list flags; only set with thread list lock held. */ -#define TLFLAGS_GC_SAFE 0x0001 /* thread safe for cleaning */ -#define TLFLAGS_IN_TDLIST 0x0002 /* thread in all thread list */ -#define TLFLAGS_IN_GCLIST 0x0004 /* thread in gc list */ - int tlflags; - - /* - * Base priority is the user setable and retrievable priority - * of the thread. It is only affected by explicit calls to - * set thread priority and upon thread creation via a thread - * attribute or default priority. - */ - char base_priority; - - /* - * Inherited priority is the priority a thread inherits by - * taking a priority inheritence or protection mutex. It - * is not affected by base priority changes. Inherited - * priority defaults to and remains 0 until a mutex is taken - * that is being waited on by any other thread whose priority - * is non-zero. - */ - char inherited_priority; - - /* - * Active priority is always the maximum of the threads base - * priority and inherited priority. When there is a change - * in either the base or inherited priority, the active - * priority must be recalculated. - */ - char active_priority; - - /* Number of priority ceiling or protection mutexes owned. */ - int priority_mutex_count; - - /* Number rwlocks rdlocks held. */ - int rdlock_count; - - /* - * Queue of currently owned mutexes. - */ - TAILQ_HEAD(, pthread_mutex) mutexq; - - void *ret; - struct pthread_specific_elem *specific; - int specific_data_count; - - /* Alternative stack for sigaltstack() */ - stack_t sigstk; - - /* - * Current locks bitmap for rtld. - */ - int rtld_bits; - - /* Cleanup handlers Link List */ - struct pthread_cleanup *cleanup; - char *fname; /* Ptr to source file name */ - int lineno; /* Source line number. */ -}; - -/* - * Critical regions can also be detected by looking at the threads - * current lock level. Ensure these macros increment and decrement - * the lock levels such that locks can not be held with a lock level - * of 0. - */ -#define THR_IN_CRITICAL(thrd) \ - (((thrd)->locklevel > 0) || \ - ((thrd)->critical_count > 0)) - -#define THR_YIELD_CHECK(thrd) \ -do { \ - if (!THR_IN_CRITICAL(thrd)) { \ - if (__predict_false(_libkse_debug)) \ - _thr_debug_check_yield(thrd); \ - if ((thrd)->critical_yield != 0) \ - _thr_sched_switch(thrd); \ - if ((thrd)->check_pending != 0) \ - _thr_sig_check_pending(thrd); \ - } \ -} while (0) - -#define THR_LOCK_ACQUIRE(thrd, lck) \ -do { \ - if ((thrd)->locklevel < MAX_THR_LOCKLEVEL) { \ - THR_DEACTIVATE_LAST_LOCK(thrd); \ - (thrd)->locklevel++; \ - _lock_acquire((lck), \ - &(thrd)->lockusers[(thrd)->locklevel - 1], \ - (thrd)->active_priority); \ - } else \ - PANIC("Exceeded maximum lock level"); \ -} while (0) - -#define THR_LOCK_RELEASE(thrd, lck) \ -do { \ - if ((thrd)->locklevel > 0) { \ - _lock_release((lck), \ - &(thrd)->lockusers[(thrd)->locklevel - 1]); \ - (thrd)->locklevel--; \ - THR_ACTIVATE_LAST_LOCK(thrd); \ - if ((thrd)->locklevel == 0) \ - THR_YIELD_CHECK(thrd); \ - } \ -} while (0) - -#define THR_ACTIVATE_LAST_LOCK(thrd) \ -do { \ - if ((thrd)->locklevel > 0) \ - _lockuser_setactive( \ - &(thrd)->lockusers[(thrd)->locklevel - 1], 1); \ -} while (0) - -#define THR_DEACTIVATE_LAST_LOCK(thrd) \ -do { \ - if ((thrd)->locklevel > 0) \ - _lockuser_setactive( \ - &(thrd)->lockusers[(thrd)->locklevel - 1], 0); \ -} while (0) - -/* - * For now, threads will have their own lock separate from their - * KSE scheduling lock. - */ -#define THR_LOCK(thr) THR_LOCK_ACQUIRE(thr, &(thr)->lock) -#define THR_UNLOCK(thr) THR_LOCK_RELEASE(thr, &(thr)->lock) -#define THR_THREAD_LOCK(curthrd, thr) THR_LOCK_ACQUIRE(curthrd, &(thr)->lock) -#define THR_THREAD_UNLOCK(curthrd, thr) THR_LOCK_RELEASE(curthrd, &(thr)->lock) - -/* - * Priority queue manipulation macros (using pqe link). We use - * the thread's kseg link instead of the kse link because a thread - * does not (currently) have a statically assigned kse. - */ -#define THR_RUNQ_INSERT_HEAD(thrd) \ - _pq_insert_head(&(thrd)->kseg->kg_schedq.sq_runq, thrd) -#define THR_RUNQ_INSERT_TAIL(thrd) \ - _pq_insert_tail(&(thrd)->kseg->kg_schedq.sq_runq, thrd) -#define THR_RUNQ_REMOVE(thrd) \ - _pq_remove(&(thrd)->kseg->kg_schedq.sq_runq, thrd) - -/* - * Macros to insert/remove threads to the all thread list and - * the gc list. - */ -#define THR_LIST_ADD(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) == 0) { \ - TAILQ_INSERT_HEAD(&_thread_list, thrd, tle); \ - _thr_hash_add(thrd); \ - (thrd)->tlflags |= TLFLAGS_IN_TDLIST; \ - } \ -} while (0) -#define THR_LIST_REMOVE(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) != 0) { \ - TAILQ_REMOVE(&_thread_list, thrd, tle); \ - _thr_hash_remove(thrd); \ - (thrd)->tlflags &= ~TLFLAGS_IN_TDLIST; \ - } \ -} while (0) -#define THR_GCLIST_ADD(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) == 0) { \ - TAILQ_INSERT_HEAD(&_thread_gc_list, thrd, gcle);\ - (thrd)->tlflags |= TLFLAGS_IN_GCLIST; \ - _gc_count++; \ - } \ -} while (0) -#define THR_GCLIST_REMOVE(thrd) do { \ - if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) != 0) { \ - TAILQ_REMOVE(&_thread_gc_list, thrd, gcle); \ - (thrd)->tlflags &= ~TLFLAGS_IN_GCLIST; \ - _gc_count--; \ - } \ -} while (0) - -#define GC_NEEDED() (atomic_load_acq_int(&_gc_count) >= 5) - -/* - * Locking the scheduling queue for another thread uses that thread's - * KSEG lock. - */ -#define THR_SCHED_LOCK(curthr, thr) do { \ - (curthr)->critical[(curthr)->locklevel] = _kse_critical_enter(); \ - (curthr)->locklevel++; \ - KSE_SCHED_LOCK((curthr)->kse, (thr)->kseg); \ -} while (0) - -#define THR_SCHED_UNLOCK(curthr, thr) do { \ - KSE_SCHED_UNLOCK((curthr)->kse, (thr)->kseg); \ - (curthr)->locklevel--; \ - _kse_critical_leave((curthr)->critical[(curthr)->locklevel]); \ -} while (0) - -/* Take the scheduling lock with the intent to call the scheduler. */ -#define THR_LOCK_SWITCH(curthr) do { \ - (void)_kse_critical_enter(); \ - KSE_SCHED_LOCK((curthr)->kse, (curthr)->kseg); \ -} while (0) -#define THR_UNLOCK_SWITCH(curthr) do { \ - KSE_SCHED_UNLOCK((curthr)->kse, (curthr)->kseg);\ -} while (0) - -#define THR_CRITICAL_ENTER(thr) (thr)->critical_count++ -#define THR_CRITICAL_LEAVE(thr) do { \ - (thr)->critical_count--; \ - if (((thr)->critical_yield != 0) && \ - ((thr)->critical_count == 0)) { \ - (thr)->critical_yield = 0; \ - _thr_sched_switch(thr); \ - } \ -} while (0) - -#define THR_IS_ACTIVE(thrd) \ - ((thrd)->kse != NULL) && ((thrd)->kse->k_curthread == (thrd)) - -#define THR_IN_SYNCQ(thrd) (((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0) - -#define THR_IS_SUSPENDED(thrd) \ - (((thrd)->state == PS_SUSPENDED) || \ - (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0)) -#define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 0) -#define DBG_CAN_RUN(thrd) (((thrd)->tcb->tcb_tmbx.tm_dflags & \ - TMDF_SUSPEND) == 0) - -extern int __isthreaded; - -static inline int -_kse_isthreaded(void) -{ - return (__isthreaded != 0); -} - -/* - * Global variables for the pthread kernel. - */ - -SCLASS void *_usrstack SCLASS_PRESET(NULL); -SCLASS struct kse *_kse_initial SCLASS_PRESET(NULL); -SCLASS struct pthread *_thr_initial SCLASS_PRESET(NULL); -/* For debugger */ -SCLASS int _libkse_debug SCLASS_PRESET(0); -SCLASS int _thread_activated SCLASS_PRESET(0); -SCLASS int _thread_scope_system SCLASS_PRESET(0); - -/* List of all threads: */ -SCLASS TAILQ_HEAD(, pthread) _thread_list - SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_list)); - -/* List of threads needing GC: */ -SCLASS TAILQ_HEAD(, pthread) _thread_gc_list - SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_gc_list)); - -SCLASS int _thread_active_threads SCLASS_PRESET(1); - -SCLASS TAILQ_HEAD(atfork_head, pthread_atfork) _thr_atfork_list; -SCLASS pthread_mutex_t _thr_atfork_mutex; - -/* Default thread attributes: */ -SCLASS struct pthread_attr _pthread_attr_default - SCLASS_PRESET({ - SCHED_RR, 0, TIMESLICE_USEC, THR_DEFAULT_PRIORITY, - THR_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, - NULL, NULL, /* stacksize */0, /* guardsize */0 - }); - -/* Default mutex attributes: */ -SCLASS struct pthread_mutex_attr _pthread_mutexattr_default - SCLASS_PRESET({PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }); - -/* Default condition variable attributes: */ -SCLASS struct pthread_cond_attr _pthread_condattr_default - SCLASS_PRESET({COND_TYPE_FAST, 0}); - -/* Clock resolution in usec. */ -SCLASS int _clock_res_usec SCLASS_PRESET(CLOCK_RES_USEC); - -/* Array of signal actions for this process: */ -SCLASS struct sigaction _thread_sigact[_SIG_MAXSIG]; - -/* - * Lock for above count of dummy handlers and for the process signal - * mask and pending signal sets. - */ -SCLASS struct lock _thread_signal_lock; - -/* Pending signals and mask for this process: */ -SCLASS sigset_t _thr_proc_sigpending; -SCLASS siginfo_t _thr_proc_siginfo[_SIG_MAXSIG]; - -SCLASS pid_t _thr_pid SCLASS_PRESET(0); - -/* Garbage collector lock. */ -SCLASS struct lock _gc_lock; -SCLASS int _gc_check SCLASS_PRESET(0); -SCLASS int _gc_count SCLASS_PRESET(0); - -SCLASS struct lock _mutex_static_lock; -SCLASS struct lock _rwlock_static_lock; -SCLASS struct lock _keytable_lock; -SCLASS struct lock _thread_list_lock; -SCLASS int _thr_guard_default; -SCLASS int _thr_stack_default; -SCLASS int _thr_stack_initial; -SCLASS int _thr_page_size; -SCLASS pthread_t _thr_sig_daemon; -SCLASS int _thr_debug_flags SCLASS_PRESET(0); - -/* Undefine the storage class and preset specifiers: */ -#undef SCLASS -#undef SCLASS_PRESET - - -/* - * Function prototype definitions. - */ -__BEGIN_DECLS -int _cond_reinit(pthread_cond_t *); -struct kse *_kse_alloc(struct pthread *, int sys_scope); -kse_critical_t _kse_critical_enter(void); -void _kse_critical_leave(kse_critical_t); -int _kse_in_critical(void); -void _kse_free(struct pthread *, struct kse *); -void _kse_init(void); -struct kse_group *_kseg_alloc(struct pthread *); -void _kse_lock_wait(struct lock *, struct lockuser *lu); -void _kse_lock_wakeup(struct lock *, struct lockuser *lu); -void _kse_single_thread(struct pthread *); -int _kse_setthreaded(int); -void _kseg_free(struct kse_group *); -int _mutex_cv_lock(pthread_mutex_t *); -int _mutex_cv_unlock(pthread_mutex_t *); -void _mutex_notify_priochange(struct pthread *, struct pthread *, int); -int _mutex_reinit(struct pthread_mutex *); -void _mutex_unlock_private(struct pthread *); -void _libpthread_init(struct pthread *); -int _pq_alloc(struct pq_queue *, int, int); -void _pq_free(struct pq_queue *); -int _pq_init(struct pq_queue *); -void _pq_remove(struct pq_queue *pq, struct pthread *); -void _pq_insert_head(struct pq_queue *pq, struct pthread *); -void _pq_insert_tail(struct pq_queue *pq, struct pthread *); -struct pthread *_pq_first(struct pq_queue *pq); -struct pthread *_pq_first_debug(struct pq_queue *pq); -void *_pthread_getspecific(pthread_key_t); -int _pthread_key_create(pthread_key_t *, void (*) (void *)); -int _pthread_key_delete(pthread_key_t); -int _pthread_mutex_destroy(pthread_mutex_t *); -int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); -int _pthread_mutex_lock(pthread_mutex_t *); -int _pthread_mutex_trylock(pthread_mutex_t *); -int _pthread_mutex_unlock(pthread_mutex_t *); -int _pthread_mutexattr_init(pthread_mutexattr_t *); -int _pthread_mutexattr_destroy(pthread_mutexattr_t *); -int _pthread_mutexattr_settype(pthread_mutexattr_t *, int); -int _pthread_once(pthread_once_t *, void (*) (void)); -int _pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); -int _pthread_rwlock_destroy (pthread_rwlock_t *); -struct pthread *_pthread_self(void); -int _pthread_setspecific(pthread_key_t, const void *); -void _pthread_yield(void); -void _pthread_cleanup_push(void (*routine) (void *), void *routine_arg); -void _pthread_cleanup_pop(int execute); -struct pthread *_thr_alloc(struct pthread *); -void _thr_exit(char *, int, char *); -void _thr_exit_cleanup(void); -void _thr_lock_wait(struct lock *lock, struct lockuser *lu); -void _thr_lock_wakeup(struct lock *lock, struct lockuser *lu); -void _thr_mutex_reinit(pthread_mutex_t *); -int _thr_ref_add(struct pthread *, struct pthread *, int); -void _thr_ref_delete(struct pthread *, struct pthread *); -void _thr_rtld_init(void); -void _thr_rtld_fini(void); -int _thr_schedule_add(struct pthread *, struct pthread *); -void _thr_schedule_remove(struct pthread *, struct pthread *); -void _thr_setrunnable(struct pthread *curthread, struct pthread *thread); -struct kse_mailbox *_thr_setrunnable_unlocked(struct pthread *thread); -struct kse_mailbox *_thr_sig_add(struct pthread *, int, siginfo_t *); -void _thr_sig_dispatch(struct kse *, int, siginfo_t *); -int _thr_stack_alloc(struct pthread_attr *); -void _thr_stack_free(struct pthread_attr *); -void _thr_exit_cleanup(void); -void _thr_free(struct pthread *, struct pthread *); -void _thr_gc(struct pthread *); -void _thr_panic_exit(char *, int, char *); -void _thread_cleanupspecific(void); -void _thread_dump_info(void); -void _thread_printf(int, const char *, ...); -void _thr_sched_switch(struct pthread *); -void _thr_sched_switch_unlocked(struct pthread *); -void _thr_set_timeout(const struct timespec *); -void _thr_seterrno(struct pthread *, int); -void _thr_sig_handler(int, siginfo_t *, ucontext_t *); -void _thr_sig_check_pending(struct pthread *); -void _thr_sig_rundown(struct pthread *, ucontext_t *); -void _thr_sig_send(struct pthread *pthread, int sig); -void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf); -void _thr_spinlock_init(void); -void _thr_cancel_enter(struct pthread *); -void _thr_cancel_leave(struct pthread *, int); -int _thr_setconcurrency(int new_level); -int _thr_setmaxconcurrency(void); -void _thr_critical_enter(struct pthread *); -void _thr_critical_leave(struct pthread *); -int _thr_start_sig_daemon(void); -int _thr_getprocsig(int sig, siginfo_t *siginfo); -int _thr_getprocsig_unlocked(int sig, siginfo_t *siginfo); -void _thr_signal_init(void); -void _thr_signal_deinit(void); -void _thr_hash_add(struct pthread *); -void _thr_hash_remove(struct pthread *); -struct pthread *_thr_hash_find(struct pthread *); -void _thr_finish_cancellation(void *arg); -int _thr_sigonstack(void *sp); -void _thr_debug_check_yield(struct pthread *); - -/* - * Aliases for _pthread functions. Should be called instead of - * originals if PLT replocation is unwanted at runtme. - */ -int _thr_cond_broadcast(pthread_cond_t *); -int _thr_cond_signal(pthread_cond_t *); -int _thr_cond_wait(pthread_cond_t *, pthread_mutex_t *); -int _thr_mutex_lock(pthread_mutex_t *); -int _thr_mutex_unlock(pthread_mutex_t *); -int _thr_rwlock_rdlock (pthread_rwlock_t *); -int _thr_rwlock_wrlock (pthread_rwlock_t *); -int _thr_rwlock_unlock (pthread_rwlock_t *); - -/* #include <sys/aio.h> */ -#ifdef _SYS_AIO_H_ -int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); -#endif - -/* #include <fcntl.h> */ -#ifdef _SYS_FCNTL_H_ -int __sys_fcntl(int, int, ...); -int __sys_open(const char *, int, ...); -#endif - -/* #include <sys/ioctl.h> */ -#ifdef _SYS_IOCTL_H_ -int __sys_ioctl(int, unsigned long, ...); -#endif - -/* #inclde <sched.h> */ -#ifdef _SCHED_H_ -int __sys_sched_yield(void); -#endif - -/* #include <signal.h> */ -#ifdef _SIGNAL_H_ -int __sys_kill(pid_t, int); -int __sys_sigaction(int, const struct sigaction *, struct sigaction *); -int __sys_sigpending(sigset_t *); -int __sys_sigprocmask(int, const sigset_t *, sigset_t *); -int __sys_sigsuspend(const sigset_t *); -int __sys_sigreturn(ucontext_t *); -int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); -#endif - -/* #include <sys/socket.h> */ -#ifdef _SYS_SOCKET_H_ -int __sys_accept(int, struct sockaddr *, socklen_t *); -int __sys_connect(int, const struct sockaddr *, socklen_t); -int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, - off_t *, int); -#endif - -/* #include <sys/uio.h> */ -#ifdef _SYS_UIO_H_ -ssize_t __sys_readv(int, const struct iovec *, int); -ssize_t __sys_writev(int, const struct iovec *, int); -#endif - -/* #include <time.h> */ -#ifdef _TIME_H_ -int __sys_nanosleep(const struct timespec *, struct timespec *); -#endif - -/* #include <unistd.h> */ -#ifdef _UNISTD_H_ -int __sys_close(int); -int __sys_execve(const char *, char * const *, char * const *); -int __sys_fork(void); -int __sys_fsync(int); -pid_t __sys_getpid(void); -int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); -ssize_t __sys_read(int, void *, size_t); -ssize_t __sys_write(int, const void *, size_t); -void __sys_exit(int); -int __sys_sigwait(const sigset_t *, int *); -int __sys_sigtimedwait(sigset_t *, siginfo_t *, struct timespec *); -#endif - -/* #include <poll.h> */ -#ifdef _SYS_POLL_H_ -int __sys_poll(struct pollfd *, unsigned, int); -#endif - -/* #include <sys/mman.h> */ -#ifdef _SYS_MMAN_H_ -int __sys_msync(void *, size_t, int); -#endif - -static __inline int -_thr_dump_enabled(void) -{ - - return ((_thr_debug_flags & DBG_INFO_DUMP) != 0); -} - -#endif /* !_THR_PRIVATE_H */ diff --git a/lib/libpthread/thread/thr_pselect.c b/lib/libpthread/thread/thr_pselect.c deleted file mode 100644 index a0e9410..0000000 --- a/lib/libpthread/thread/thr_pselect.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2002 Daniel M. 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. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/select.h> -#include <sys/time.h> - -#include <errno.h> -#include <signal.h> -#include <pthread.h> - -#include "thr_private.h" - -extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask); - -LT10_COMPAT_PRIVATE(_pselect); -LT10_COMPAT_DEFAULT(pselect); - -__weak_reference(_pselect, pselect); - -int -_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, - const struct timespec *timo, const sigset_t *mask) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __pselect(count, rfds, wfds, efds, timo, mask); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_pspinlock.c b/lib/libpthread/thread/thr_pspinlock.c deleted file mode 100644 index 5836fde..0000000 --- a/lib/libpthread/thread/thr_pspinlock.c +++ /dev/null @@ -1,174 +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 <sys/types.h> -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <stdlib.h> - -#include "atomic_ops.h" -#include "thr_private.h" - -#define SPIN_COUNT 10000 - -LT10_COMPAT_PRIVATE(_pthread_spin_init); -LT10_COMPAT_DEFAULT(pthread_spin_init); -LT10_COMPAT_PRIVATE(_pthread_spin_destroy); -LT10_COMPAT_DEFAULT(pthread_spin_destroy); -LT10_COMPAT_PRIVATE(_pthread_spin_trylock); -LT10_COMPAT_DEFAULT(pthread_spin_trylock); -LT10_COMPAT_PRIVATE(_pthread_spin_lock); -LT10_COMPAT_DEFAULT(pthread_spin_lock); -LT10_COMPAT_PRIVATE(_pthread_spin_unlock); -LT10_COMPAT_DEFAULT(pthread_spin_unlock); - -__weak_reference(_pthread_spin_init, pthread_spin_init); -__weak_reference(_pthread_spin_destroy, pthread_spin_destroy); -__weak_reference(_pthread_spin_trylock, pthread_spin_trylock); -__weak_reference(_pthread_spin_lock, pthread_spin_lock); -__weak_reference(_pthread_spin_unlock, pthread_spin_unlock); - -int -_pthread_spin_init(pthread_spinlock_t *lock, int pshared) -{ - struct pthread_spinlock *lck; - int ret; - - if (lock == NULL || pshared != PTHREAD_PROCESS_PRIVATE) - ret = EINVAL; - else if ((lck = malloc(sizeof(struct pthread_spinlock))) == NULL) - ret = ENOMEM; - else { - lck->s_lock = 0; - lck->s_owner= NULL; - *lock = lck; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_destroy(pthread_spinlock_t *lock) -{ - int ret; - - if (lock == NULL || *lock == NULL) - ret = EINVAL; - else if ((*lock)->s_owner != NULL) - ret = EBUSY; - else { - free(*lock); - *lock = NULL; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_trylock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - struct pthread *self = _pthread_self(); - int oldval, ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else if (lck->s_owner == self) - ret = EDEADLK; - else if (lck->s_lock != 0) - ret = EBUSY; - else { - atomic_swap_int((int *)&(lck)->s_lock, 1, &oldval); - if (oldval) - ret = EBUSY; - else { - lck->s_owner = _pthread_self(); - ret = 0; - } - } - return (ret); -} - -int -_pthread_spin_lock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - struct pthread *self = _pthread_self(); - int count, oldval, ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else if (lck->s_owner == self) - ret = EDEADLK; - else { - do { - count = SPIN_COUNT; - while (lck->s_lock) { -#ifdef __i386__ - /* tell cpu we are spinning */ - __asm __volatile("pause"); -#endif - if (--count <= 0) { - count = SPIN_COUNT; - _pthread_yield(); - } - } - atomic_swap_int((int *)&(lck)->s_lock, 1, &oldval); - } while (oldval); - - lck->s_owner = self; - ret = 0; - } - - return (ret); -} - -int -_pthread_spin_unlock(pthread_spinlock_t *lock) -{ - struct pthread_spinlock *lck; - int ret; - - if (lock == NULL || (lck = *lock) == NULL) - ret = EINVAL; - else { - if (lck->s_owner != _pthread_self()) - ret = EPERM; - else { - lck->s_owner = NULL; - atomic_swap_int((int *)&lck->s_lock, 0, &ret); - ret = 0; - } - } - - return (ret); -} - diff --git a/lib/libpthread/thread/thr_raise.c b/lib/libpthread/thread/thr_raise.c deleted file mode 100644 index ad4aa39..0000000 --- a/lib/libpthread/thread/thr_raise.c +++ /dev/null @@ -1,56 +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 <pthread.h> -#include <errno.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_raise); -LT10_COMPAT_DEFAULT(raise); - -__weak_reference(_raise, raise); - -int -_raise(int sig) -{ - int ret; - - if (!_kse_isthreaded()) - ret = kill(getpid(), sig); - else { - ret = pthread_kill(pthread_self(), sig); - if (ret != 0) { - errno = ret; - ret = -1; - } - } - return (ret); -} diff --git a/lib/libpthread/thread/thr_read.c b/lib/libpthread/thread/thr_read.c deleted file mode 100644 index 8fd349a..0000000 --- a/lib/libpthread/thread/thr_read.c +++ /dev/null @@ -1,56 +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 <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__read); -LT10_COMPAT_DEFAULT(read); - -__weak_reference(__read, read); - -ssize_t -__read(int fd, void *buf, size_t nbytes) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_read(fd, buf, nbytes); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_readv.c b/lib/libpthread/thread/thr_readv.c deleted file mode 100644 index 46b08dc..0000000 --- a/lib/libpthread/thread/thr_readv.c +++ /dev/null @@ -1,56 +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 <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__readv); -LT10_COMPAT_DEFAULT(readv); - -__weak_reference(__readv, readv); - -ssize_t -__readv(int fd, const struct iovec *iov, int iovcnt) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_readv(fd, iov, iovcnt); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_resume_np.c b/lib/libpthread/thread/thr_resume_np.c deleted file mode 100644 index eb7bcf3..0000000 --- a/lib/libpthread/thread/thr_resume_np.c +++ /dev/null @@ -1,109 +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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -static struct kse_mailbox *resume_common(struct pthread *); - -LT10_COMPAT_PRIVATE(_pthread_resume_np); -LT10_COMPAT_DEFAULT(pthread_resume_np); -LT10_COMPAT_PRIVATE(_pthread_resume_all_np); -LT10_COMPAT_DEFAULT(pthread_resume_all_np); - -__weak_reference(_pthread_resume_np, pthread_resume_np); -__weak_reference(_pthread_resume_all_np, pthread_resume_all_np); - - -/* Resume a thread: */ -int -_pthread_resume_np(pthread_t thread) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx; - int ret; - - /* Add a reference to the thread: */ - if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) == 0) { - /* Lock the threads scheduling queue: */ - THR_SCHED_LOCK(curthread, thread); - kmbx = resume_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - _thr_ref_delete(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - return (ret); -} - -void -_pthread_resume_all_np(void) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *thread; - struct kse_mailbox *kmbx; - kse_critical_t crit; - - /* Take the thread list lock: */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - TAILQ_FOREACH(thread, &_thread_list, tle) { - if (thread != curthread) { - THR_SCHED_LOCK(curthread, thread); - kmbx = resume_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - } - } - - /* Release the thread list lock: */ - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -static struct kse_mailbox * -resume_common(struct pthread *thread) -{ - /* Clear the suspend flag: */ - thread->flags &= ~THR_FLAGS_SUSPENDED; - - /* - * If the thread's state is suspended, that means it is - * now runnable but not in any scheduling queue. Set the - * state to running and insert it into the run queue. - */ - if (thread->state == PS_SUSPENDED) - return (_thr_setrunnable_unlocked(thread)); - else - return (NULL); -} diff --git a/lib/libpthread/thread/thr_rtld.c b/lib/libpthread/thread/thr_rtld.c deleted file mode 100644 index e813073..0000000 --- a/lib/libpthread/thread/thr_rtld.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2001 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 - * in this position and unchanged. - * 2. Redistributions in binary form must 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$ - */ -#include <sys/cdefs.h> -#include <stdlib.h> - -#include "rtld_lock.h" -#include "thr_private.h" - -static int _thr_rtld_clr_flag(int); -static void *_thr_rtld_lock_create(void); -static void _thr_rtld_lock_destroy(void *); -static void _thr_rtld_lock_release(void *); -static void _thr_rtld_rlock_acquire(void *); -static int _thr_rtld_set_flag(int); -static void _thr_rtld_wlock_acquire(void *); - -#ifdef NOTYET -static void * -_thr_rtld_lock_create(void) -{ - pthread_rwlock_t prwlock; - if (_pthread_rwlock_init(&prwlock, NULL)) - return (NULL); - return (prwlock); -} - -static void -_thr_rtld_lock_destroy(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - if (prwlock != NULL) - _pthread_rwlock_destroy(&prwlock); -} - -static void -_thr_rtld_rlock_acquire(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_rdlock(&prwlock); -} - -static void -_thr_rtld_wlock_acquire(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_wrlock(&prwlock); -} - -static void -_thr_rtld_lock_release(void *lock) -{ - pthread_rwlock_t prwlock; - - prwlock = (pthread_rwlock_t)lock; - _thr_rwlock_unlock(&prwlock); -} - - -static int -_thr_rtld_set_flag(int mask) -{ - struct pthread *curthread; - int bits; - - curthread = _get_curthread(); - if (curthread != NULL) { - bits = curthread->rtld_bits; - curthread->rtld_bits |= mask; - } else { - bits = 0; - PANIC("No current thread in rtld call"); - } - - return (bits); -} - -static int -_thr_rtld_clr_flag(int mask) -{ - struct pthread *curthread; - int bits; - - curthread = _get_curthread(); - if (curthread != NULL) { - bits = curthread->rtld_bits; - curthread->rtld_bits &= ~mask; - } else { - bits = 0; - PANIC("No current thread in rtld call"); - } - return (bits); -} - -void -_thr_rtld_init(void) -{ - struct RtldLockInfo li; - - li.lock_create = _thr_rtld_lock_create; - li.lock_destroy = _thr_rtld_lock_destroy; - li.rlock_acquire = _thr_rtld_rlock_acquire; - li.wlock_acquire = _thr_rtld_wlock_acquire; - li.lock_release = _thr_rtld_lock_release; - li.thread_set_flag = _thr_rtld_set_flag; - li.thread_clr_flag = _thr_rtld_clr_flag; - li.at_fork = NULL; - _rtld_thread_init(&li); -} - -void -_thr_rtld_fini(void) -{ - _rtld_thread_init(NULL); -} -#endif - -struct rtld_kse_lock { - struct lock lck; - struct kse *owner; - kse_critical_t crit; - int count; - int write; -}; - -static void * -_thr_rtld_lock_create(void) -{ - struct rtld_kse_lock *l; - - if ((l = malloc(sizeof(struct rtld_kse_lock))) != NULL) { - _lock_init(&l->lck, LCK_ADAPTIVE, _kse_lock_wait, - _kse_lock_wakeup); - l->owner = NULL; - l->count = 0; - l->write = 0; - } - return (l); -} - -static void -_thr_rtld_lock_destroy(void *lock) -{ - /* XXX We really can not free memory after a fork() */ -#if 0 - struct rtld_kse_lock *l; - - l = (struct rtld_kse_lock *)lock; - _lock_destroy(&l->lck); - free(l); -#endif - return; -} - -static void -_thr_rtld_rlock_acquire(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner == curkse) { - l->count++; - _kse_critical_leave(crit); /* probably not necessary */ - } else { - KSE_LOCK_ACQUIRE(curkse, &l->lck); - l->crit = crit; - l->owner = curkse; - l->count = 1; - l->write = 0; - } -} - -static void -_thr_rtld_wlock_acquire(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner == curkse) { - _kse_critical_leave(crit); - PANIC("Recursive write lock attempt on rtld lock"); - } else { - KSE_LOCK_ACQUIRE(curkse, &l->lck); - l->crit = crit; - l->owner = curkse; - l->count = 1; - l->write = 1; - } -} - -static void -_thr_rtld_lock_release(void *lock) -{ - struct rtld_kse_lock *l; - kse_critical_t crit; - struct kse *curkse; - - l = (struct rtld_kse_lock *)lock; - crit = _kse_critical_enter(); - curkse = _get_curkse(); - if (l->owner != curkse) { - /* - * We might want to forcibly unlock the rtld lock - * and/or disable threaded mode so there is better - * chance that the panic will work. Otherwise, - * we could end up trying to take the rtld lock - * again. - */ - _kse_critical_leave(crit); - PANIC("Attempt to unlock rtld lock when not owner."); - } else { - l->count--; - if (l->count == 0) { - /* - * If there ever is a count associated with - * _kse_critical_leave(), we'll need to add - * another call to it here with the crit - * value from above. - */ - crit = l->crit; - l->owner = NULL; - l->write = 0; - KSE_LOCK_RELEASE(curkse, &l->lck); - } - _kse_critical_leave(crit); - } -} - - -static int -_thr_rtld_set_flag(int mask) -{ - return (0); -} - -static int -_thr_rtld_clr_flag(int mask) -{ - return (0); -} - -void -_thr_rtld_init(void) -{ - struct RtldLockInfo li; - - li.lock_create = _thr_rtld_lock_create; - li.lock_destroy = _thr_rtld_lock_destroy; - li.rlock_acquire = _thr_rtld_rlock_acquire; - li.wlock_acquire = _thr_rtld_wlock_acquire; - li.lock_release = _thr_rtld_lock_release; - li.thread_set_flag = _thr_rtld_set_flag; - li.thread_clr_flag = _thr_rtld_clr_flag; - li.at_fork = NULL; - _rtld_thread_init(&li); -} - -void -_thr_rtld_fini(void) -{ - _rtld_thread_init(NULL); -} diff --git a/lib/libpthread/thread/thr_rwlock.c b/lib/libpthread/thread/thr_rwlock.c deleted file mode 100644 index a0b36de..0000000 --- a/lib/libpthread/thread/thr_rwlock.c +++ /dev/null @@ -1,438 +0,0 @@ -/*- - * Copyright (c) 1998 Alex Nash - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <errno.h> -#include <limits.h> -#include <stdlib.h> - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "thr_private.h" - -/* maximum number of times a read lock may be obtained */ -#define MAX_READ_LOCKS (INT_MAX - 1) - -LT10_COMPAT_PRIVATE(_pthread_rwlock_destroy); -LT10_COMPAT_DEFAULT(pthread_rwlock_destroy); -LT10_COMPAT_PRIVATE(_pthread_rwlock_init); -LT10_COMPAT_DEFAULT(pthread_rwlock_init); -LT10_COMPAT_PRIVATE(_pthread_rwlock_rdlock); -LT10_COMPAT_DEFAULT(pthread_rwlock_rdlock); -LT10_COMPAT_PRIVATE(_pthread_rwlock_timedrdlock); -LT10_COMPAT_DEFAULT(pthread_rwlock_timedrdlock); -LT10_COMPAT_PRIVATE(_pthread_rwlock_tryrdlock); -LT10_COMPAT_DEFAULT(pthread_rwlock_tryrdlock); -LT10_COMPAT_PRIVATE(_pthread_rwlock_trywrlock); -LT10_COMPAT_DEFAULT(pthread_rwlock_trywrlock); -LT10_COMPAT_PRIVATE(_pthread_rwlock_unlock); -LT10_COMPAT_DEFAULT(pthread_rwlock_unlock); -LT10_COMPAT_PRIVATE(_pthread_rwlock_wrlock); -LT10_COMPAT_DEFAULT(pthread_rwlock_wrlock); -LT10_COMPAT_PRIVATE(_pthread_rwlock_timedwrlock); -LT10_COMPAT_DEFAULT(pthread_rwlock_timedwrlock); - -__weak_reference(_pthread_rwlock_destroy, pthread_rwlock_destroy); -__weak_reference(_pthread_rwlock_init, pthread_rwlock_init); -__weak_reference(_pthread_rwlock_rdlock, pthread_rwlock_rdlock); -__weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock); -__weak_reference(_pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock); -__weak_reference(_pthread_rwlock_trywrlock, pthread_rwlock_trywrlock); -__weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock); -__weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock); -__weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); - -/* - * Prototypes - */ -static int init_static(pthread_rwlock_t *rwlock); - - -static int -init_static(pthread_rwlock_t *rwlock) -{ - struct pthread *thread = _get_curthread(); - int ret; - - THR_LOCK_ACQUIRE(thread, &_rwlock_static_lock); - - if (*rwlock == NULL) - ret = _pthread_rwlock_init(rwlock, NULL); - else - ret = 0; - - THR_LOCK_RELEASE(thread, &_rwlock_static_lock); - return (ret); -} - -int -_pthread_rwlock_destroy (pthread_rwlock_t *rwlock) -{ - int ret; - - if (rwlock == NULL) - ret = EINVAL; - else { - pthread_rwlock_t prwlock; - - prwlock = *rwlock; - - _pthread_mutex_destroy(&prwlock->lock); - _pthread_cond_destroy(&prwlock->read_signal); - _pthread_cond_destroy(&prwlock->write_signal); - free(prwlock); - - *rwlock = NULL; - - ret = 0; - } - return (ret); -} - -int -_pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) -{ - pthread_rwlock_t prwlock; - int ret; - - /* allocate rwlock object */ - prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock)); - - if (prwlock == NULL) - return (ENOMEM); - - /* initialize the lock */ - if ((ret = _pthread_mutex_init(&prwlock->lock, NULL)) != 0) - free(prwlock); - else { - /* initialize the read condition signal */ - ret = _pthread_cond_init(&prwlock->read_signal, NULL); - - if (ret != 0) { - _pthread_mutex_destroy(&prwlock->lock); - free(prwlock); - } else { - /* initialize the write condition signal */ - ret = _pthread_cond_init(&prwlock->write_signal, NULL); - - if (ret != 0) { - _pthread_cond_destroy(&prwlock->read_signal); - _pthread_mutex_destroy(&prwlock->lock); - free(prwlock); - } else { - /* success */ - prwlock->state = 0; - prwlock->blocked_writers = 0; - - *rwlock = prwlock; - } - } - } - - return (ret); -} - -static int -rwlock_rdlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) -{ - pthread_rwlock_t prwlock; - struct pthread *curthread; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - /* check lock count */ - if (prwlock->state == MAX_READ_LOCKS) { - _thr_mutex_unlock(&prwlock->lock); - return (EAGAIN); - } - - curthread = _get_curthread(); - if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) { - /* - * To avoid having to track all the rdlocks held by - * a thread or all of the threads that hold a rdlock, - * we keep a simple count of all the rdlocks held by - * a thread. If a thread holds any rdlocks it is - * possible that it is attempting to take a recursive - * rdlock. If there are blocked writers and precedence - * is given to them, then that would result in the thread - * deadlocking. So allowing a thread to take the rdlock - * when it already has one or more rdlocks avoids the - * deadlock. I hope the reader can follow that logic ;-) - */ - ; /* nothing needed */ - } else { - /* give writers priority over readers */ - while (prwlock->blocked_writers || prwlock->state < 0) { - if (abstime) - ret = _pthread_cond_timedwait - (&prwlock->read_signal, - &prwlock->lock, abstime); - else - ret = _thr_cond_wait(&prwlock->read_signal, - &prwlock->lock); - if (ret != 0) { - /* can't do a whole lot if this fails */ - _thr_mutex_unlock(&prwlock->lock); - return (ret); - } - } - } - - curthread->rdlock_count++; - prwlock->state++; /* indicate we are locked for reading */ - - /* - * Something is really wrong if this call fails. Returning - * error won't do because we've already obtained the read - * lock. Decrementing 'state' is no good because we probably - * don't have the monitor lock. - */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) -{ - return (rwlock_rdlock_common(rwlock, NULL)); -} - -__strong_reference(_pthread_rwlock_rdlock, _thr_rwlock_rdlock); - -int -_pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, - const struct timespec *abstime) -{ - return (rwlock_rdlock_common(rwlock, abstime)); -} - -int -_pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) -{ - struct pthread *curthread; - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - curthread = _get_curthread(); - if (prwlock->state == MAX_READ_LOCKS) - ret = EAGAIN; - else if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) { - /* see comment for pthread_rwlock_rdlock() */ - curthread->rdlock_count++; - prwlock->state++; - } - /* give writers priority over readers */ - else if (prwlock->blocked_writers || prwlock->state < 0) - ret = EBUSY; - else { - curthread->rdlock_count++; - prwlock->state++; /* indicate we are locked for reading */ - } - - /* see the comment on this in pthread_rwlock_rdlock */ - _pthread_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) -{ - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - if (prwlock->state != 0) - ret = EBUSY; - else - /* indicate we are locked for writing */ - prwlock->state = -1; - - /* see the comment on this in pthread_rwlock_rdlock */ - _pthread_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_unlock (pthread_rwlock_t *rwlock) -{ - struct pthread *curthread; - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - if (prwlock == NULL) - return (EINVAL); - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - curthread = _get_curthread(); - if (prwlock->state > 0) { - curthread->rdlock_count--; - prwlock->state--; - if (prwlock->state == 0 && prwlock->blocked_writers) - ret = _thr_cond_signal(&prwlock->write_signal); - } else if (prwlock->state < 0) { - prwlock->state = 0; - - if (prwlock->blocked_writers) - ret = _thr_cond_signal(&prwlock->write_signal); - else - ret = _thr_cond_broadcast(&prwlock->read_signal); - } else - ret = EINVAL; - - /* see the comment on this in pthread_rwlock_rdlock */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -__strong_reference(_pthread_rwlock_unlock, _thr_rwlock_unlock); - -static int -rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) -{ - pthread_rwlock_t prwlock; - int ret; - - if (rwlock == NULL) - return (EINVAL); - - prwlock = *rwlock; - - /* check for static initialization */ - if (prwlock == NULL) { - if ((ret = init_static(rwlock)) != 0) - return (ret); - - prwlock = *rwlock; - } - - /* grab the monitor lock */ - if ((ret = _thr_mutex_lock(&prwlock->lock)) != 0) - return (ret); - - while (prwlock->state != 0) { - prwlock->blocked_writers++; - - if (abstime != NULL) - ret = _pthread_cond_timedwait(&prwlock->write_signal, - &prwlock->lock, abstime); - else - ret = _thr_cond_wait(&prwlock->write_signal, - &prwlock->lock); - if (ret != 0) { - prwlock->blocked_writers--; - _thr_mutex_unlock(&prwlock->lock); - return (ret); - } - - prwlock->blocked_writers--; - } - - /* indicate we are locked for writing */ - prwlock->state = -1; - - /* see the comment on this in pthread_rwlock_rdlock */ - _thr_mutex_unlock(&prwlock->lock); - - return (ret); -} - -int -_pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) -{ - return (rwlock_wrlock_common (rwlock, NULL)); -} -__strong_reference(_pthread_rwlock_wrlock, _thr_rwlock_wrlock); - -int -_pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, - const struct timespec *abstime) -{ - return (rwlock_wrlock_common (rwlock, abstime)); -} diff --git a/lib/libpthread/thread/thr_rwlockattr.c b/lib/libpthread/thread/thr_rwlockattr.c deleted file mode 100644 index 174b28f..0000000 --- a/lib/libpthread/thread/thr_rwlockattr.c +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * Copyright (c) 1998 Alex Nash - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <errno.h> -#include <stdlib.h> - -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_rwlockattr_destroy); -LT10_COMPAT_DEFAULT(pthread_rwlockattr_destroy); -LT10_COMPAT_PRIVATE(_pthread_rwlockattr_getpshared); -LT10_COMPAT_DEFAULT(pthread_rwlockattr_getpshared); -LT10_COMPAT_PRIVATE(_pthread_rwlockattr_init); -LT10_COMPAT_DEFAULT(pthread_rwlockattr_init); -LT10_COMPAT_PRIVATE(_pthread_rwlockattr_setpshared); -LT10_COMPAT_DEFAULT(pthread_rwlockattr_setpshared); - -__weak_reference(_pthread_rwlockattr_destroy, pthread_rwlockattr_destroy); -__weak_reference(_pthread_rwlockattr_getpshared, pthread_rwlockattr_getpshared); -__weak_reference(_pthread_rwlockattr_init, pthread_rwlockattr_init); -__weak_reference(_pthread_rwlockattr_setpshared, pthread_rwlockattr_setpshared); - -int -_pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwlockattr) -{ - pthread_rwlockattr_t prwlockattr; - - if (rwlockattr == NULL) - return(EINVAL); - - prwlockattr = *rwlockattr; - - if (prwlockattr == NULL) - return(EINVAL); - - free(prwlockattr); - - return(0); -} - -int -_pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *rwlockattr, - int *pshared) -{ - *pshared = (*rwlockattr)->pshared; - - return(0); -} - -int -_pthread_rwlockattr_init(pthread_rwlockattr_t *rwlockattr) -{ - pthread_rwlockattr_t prwlockattr; - - if (rwlockattr == NULL) - return(EINVAL); - - prwlockattr = (pthread_rwlockattr_t) - malloc(sizeof(struct pthread_rwlockattr)); - - if (prwlockattr == NULL) - return(ENOMEM); - - prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE; - *rwlockattr = prwlockattr; - - return(0); -} - -int -_pthread_rwlockattr_setpshared(pthread_rwlockattr_t *rwlockattr, int pshared) -{ - /* Only PTHREAD_PROCESS_PRIVATE is supported. */ - if (pshared != PTHREAD_PROCESS_PRIVATE) - return(EINVAL); - - (*rwlockattr)->pshared = pshared; - - return(0); -} - diff --git a/lib/libpthread/thread/thr_select.c b/lib/libpthread/thread/thr_select.c deleted file mode 100644 index 2913c69..0000000 --- a/lib/libpthread/thread/thr_select.c +++ /dev/null @@ -1,65 +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 <unistd.h> -#include <errno.h> -#include <poll.h> -#include <stdlib.h> -#include <string.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/fcntl.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__select); -LT10_COMPAT_DEFAULT(select); - -__weak_reference(__select, select); - -int -__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout) -{ - struct pthread *curthread = _get_curthread(); - struct timespec ts; - int ret; - - if (numfds == 0 && timeout != NULL) { - TIMEVAL_TO_TIMESPEC(timeout, &ts); - return nanosleep(&ts, NULL); - } else { - _thr_cancel_enter(curthread); - ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); - _thr_cancel_leave(curthread, 1); - } - return ret; -} diff --git a/lib/libpthread/thread/thr_self.c b/lib/libpthread/thread/thr_self.c deleted file mode 100644 index e016b95..0000000 --- a/lib/libpthread/thread/thr_self.c +++ /dev/null @@ -1,47 +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 <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_self); -LT10_COMPAT_DEFAULT(pthread_self); - -__weak_reference(_pthread_self, pthread_self); - -pthread_t -_pthread_self(void) -{ - if (_thr_initial == NULL) - _libpthread_init(NULL); - - /* Return the running thread pointer: */ - return (_get_curthread()); -} diff --git a/lib/libpthread/thread/thr_sem.c b/lib/libpthread/thread/thr_sem.c deleted file mode 100644 index 21746bbe..0000000 --- a/lib/libpthread/thread/thr_sem.c +++ /dev/null @@ -1,267 +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 "namespace.h" -#include <sys/types.h> -#include <sys/queue.h> -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <stdlib.h> -#include <time.h> -#include <_semaphore.h> -#include "un-namespace.h" -#include "libc_private.h" -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_sem_init); -LT10_COMPAT_DEFAULT(sem_init); -LT10_COMPAT_PRIVATE(_sem_wait); -LT10_COMPAT_DEFAULT(sem_wait); -LT10_COMPAT_PRIVATE(_sem_timedwait); -LT10_COMPAT_DEFAULT(sem_timedwait); -LT10_COMPAT_PRIVATE(_sem_post); -LT10_COMPAT_DEFAULT(sem_post); - -__weak_reference(_sem_init, sem_init); -__weak_reference(_sem_wait, sem_wait); -__weak_reference(_sem_timedwait, sem_timedwait); -__weak_reference(_sem_post, sem_post); - - -static inline int -sem_check_validity(sem_t *sem) -{ - - if ((sem != NULL) && ((*sem)->magic == SEM_MAGIC)) - return (0); - else { - errno = EINVAL; - return (-1); - } -} - -static void -decrease_nwaiters(void *arg) -{ - sem_t *sem = (sem_t *)arg; - - (*sem)->nwaiters--; - /* - * this function is called from cancellation point, - * the mutex should already be hold. - */ - _pthread_mutex_unlock(&(*sem)->lock); -} - -static sem_t -sem_alloc(unsigned int value, semid_t semid, int system_sem) -{ - sem_t sem; - - if (value > SEM_VALUE_MAX) { - errno = EINVAL; - return (NULL); - } - - sem = (sem_t)malloc(sizeof(struct sem)); - if (sem == NULL) { - errno = ENOSPC; - return (NULL); - } - - /* - * Initialize the semaphore. - */ - if (_pthread_mutex_init(&sem->lock, NULL) != 0) { - free(sem); - errno = ENOSPC; - return (NULL); - } - - if (_pthread_cond_init(&sem->gtzero, NULL) != 0) { - _pthread_mutex_destroy(&sem->lock); - free(sem); - errno = ENOSPC; - return (NULL); - } - - sem->count = (u_int32_t)value; - sem->nwaiters = 0; - sem->magic = SEM_MAGIC; - sem->semid = semid; - sem->syssem = system_sem; - return (sem); -} - -int -_sem_init(sem_t *sem, int pshared, unsigned int value) -{ - semid_t semid; - - semid = (semid_t)SEM_USER; - if ((pshared != 0) && (ksem_init(&semid, value) != 0)) - return (-1); - - (*sem) = sem_alloc(value, semid, pshared); - if ((*sem) == NULL) { - if (pshared != 0) - ksem_destroy(semid); - return (-1); - } - return (0); -} - -int -_sem_wait(sem_t *sem) -{ - struct pthread *curthread; - int retval; - - if (sem_check_validity(sem) != 0) - return (-1); - - curthread = _get_curthread(); - if ((*sem)->syssem != 0) { - _thr_cancel_enter(curthread); - retval = ksem_wait((*sem)->semid); - _thr_cancel_leave(curthread, retval != 0); - } - else { - _pthread_testcancel(); - _pthread_mutex_lock(&(*sem)->lock); - - while ((*sem)->count <= 0) { - (*sem)->nwaiters++; - THR_CLEANUP_PUSH(curthread, decrease_nwaiters, sem); - _pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); - THR_CLEANUP_POP(curthread, 0); - (*sem)->nwaiters--; - } - (*sem)->count--; - - _pthread_mutex_unlock(&(*sem)->lock); - - retval = 0; - } - return (retval); -} - -int -_sem_timedwait(sem_t * __restrict sem, - const struct timespec * __restrict abs_timeout) -{ - struct pthread *curthread; - int retval; - int timeout_invalid; - - if (sem_check_validity(sem) != 0) - return (-1); - - if ((*sem)->syssem != 0) { - curthread = _get_curthread(); - _thr_cancel_enter(curthread); - retval = ksem_timedwait((*sem)->semid, abs_timeout); - _thr_cancel_leave(curthread, retval != 0); - } - else { - /* - * The timeout argument is only supposed to - * be checked if the thread would have blocked. - * This is checked outside of the lock so a - * segfault on an invalid address doesn't end - * up leaving the mutex locked. - */ - _pthread_testcancel(); - timeout_invalid = (abs_timeout->tv_nsec >= 1000000000) || - (abs_timeout->tv_nsec < 0); - _pthread_mutex_lock(&(*sem)->lock); - - if ((*sem)->count <= 0) { - if (timeout_invalid) { - _pthread_mutex_unlock(&(*sem)->lock); - errno = EINVAL; - return (-1); - } - (*sem)->nwaiters++; - _pthread_cleanup_push(decrease_nwaiters, sem); - _pthread_cond_timedwait(&(*sem)->gtzero, - &(*sem)->lock, abs_timeout); - _pthread_cleanup_pop(0); - (*sem)->nwaiters--; - } - if ((*sem)->count == 0) { - errno = ETIMEDOUT; - retval = -1; - } - else { - (*sem)->count--; - retval = 0; - } - - _pthread_mutex_unlock(&(*sem)->lock); - } - - return (retval); -} - -int -_sem_post(sem_t *sem) -{ - struct pthread *curthread; - int retval; - - if (sem_check_validity(sem) != 0) - return (-1); - - if ((*sem)->syssem != 0) - retval = ksem_post((*sem)->semid); - else { - /* - * sem_post() is required to be safe to call from within - * signal handlers. Thus, we must enter a critical region. - */ - curthread = _get_curthread(); - _thr_critical_enter(curthread); - _pthread_mutex_lock(&(*sem)->lock); - - (*sem)->count++; - if ((*sem)->nwaiters > 0) - _pthread_cond_signal(&(*sem)->gtzero); - - _pthread_mutex_unlock(&(*sem)->lock); - _thr_critical_leave(curthread); - retval = 0; - } - - return (retval); -} diff --git a/lib/libpthread/thread/thr_seterrno.c b/lib/libpthread/thread/thr_seterrno.c deleted file mode 100644 index 0b83ff0..0000000 --- a/lib/libpthread/thread/thr_seterrno.c +++ /dev/null @@ -1,56 +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 <pthread.h> -#include "thr_private.h" - -/* - * This function needs to reference the global error variable which is - * normally hidden from the user. - */ -#ifdef errno -#undef errno; -#endif -extern int errno; - -void -_thread_seterrno(pthread_t thread, int error) -{ - /* Check for the initial thread: */ - if (thread == _thr_initial) - /* The initial thread always uses the global error variable: */ - errno = error; - else - /* - * Threads other than the initial thread always use the error - * field in the thread structureL - */ - thread->error = error; -} diff --git a/lib/libpthread/thread/thr_setprio.c b/lib/libpthread/thread/thr_setprio.c deleted file mode 100644 index 2f67e81..0000000 --- a/lib/libpthread/thread/thr_setprio.c +++ /dev/null @@ -1,52 +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 <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_setprio); -LT10_COMPAT_DEFAULT(pthread_setprio); - -__weak_reference(_pthread_setprio, pthread_setprio); - -int -_pthread_setprio(pthread_t pthread, int prio) -{ - int ret, policy; - struct sched_param param; - - if ((ret = pthread_getschedparam(pthread, &policy, ¶m)) == 0) { - param.sched_priority = prio; - ret = pthread_setschedparam(pthread, policy, ¶m); - } - - /* Return the error status: */ - return (ret); -} diff --git a/lib/libpthread/thread/thr_setschedparam.c b/lib/libpthread/thread/thr_setschedparam.c deleted file mode 100644 index 8f5154c..0000000 --- a/lib/libpthread/thread/thr_setschedparam.c +++ /dev/null @@ -1,139 +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 <errno.h> -#include <sys/param.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_setschedparam); -LT10_COMPAT_DEFAULT(pthread_setschedparam); - -__weak_reference(_pthread_setschedparam, pthread_setschedparam); - -int -_pthread_setschedparam(pthread_t pthread, int policy, - const struct sched_param *param) -{ - struct pthread *curthread = _get_curthread(); - int in_syncq; - int in_readyq = 0; - int old_prio; - int ret = 0; - - if ((param == NULL) || (policy < SCHED_FIFO) || (policy > SCHED_RR)) { - /* Return an invalid argument error: */ - ret = EINVAL; - } else if ((param->sched_priority < THR_MIN_PRIORITY) || - (param->sched_priority > THR_MAX_PRIORITY)) { - /* Return an unsupported value error. */ - ret = ENOTSUP; - - /* Find the thread in the list of active threads: */ - } else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) - == 0) { - /* - * Lock the threads scheduling queue while we change - * its priority: - */ - THR_SCHED_LOCK(curthread, pthread); - if ((pthread->state == PS_DEAD) || - (pthread->state == PS_DEADLOCK) || - ((pthread->flags & THR_FLAGS_EXITING) != 0)) { - THR_SCHED_UNLOCK(curthread, pthread); - _thr_ref_delete(curthread, pthread); - return (ESRCH); - } - in_syncq = pthread->sflags & THR_FLAGS_IN_SYNCQ; - - /* Set the scheduling policy: */ - pthread->attr.sched_policy = policy; - - if (param->sched_priority == - THR_BASE_PRIORITY(pthread->base_priority)) - /* - * There is nothing to do; unlock the threads - * scheduling queue. - */ - THR_SCHED_UNLOCK(curthread, pthread); - else { - /* - * Remove the thread from its current priority - * queue before any adjustments are made to its - * active priority: - */ - old_prio = pthread->active_priority; - if ((pthread->flags & THR_FLAGS_IN_RUNQ) != 0) { - in_readyq = 1; - THR_RUNQ_REMOVE(pthread); - } - - /* Set the thread base priority: */ - pthread->base_priority &= - (THR_SIGNAL_PRIORITY | THR_RT_PRIORITY); - pthread->base_priority = param->sched_priority; - - /* Recalculate the active priority: */ - pthread->active_priority = MAX(pthread->base_priority, - pthread->inherited_priority); - - if (in_readyq) { - if ((pthread->priority_mutex_count > 0) && - (old_prio > pthread->active_priority)) { - /* - * POSIX states that if the priority is - * being lowered, the thread must be - * inserted at the head of the queue for - * its priority if it owns any priority - * protection or inheritence mutexes. - */ - THR_RUNQ_INSERT_HEAD(pthread); - } - else - THR_RUNQ_INSERT_TAIL(pthread); - } - - /* Unlock the threads scheduling queue: */ - THR_SCHED_UNLOCK(curthread, pthread); - - /* - * Check for any mutex priority adjustments. This - * includes checking for a priority mutex on which - * this thread is waiting. - */ - _mutex_notify_priochange(curthread, pthread, in_syncq); - } - _thr_ref_delete(curthread, pthread); - } - return (ret); -} diff --git a/lib/libpthread/thread/thr_sig.c b/lib/libpthread/thread/thr_sig.c deleted file mode 100644 index 2287221..0000000 --- a/lib/libpthread/thread/thr_sig.c +++ /dev/null @@ -1,1250 +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 <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <pthread.h> -#include "thr_private.h" - -/* Prototypes: */ -static inline void build_siginfo(siginfo_t *info, int signo); -#ifndef SYSTEM_SCOPE_ONLY -static struct pthread *thr_sig_find(struct kse *curkse, int sig, - siginfo_t *info); -#endif -static inline void thr_sigframe_restore(struct pthread *thread, - struct pthread_sigframe *psf); -static inline void thr_sigframe_save(struct pthread *thread, - struct pthread_sigframe *psf); - -#define SA_KILL 0x01 /* terminates process by default */ -#define SA_STOP 0x02 -#define SA_CONT 0x04 - -static int sigproptbl[NSIG] = { - SA_KILL, /* SIGHUP */ - SA_KILL, /* SIGINT */ - SA_KILL, /* SIGQUIT */ - SA_KILL, /* SIGILL */ - SA_KILL, /* SIGTRAP */ - SA_KILL, /* SIGABRT */ - SA_KILL, /* SIGEMT */ - SA_KILL, /* SIGFPE */ - SA_KILL, /* SIGKILL */ - SA_KILL, /* SIGBUS */ - SA_KILL, /* SIGSEGV */ - SA_KILL, /* SIGSYS */ - SA_KILL, /* SIGPIPE */ - SA_KILL, /* SIGALRM */ - SA_KILL, /* SIGTERM */ - 0, /* SIGURG */ - SA_STOP, /* SIGSTOP */ - SA_STOP, /* SIGTSTP */ - SA_CONT, /* SIGCONT */ - 0, /* SIGCHLD */ - SA_STOP, /* SIGTTIN */ - SA_STOP, /* SIGTTOU */ - 0, /* SIGIO */ - SA_KILL, /* SIGXCPU */ - SA_KILL, /* SIGXFSZ */ - SA_KILL, /* SIGVTALRM */ - SA_KILL, /* SIGPROF */ - 0, /* SIGWINCH */ - 0, /* SIGINFO */ - SA_KILL, /* SIGUSR1 */ - SA_KILL /* SIGUSR2 */ -}; - -/* #define DEBUG_SIGNAL */ -#ifdef DEBUG_SIGNAL -#define DBG_MSG stdout_debug -#else -#define DBG_MSG(x...) -#endif - -/* - * Signal setup and delivery. - * - * 1) Delivering signals to threads in the same KSE. - * These signals are sent by upcall events and are set in the - * km_sigscaught field of the KSE mailbox. Since these signals - * are received while operating on the KSE stack, they can be - * delivered either by using signalcontext() to add a stack frame - * to the target thread's stack, or by adding them in the thread's - * pending set and having the thread run them down after it - * 2) Delivering signals to threads in other KSEs/KSEGs. - * 3) Delivering signals to threads in critical regions. - * 4) Delivering signals to threads after they change their signal masks. - * - * Methods of delivering signals. - * - * 1) Add a signal frame to the thread's saved context. - * 2) Add the signal to the thread structure, mark the thread as - * having signals to handle, and let the thread run them down - * after it resumes from the KSE scheduler. - * - * Problem with 1). You can't do this to a running thread or a - * thread in a critical region. - * - * Problem with 2). You can't do this to a thread that doesn't - * yield in some way (explicitly enters the scheduler). A thread - * blocked in the kernel or a CPU hungry thread will not see the - * signal without entering the scheduler. - * - * The solution is to use both 1) and 2) to deliver signals: - * - * o Thread in critical region - use 2). When the thread - * leaves the critical region it will check to see if it - * has pending signals and run them down. - * - * o Thread enters scheduler explicitly - use 2). The thread - * can check for pending signals after it returns from the - * the scheduler. - * - * o Thread is running and not current thread - use 2). When the - * thread hits a condition specified by one of the other bullets, - * the signal will be delivered. - * - * o Thread is running and is current thread (e.g., the thread - * has just changed its signal mask and now sees that it has - * pending signals) - just run down the pending signals. - * - * o Thread is swapped out due to quantum expiration - use 1) - * - * o Thread is blocked in kernel - kse_thr_wakeup() and then - * use 1) - */ - -/* - * Rules for selecting threads for signals received: - * - * 1) If the signal is a sychronous signal, it is delivered to - * the generating (current thread). If the thread has the - * signal masked, it is added to the threads pending signal - * set until the thread unmasks it. - * - * 2) A thread in sigwait() where the signal is in the thread's - * waitset. - * - * 3) A thread in sigsuspend() where the signal is not in the - * thread's suspended signal mask. - * - * 4) Any thread (first found/easiest to deliver) that has the - * signal unmasked. - */ - -#ifndef SYSTEM_SCOPE_ONLY - -static void * -sig_daemon(void *arg /* Unused */) -{ - int i; - kse_critical_t crit; - struct timespec ts; - sigset_t set; - struct kse *curkse; - struct pthread *curthread = _get_curthread(); - - DBG_MSG("signal daemon started(%p)\n", curthread); - - curthread->name = strdup("signal thread"); - crit = _kse_critical_enter(); - curkse = _get_curkse(); - - /* - * Daemon thread is a bound thread and we must be created with - * all signals masked - */ -#if 0 - SIGFILLSET(set); - __sys_sigprocmask(SIG_SETMASK, &set, NULL); -#endif - __sys_sigpending(&set); - ts.tv_sec = 0; - ts.tv_nsec = 0; - while (1) { - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - _thr_proc_sigpending = set; - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(set, i) != 0) - _thr_sig_dispatch(curkse, i, - NULL /* no siginfo */); - } - ts.tv_sec = 30; - ts.tv_nsec = 0; - curkse->k_kcb->kcb_kmbx.km_flags = - KMF_NOUPCALL | KMF_NOCOMPLETED | KMF_WAITSIGEVENT; - kse_release(&ts); - curkse->k_kcb->kcb_kmbx.km_flags = 0; - set = curkse->k_kcb->kcb_kmbx.km_sigscaught; - } - return (0); -} - - -/* Utility function to create signal daemon thread */ -int -_thr_start_sig_daemon(void) -{ - pthread_attr_t attr; - sigset_t sigset, oldset; - - SIGFILLSET(sigset); - pthread_sigmask(SIG_SETMASK, &sigset, &oldset); - pthread_attr_init(&attr); - pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - attr->flags |= THR_SIGNAL_THREAD; - /* sigmask will be inherited */ - if (pthread_create(&_thr_sig_daemon, &attr, sig_daemon, NULL)) - PANIC("can not create signal daemon thread!\n"); - pthread_attr_destroy(&attr); - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - return (0); -} - -/* - * This signal handler only delivers asynchronous signals. - * This must be called with upcalls disabled and without - * holding any locks. - */ -void -_thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info) -{ - struct kse_mailbox *kmbx; - struct pthread *thread; - - DBG_MSG(">>> _thr_sig_dispatch(%d)\n", sig); - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - while ((thread = thr_sig_find(curkse, sig, info)) != NULL) { - /* - * Setup the target thread to receive the signal: - */ - DBG_MSG("Got signal %d, selecting thread %p\n", sig, thread); - KSE_SCHED_LOCK(curkse, thread->kseg); - if ((thread->state == PS_DEAD) || - (thread->state == PS_DEADLOCK) || - THR_IS_EXITING(thread) || THR_IS_SUSPENDED(thread)) { - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - } else if (SIGISMEMBER(thread->sigmask, sig)) { - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - } else { - kmbx = _thr_sig_add(thread, sig, info); - KSE_SCHED_UNLOCK(curkse, thread->kseg); - _thr_ref_delete(NULL, thread); - if (kmbx != NULL) - kse_wakeup(kmbx); - break; - } - } - DBG_MSG("<<< _thr_sig_dispatch\n"); -} - -#endif /* ! SYSTEM_SCOPE_ONLY */ - -static __inline int -sigprop(int sig) -{ - - if (sig > 0 && sig < NSIG) - return (sigproptbl[_SIG_IDX(sig)]); - return (0); -} - -typedef void (*ohandler)(int sig, int code, - struct sigcontext *scp, char *addr, __sighandler_t *catcher); - -void -_thr_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp) -{ - struct pthread_sigframe psf; - __siginfohandler_t *sigfunc; - struct pthread *curthread; - struct kse *curkse; - struct sigaction act; - int sa_flags, err_save; - - err_save = errno; - - DBG_MSG(">>> _thr_sig_handler(%d)\n", sig); - - curthread = _get_curthread(); - if (curthread == NULL) - PANIC("No current thread.\n"); - if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) - PANIC("Thread is not system scope.\n"); - if (curthread->flags & THR_FLAGS_EXITING) { - errno = err_save; - return; - } - - curkse = _get_curkse(); - /* - * If thread is in critical region or if thread is on - * the way of state transition, then latch signal into buffer. - */ - if (_kse_in_critical() || THR_IN_CRITICAL(curthread) || - curthread->state != PS_RUNNING) { - DBG_MSG(">>> _thr_sig_handler(%d) in critical\n", sig); - curthread->siginfo[sig-1] = *info; - curthread->check_pending = 1; - curkse->k_sigseqno++; - SIGADDSET(curthread->sigpend, sig); - /* - * If the kse is on the way to idle itself, but - * we have signal ready, we should prevent it - * to sleep, kernel will latch the wakeup request, - * so kse_release will return from kernel immediately. - */ - if (KSE_IS_IDLE(curkse)) - kse_wakeup(&curkse->k_kcb->kcb_kmbx); - errno = err_save; - return; - } - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - /* Check the threads previous state: */ - curthread->critical_count++; - if (curthread->sigbackout != NULL) - curthread->sigbackout((void *)curthread); - curthread->critical_count--; - thr_sigframe_save(curthread, &psf); - THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); - - _kse_critical_enter(); - /* Get a fresh copy of signal mask */ - __sys_sigprocmask(SIG_BLOCK, NULL, &curthread->sigmask); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - sa_flags = _thread_sigact[sig - 1].sa_flags; - if (sa_flags & SA_RESETHAND) { - act.sa_handler = SIG_DFL; - act.sa_flags = SA_RESTART; - SIGEMPTYSET(act.sa_mask); - __sys_sigaction(sig, &act, NULL); - __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); - } - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* Now invoke real handler */ - if (((__sighandler_t *)sigfunc != SIG_DFL) && - ((__sighandler_t *)sigfunc != SIG_IGN) && - (sigfunc != (__siginfohandler_t *)_thr_sig_handler)) { - if ((sa_flags & SA_SIGINFO) != 0 || info == NULL) - (*(sigfunc))(sig, info, ucp); - else { - ((ohandler)(*sigfunc))( - sig, info->si_code, (struct sigcontext *)ucp, - info->si_addr, (__sighandler_t *)sigfunc); - } - } else { - if ((__sighandler_t *)sigfunc == SIG_DFL) { - if (sigprop(sig) & SA_KILL) { - if (_kse_isthreaded()) - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, sig); - else - kill(getpid(), sig); - } -#ifdef NOTYET - else if (sigprop(sig) & SA_STOP) - kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, sig); -#endif - } - } - _kse_critical_enter(); - curthread->sigmask = ucp->uc_sigmask; - SIG_CANTMASK(curthread->sigmask); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - thr_sigframe_restore(curthread, &psf); - - DBG_MSG("<<< _thr_sig_handler(%d)\n", sig); - - errno = err_save; -} - -struct sighandle_info { - __siginfohandler_t *sigfunc; - int sa_flags; - int sig; - siginfo_t *info; - ucontext_t *ucp; -}; - -static void handle_signal(struct pthread *curthread, - struct sighandle_info *shi); -static void handle_signal_altstack(struct pthread *curthread, - struct sighandle_info *shi); - -/* Must be called with signal lock and schedule lock held in order */ -static void -thr_sig_invoke_handler(struct pthread *curthread, int sig, siginfo_t *info, - ucontext_t *ucp) -{ - __siginfohandler_t *sigfunc; - sigset_t sigmask; - int sa_flags; - int onstack; - struct sigaction act; - struct kse *curkse; - struct sighandle_info shi; - - /* - * Invoke the signal handler without going through the scheduler: - */ - DBG_MSG("Got signal %d, calling handler for current thread %p\n", - sig, curthread); - - if (!_kse_in_critical()) - PANIC("thr_sig_invoke_handler without in critical\n"); - curkse = curthread->kse; - /* - * Check that a custom handler is installed and if - * the signal is not blocked: - */ - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - sa_flags = _thread_sigact[sig - 1].sa_flags; - sigmask = curthread->sigmask; - SIGSETOR(curthread->sigmask, _thread_sigact[sig - 1].sa_mask); - if (!(sa_flags & (SA_NODEFER | SA_RESETHAND))) - SIGADDSET(curthread->sigmask, sig); - if ((sig != SIGILL) && (sa_flags & SA_RESETHAND)) { - act.sa_handler = SIG_DFL; - act.sa_flags = SA_RESTART; - SIGEMPTYSET(act.sa_mask); - __sys_sigaction(sig, &act, NULL); - __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); - } - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - /* - * We are processing buffered signals, synchronize working - * signal mask into kernel. - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - onstack = _thr_sigonstack(&sigfunc); - ucp->uc_stack = curthread->sigstk; - ucp->uc_stack.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) - ? SS_DISABLE : ((onstack) ? SS_ONSTACK : 0); - if (curthread->oldsigmask) { - ucp->uc_sigmask = *(curthread->oldsigmask); - curthread->oldsigmask = NULL; - } else - ucp->uc_sigmask = sigmask; - shi.sigfunc = sigfunc; - shi.sig = sig; - shi.sa_flags = sa_flags; - shi.info = info; - shi.ucp = ucp; - if ((curthread->sigstk.ss_flags & SS_DISABLE) == 0) { - /* Deliver signal on alternative stack */ - if (sa_flags & SA_ONSTACK && !onstack) - handle_signal_altstack(curthread, &shi); - else - handle_signal(curthread, &shi); - } else { - handle_signal(curthread, &shi); - } - - _kse_critical_enter(); - /* Don't trust after critical leave/enter */ - curkse = curthread->kse; - - /* - * Restore the thread's signal mask. - */ - curthread->sigmask = ucp->uc_sigmask; - SIG_CANTMASK(curthread->sigmask); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - __sys_sigprocmask(SIG_SETMASK, &ucp->uc_sigmask, NULL); - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - - DBG_MSG("Got signal %d, handler returned %p\n", sig, curthread); -} - -static void -handle_signal(struct pthread *curthread, struct sighandle_info *shi) -{ - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - - /* Check if the signal requires a dump of thread information: */ - if (_thr_dump_enabled() && (shi->sig == SIGINFO)) { - /* Dump thread information to file: */ - _thread_dump_info(); - } - - if (((__sighandler_t *)shi->sigfunc != SIG_DFL) && - ((__sighandler_t *)shi->sigfunc != SIG_IGN)) { - if ((shi->sa_flags & SA_SIGINFO) != 0 || shi->info == NULL) - (*(shi->sigfunc))(shi->sig, shi->info, shi->ucp); - else { - ((ohandler)(*shi->sigfunc))( - shi->sig, shi->info->si_code, - (struct sigcontext *)shi->ucp, - shi->info->si_addr, - (__sighandler_t *)shi->sigfunc); - } - } else { - if ((__sighandler_t *)shi->sigfunc == SIG_DFL) { - if (sigprop(shi->sig) & SA_KILL) { - if (_kse_isthreaded()) - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, shi->sig); - else - kill(getpid(), shi->sig); - } -#ifdef NOTYET - else if (sigprop(shi->sig) & SA_STOP) - kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, - shi->sig); -#endif - } - } -} - -static void -handle_signal_wrapper(struct pthread *curthread, ucontext_t *ret_uc, - struct sighandle_info *shi) -{ - shi->ucp->uc_stack.ss_flags = SS_ONSTACK; - handle_signal(curthread, shi); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - setcontext(ret_uc); - else { - /* Work around for ia64, THR_SETCONTEXT does not work */ - _kse_critical_enter(); - curthread->tcb->tcb_tmbx.tm_context = *ret_uc; - _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); - /* THR_SETCONTEXT */ - } -} - -/* - * Jump to stack set by sigaltstack before invoking signal handler - */ -static void -handle_signal_altstack(struct pthread *curthread, struct sighandle_info *shi) -{ - volatile int once; - ucontext_t uc1, *uc2; - - THR_ASSERT(_kse_in_critical(), "Not in critical"); - - once = 0; - THR_GETCONTEXT(&uc1); - if (once == 0) { - once = 1; - /* XXX - * We are still in critical region, it is safe to operate thread - * context - */ - uc2 = &curthread->tcb->tcb_tmbx.tm_context; - uc2->uc_stack = curthread->sigstk; - makecontext(uc2, (void (*)(void))handle_signal_wrapper, - 3, curthread, &uc1, shi); - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - setcontext(uc2); - else { - _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); - /* THR_SETCONTEXT(uc2); */ - } - } -} - -int -_thr_getprocsig(int sig, siginfo_t *siginfo) -{ - kse_critical_t crit; - struct kse *curkse; - int ret; - - DBG_MSG(">>> _thr_getprocsig\n"); - - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - ret = _thr_getprocsig_unlocked(sig, siginfo); - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - _kse_critical_leave(crit); - - DBG_MSG("<<< _thr_getprocsig\n"); - return (ret); -} - -int -_thr_getprocsig_unlocked(int sig, siginfo_t *siginfo) -{ - sigset_t sigset; - struct timespec ts; - - /* try to retrieve signal from kernel */ - SIGEMPTYSET(sigset); - SIGADDSET(sigset, sig); - ts.tv_sec = 0; - ts.tv_nsec = 0; - SIGDELSET(_thr_proc_sigpending, sig); - if (__sys_sigtimedwait(&sigset, siginfo, &ts) > 0) - return (sig); - return (0); -} - -#ifndef SYSTEM_SCOPE_ONLY -/* - * Find a thread that can handle the signal. This must be called - * with upcalls disabled. - */ -struct pthread * -thr_sig_find(struct kse *curkse, int sig, siginfo_t *info) -{ - struct kse_mailbox *kmbx = NULL; - struct pthread *pthread; - struct pthread *suspended_thread, *signaled_thread; - __siginfohandler_t *sigfunc; - siginfo_t si; - - DBG_MSG("Looking for thread to handle signal %d\n", sig); - - /* - * Enter a loop to look for threads that have the signal - * unmasked. POSIX specifies that a thread in a sigwait - * will get the signal over any other threads. Second - * preference will be threads in in a sigsuspend. Third - * preference will be the current thread. If none of the - * above, then the signal is delivered to the first thread - * that is found. Note that if a custom handler is not - * installed, the signal only affects threads in sigwait. - */ - suspended_thread = NULL; - signaled_thread = NULL; - - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - TAILQ_FOREACH(pthread, &_thread_list, tle) { - if (pthread == _thr_sig_daemon) - continue; - /* Signal delivering to bound thread is done by kernel */ - if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - continue; - /* Take the scheduling lock. */ - KSE_SCHED_LOCK(curkse, pthread->kseg); - if ((pthread->state == PS_DEAD) || - (pthread->state == PS_DEADLOCK) || - THR_IS_EXITING(pthread) || - THR_IS_SUSPENDED(pthread)) { - ; /* Skip this thread. */ - } else if (pthread->state == PS_SIGWAIT && - SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { - /* - * retrieve signal from kernel, if it is job control - * signal, and sigaction is SIG_DFL, then we will - * be stopped in kernel, we hold lock here, but that - * does not matter, because that's job control, and - * whole process should be stopped. - */ - if (_thr_getprocsig(sig, &si)) { - DBG_MSG("Waking thread %p in sigwait" - " with signal %d\n", pthread, sig); - /* where to put siginfo ? */ - *(pthread->data.sigwait->siginfo) = si; - kmbx = _thr_setrunnable_unlocked(pthread); - } - KSE_SCHED_UNLOCK(curkse, pthread->kseg); - /* - * POSIX doesn't doesn't specify which thread - * will get the signal if there are multiple - * waiters, so we give it to the first thread - * we find. - * - * Do not attempt to deliver this signal - * to other threads and do not add the signal - * to the process pending set. - */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - if (kmbx != NULL) - kse_wakeup(kmbx); - if (suspended_thread != NULL) - _thr_ref_delete(NULL, suspended_thread); - if (signaled_thread != NULL) - _thr_ref_delete(NULL, signaled_thread); - return (NULL); - } else if (!SIGISMEMBER(pthread->sigmask, sig)) { - /* - * If debugger is running, we don't quick exit, - * and give it a chance to check the signal. - */ - if (_libkse_debug == 0) { - sigfunc = _thread_sigact[sig - 1].sa_sigaction; - if ((__sighandler_t *)sigfunc == SIG_DFL) { - if (sigprop(sig) & SA_KILL) { - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, sig); - /* Never reach */ - } - } - } - if (pthread->state == PS_SIGSUSPEND) { - if (suspended_thread == NULL) { - suspended_thread = pthread; - suspended_thread->refcount++; - } - } else if (signaled_thread == NULL) { - signaled_thread = pthread; - signaled_thread->refcount++; - } - } - KSE_SCHED_UNLOCK(curkse, pthread->kseg); - } - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - - if (suspended_thread != NULL) { - pthread = suspended_thread; - if (signaled_thread) - _thr_ref_delete(NULL, signaled_thread); - } else if (signaled_thread) { - pthread = signaled_thread; - } else { - pthread = NULL; - } - return (pthread); -} -#endif /* ! SYSTEM_SCOPE_ONLY */ - -static inline void -build_siginfo(siginfo_t *info, int signo) -{ - bzero(info, sizeof(*info)); - info->si_signo = signo; - info->si_pid = _thr_pid; -} - -/* - * This is called by a thread when it has pending signals to deliver. - * It should only be called from the context of the thread. - */ -void -_thr_sig_rundown(struct pthread *curthread, ucontext_t *ucp) -{ - struct pthread_sigframe psf; - siginfo_t siginfo; - int i, err_save; - kse_critical_t crit; - struct kse *curkse; - sigset_t sigmask; - - err_save = errno; - - DBG_MSG(">>> thr_sig_rundown (%p)\n", curthread); - - /* Check the threads previous state: */ - curthread->critical_count++; - if (curthread->sigbackout != NULL) - curthread->sigbackout((void *)curthread); - curthread->critical_count--; - - THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); - THR_ASSERT((curthread->state == PS_RUNNING), "state is not PS_RUNNING"); - - thr_sigframe_save(curthread, &psf); - /* - * Lower the priority before calling the handler in case - * it never returns (longjmps back): - */ - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curkse->k_kseg); - KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); - curthread->active_priority &= ~THR_SIGNAL_PRIORITY; - SIGFILLSET(sigmask); - while (1) { - /* - * For bound thread, we mask all signals and get a fresh - * copy of signal mask from kernel - */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, &sigmask, - &curthread->sigmask); - } - for (i = 1; i <= _SIG_MAXSIG; i++) { - if (SIGISMEMBER(curthread->sigmask, i)) - continue; - if (SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - siginfo = curthread->siginfo[i-1]; - break; - } - if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - && SIGISMEMBER(_thr_proc_sigpending, i)) { - if (_thr_getprocsig_unlocked(i, &siginfo)) - break; - } - } - if (i <= _SIG_MAXSIG) - thr_sig_invoke_handler(curthread, i, &siginfo, ucp); - else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sigprocmask(SIG_SETMASK, - &curthread->sigmask, NULL); - } - break; - } - } - - /* Don't trust after signal handling */ - curkse = curthread->kse; - KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); - KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); - _kse_critical_leave(&curthread->tcb->tcb_tmbx); - /* repost masked signal to kernel, it hardly happens in real world */ - if ((curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - !SIGISEMPTY(curthread->sigpend)) { /* dirty read */ - __sys_sigprocmask(SIG_SETMASK, &sigmask, &curthread->sigmask); - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - if (!_kse_isthreaded()) - kill(getpid(), i); - else - kse_thr_interrupt( - &curthread->tcb->tcb_tmbx, - KSE_INTR_SENDSIG, - i); - } - } - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - } - DBG_MSG("<<< thr_sig_rundown (%p)\n", curthread); - - thr_sigframe_restore(curthread, &psf); - errno = err_save; -} - -/* - * This checks pending signals for the current thread. It should be - * called whenever a thread changes its signal mask. Note that this - * is called from a thread (using its stack). - * - * XXX - We might want to just check to see if there are pending - * signals for the thread here, but enter the UTS scheduler - * to actually install the signal handler(s). - */ -void -_thr_sig_check_pending(struct pthread *curthread) -{ - ucontext_t uc; - volatile int once; - int errsave; - - /* - * If the thread is in critical region, delay processing signals. - * If the thread state is not PS_RUNNING, it might be switching - * into UTS and but a THR_LOCK_RELEASE saw check_pending, and it - * goes here, in the case we delay processing signals, lets UTS - * process complicated things, normally UTS will call _thr_sig_add - * to resume the thread, so we needn't repeat doing it here. - */ - if (THR_IN_CRITICAL(curthread) || curthread->state != PS_RUNNING) - return; - - errsave = errno; - once = 0; - THR_GETCONTEXT(&uc); - if (once == 0) { - once = 1; - curthread->check_pending = 0; - _thr_sig_rundown(curthread, &uc); - } - errno = errsave; -} - -/* - * Perform thread specific actions in response to a signal. - * This function is only called if there is a handler installed - * for the signal, and if the target thread has the signal - * unmasked. - * - * This must be called with the thread's scheduling lock held. - */ -struct kse_mailbox * -_thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info) -{ - siginfo_t siginfo; - struct kse *curkse; - struct kse_mailbox *kmbx = NULL; - struct pthread *curthread = _get_curthread(); - int restart; - int suppress_handler = 0; - int fromproc = 0; - __sighandler_t *sigfunc; - - DBG_MSG(">>> _thr_sig_add %p (%d)\n", pthread, sig); - - curkse = _get_curkse(); - restart = _thread_sigact[sig - 1].sa_flags & SA_RESTART; - sigfunc = _thread_sigact[sig - 1].sa_handler; - fromproc = (curthread == _thr_sig_daemon); - - if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK || - pthread->state == PS_STATE_MAX) - return (NULL); /* return false */ - - if ((pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - (curthread != pthread)) { - PANIC("Please use _thr_send_sig for bound thread"); - return (NULL); - } - - if (pthread->state != PS_SIGWAIT && - SIGISMEMBER(pthread->sigmask, sig)) { - /* signal is masked, just add signal to thread. */ - if (!fromproc) { - SIGADDSET(pthread->sigpend, sig); - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, - sizeof(*info)); - } else { - if (!_thr_getprocsig(sig, &pthread->siginfo[sig-1])) - return (NULL); - SIGADDSET(pthread->sigpend, sig); - } - } - else { - /* if process signal not exists, just return */ - if (fromproc) { - if (!_thr_getprocsig(sig, &siginfo)) - return (NULL); - info = &siginfo; - } - - if (pthread->state != PS_SIGWAIT && sigfunc == SIG_DFL && - (sigprop(sig) & SA_KILL)) { - kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); - /* Never reach */ - } - - /* - * Process according to thread state: - */ - switch (pthread->state) { - case PS_DEAD: - case PS_DEADLOCK: - case PS_STATE_MAX: - return (NULL); /* XXX return false */ - case PS_LOCKWAIT: - case PS_SUSPENDED: - /* - * You can't call a signal handler for threads in these - * states. - */ - suppress_handler = 1; - break; - case PS_RUNNING: - if ((pthread->flags & THR_FLAGS_IN_RUNQ)) { - THR_RUNQ_REMOVE(pthread); - pthread->active_priority |= THR_SIGNAL_PRIORITY; - THR_RUNQ_INSERT_TAIL(pthread); - } else { - /* Possible not in RUNQ and has curframe ? */ - pthread->active_priority |= THR_SIGNAL_PRIORITY; - } - break; - /* - * States which cannot be interrupted but still require the - * signal handler to run: - */ - case PS_COND_WAIT: - case PS_MUTEX_WAIT: - break; - - case PS_SLEEP_WAIT: - /* - * Unmasked signals always cause sleep to terminate - * early regardless of SA_RESTART: - */ - pthread->interrupted = 1; - break; - - case PS_JOIN: - break; - - case PS_SIGSUSPEND: - pthread->interrupted = 1; - break; - - case PS_SIGWAIT: - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, - sizeof(*info)); - /* - * The signal handler is not called for threads in - * SIGWAIT. - */ - suppress_handler = 1; - /* Wake up the thread if the signal is not blocked. */ - if (SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { - /* Return the signal number: */ - *(pthread->data.sigwait->siginfo) = pthread->siginfo[sig-1]; - /* Make the thread runnable: */ - kmbx = _thr_setrunnable_unlocked(pthread); - } else { - /* Increment the pending signal count. */ - SIGADDSET(pthread->sigpend, sig); - if (!SIGISMEMBER(pthread->sigmask, sig)) { - if (sigfunc == SIG_DFL && - sigprop(sig) & SA_KILL) { - kse_thr_interrupt(NULL, - KSE_INTR_SIGEXIT, - sig); - /* Never reach */ - } - pthread->check_pending = 1; - pthread->interrupted = 1; - kmbx = _thr_setrunnable_unlocked(pthread); - } - } - return (kmbx); - } - - SIGADDSET(pthread->sigpend, sig); - if (info == NULL) - build_siginfo(&pthread->siginfo[sig-1], sig); - else if (info != &pthread->siginfo[sig-1]) - memcpy(&pthread->siginfo[sig-1], info, sizeof(*info)); - pthread->check_pending = 1; - if (!(pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && - (pthread->blocked != 0) && !THR_IN_CRITICAL(pthread)) - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, - restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); - if (suppress_handler == 0) { - /* - * Setup a signal frame and save the current threads - * state: - */ - if (pthread->state != PS_RUNNING) { - if (pthread->flags & THR_FLAGS_IN_RUNQ) - THR_RUNQ_REMOVE(pthread); - pthread->active_priority |= THR_SIGNAL_PRIORITY; - kmbx = _thr_setrunnable_unlocked(pthread); - } - } - } - return (kmbx); -} - -/* - * Send a signal to a specific thread (ala pthread_kill): - */ -void -_thr_sig_send(struct pthread *pthread, int sig) -{ - struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx; - - if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, KSE_INTR_SENDSIG, sig); - return; - } - - /* Lock the scheduling queue of the target thread. */ - THR_SCHED_LOCK(curthread, pthread); - if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) { - kmbx = _thr_sig_add(pthread, sig, NULL); - /* Add a preemption point. */ - if (kmbx == NULL && (curthread->kseg == pthread->kseg) && - (pthread->active_priority > curthread->active_priority)) - curthread->critical_yield = 1; - THR_SCHED_UNLOCK(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); - /* XXX - * If thread sent signal to itself, check signals now. - * It is not really needed, _kse_critical_leave should - * have already checked signals. - */ - if (pthread == curthread && curthread->check_pending) - _thr_sig_check_pending(curthread); - - } else { - THR_SCHED_UNLOCK(curthread, pthread); - } -} - -static inline void -thr_sigframe_restore(struct pthread *curthread, struct pthread_sigframe *psf) -{ - kse_critical_t crit; - struct kse *curkse; - - THR_THREAD_LOCK(curthread, curthread); - curthread->cancelflags = psf->psf_cancelflags; - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curthread->kseg); - curthread->flags = psf->psf_flags; - curthread->interrupted = psf->psf_interrupted; - curthread->timeout = psf->psf_timeout; - curthread->data = psf->psf_wait_data; - curthread->wakeup_time = psf->psf_wakeup_time; - curthread->continuation = psf->psf_continuation; - KSE_SCHED_UNLOCK(curkse, curthread->kseg); - _kse_critical_leave(crit); - THR_THREAD_UNLOCK(curthread, curthread); -} - -static inline void -thr_sigframe_save(struct pthread *curthread, struct pthread_sigframe *psf) -{ - kse_critical_t crit; - struct kse *curkse; - - THR_THREAD_LOCK(curthread, curthread); - psf->psf_cancelflags = curthread->cancelflags; - crit = _kse_critical_enter(); - curkse = curthread->kse; - KSE_SCHED_LOCK(curkse, curthread->kseg); - /* This has to initialize all members of the sigframe. */ - psf->psf_flags = (curthread->flags & (THR_FLAGS_PRIVATE | THR_FLAGS_EXITING)); - psf->psf_interrupted = curthread->interrupted; - psf->psf_timeout = curthread->timeout; - psf->psf_wait_data = curthread->data; - psf->psf_wakeup_time = curthread->wakeup_time; - psf->psf_continuation = curthread->continuation; - KSE_SCHED_UNLOCK(curkse, curthread->kseg); - _kse_critical_leave(crit); - THR_THREAD_UNLOCK(curthread, curthread); -} - -void -_thr_signal_init(void) -{ - struct sigaction act; - __siginfohandler_t *sigfunc; - int i; - sigset_t sigset; - - SIGFILLSET(sigset); - __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); - /* Enter a loop to get the existing signal status: */ - for (i = 1; i <= _SIG_MAXSIG; i++) { - /* Get the signal handler details: */ - if (__sys_sigaction(i, NULL, &_thread_sigact[i - 1]) != 0) { - /* - * Abort this process if signal - * initialisation fails: - */ - PANIC("Cannot read signal handler info"); - } - /* Intall wrapper if handler was set */ - sigfunc = _thread_sigact[i - 1].sa_sigaction; - if (((__sighandler_t *)sigfunc) != SIG_DFL && - ((__sighandler_t *)sigfunc) != SIG_IGN) { - act = _thread_sigact[i - 1]; - act.sa_flags |= SA_SIGINFO; - act.sa_sigaction = - (__siginfohandler_t *)_thr_sig_handler; - __sys_sigaction(i, &act, NULL); - } - } - if (_thr_dump_enabled()) { - /* - * Install the signal handler for SIGINFO. It isn't - * really needed, but it is nice to have for debugging - * purposes. - */ - _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; - SIGEMPTYSET(act.sa_mask); - act.sa_flags = SA_SIGINFO | SA_RESTART; - act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; - if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, - NULL); - /* - * Abort this process if signal initialisation fails: - */ - PANIC("Cannot initialize signal handler"); - } - } - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, NULL); - __sys_sigaltstack(NULL, &_thr_initial->sigstk); -} - -void -_thr_signal_deinit(void) -{ - int i; - struct pthread *curthread = _get_curthread(); - - /* Clear process pending signals. */ - sigemptyset(&_thr_proc_sigpending); - - /* Enter a loop to get the existing signal status: */ - for (i = 1; i <= _SIG_MAXSIG; i++) { - /* Check for signals which cannot be trapped: */ - if (i == SIGKILL || i == SIGSTOP) { - } - - /* Set the signal handler details: */ - else if (__sys_sigaction(i, &_thread_sigact[i - 1], - NULL) != 0) { - /* - * Abort this process if signal - * initialisation fails: - */ - PANIC("Cannot set signal handler info"); - } - } - __sys_sigaltstack(&curthread->sigstk, NULL); -} - diff --git a/lib/libpthread/thread/thr_sigaction.c b/lib/libpthread/thread/thr_sigaction.c deleted file mode 100644 index bfb67fe..0000000 --- a/lib/libpthread/thread/thr_sigaction.c +++ /dev/null @@ -1,127 +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 <signal.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_sigaction); -LT10_COMPAT_DEFAULT(sigaction); - -__weak_reference(_sigaction, sigaction); - -int -_sigaction(int sig, const struct sigaction * act, struct sigaction * oact) -{ - int ret = 0; - int err = 0; - struct sigaction newact, oldact; - struct pthread *curthread; - kse_critical_t crit; - - /* Check if the signal number is out of range: */ - if (sig < 1 || sig > _SIG_MAXSIG) { - /* Return an invalid argument: */ - errno = EINVAL; - ret = -1; - } else { - if (act) - newact = *act; - - crit = _kse_critical_enter(); - curthread = _get_curthread(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); - - oldact = _thread_sigact[sig - 1]; - - /* Check if a signal action was supplied: */ - if (act != NULL) { - /* Set the new signal handler: */ - _thread_sigact[sig - 1] = newact; - } - - /* - * Check if the kernel needs to be advised of a change - * in signal action: - */ - if (act != NULL) { - - newact.sa_flags |= SA_SIGINFO; - - /* - * Check if the signal handler is being set to - * the default or ignore handlers: - */ - if (newact.sa_handler != SIG_DFL && - newact.sa_handler != SIG_IGN) { - /* - * Specify the thread kernel signal - * handler: - */ - newact.sa_handler = (void (*) ())_thr_sig_handler; - } - /* - * Install libpthread signal handler wrapper - * for SIGINFO signal if threads dump enabled - * even if a user set the signal handler to - * SIG_DFL or SIG_IGN. - */ - if (sig == SIGINFO && _thr_dump_enabled()) { - newact.sa_handler = - (void (*) ())_thr_sig_handler; - } - /* Change the signal action in the kernel: */ - if (__sys_sigaction(sig, &newact, NULL) != 0) { - _thread_sigact[sig - 1] = oldact; - /* errno is in kse, will copy it to thread */ - err = errno; - ret = -1; - } - } - KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); - _kse_critical_leave(crit); - /* - * Check if the existing signal action structure contents are - * to be returned: - */ - if (oact != NULL) { - /* Return the existing signal action contents: */ - *oact = oldact; - } - if (ret != 0) { - /* Return errno to thread */ - errno = err; - } - } - - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libpthread/thread/thr_sigaltstack.c b/lib/libpthread/thread/thr_sigaltstack.c deleted file mode 100644 index 8ebbdee..0000000 --- a/lib/libpthread/thread/thr_sigaltstack.c +++ /dev/null @@ -1,110 +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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <errno.h> -#include <signal.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_sigaltstack); -LT10_COMPAT_DEFAULT(sigaltstack); - -__weak_reference(_sigaltstack, sigaltstack); - -int -_sigaltstack(stack_t *_ss, stack_t *_oss) -{ - struct pthread *curthread = _get_curthread(); - stack_t ss, oss; - int oonstack, errsave, ret; - kse_critical_t crit; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - crit = _kse_critical_enter(); - ret = __sys_sigaltstack(_ss, _oss); - errsave = errno; - /* Get a copy */ - if (ret == 0 && _ss != NULL) - curthread->sigstk = *_ss; - _kse_critical_leave(crit); - errno = errsave; - return (ret); - } - - if (_ss) - ss = *_ss; - if (_oss) - oss = *_oss; - - /* Should get and set stack in atomic way */ - crit = _kse_critical_enter(); - oonstack = _thr_sigonstack(&ss); - if (_oss != NULL) { - oss = curthread->sigstk; - oss.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) - ? SS_DISABLE : ((oonstack) ? SS_ONSTACK : 0); - } - - if (_ss != NULL) { - if (oonstack) { - _kse_critical_leave(crit); - errno = EPERM; - return (-1); - } - if ((ss.ss_flags & ~SS_DISABLE) != 0) { - _kse_critical_leave(crit); - errno = EINVAL; - return (-1); - } - if (!(ss.ss_flags & SS_DISABLE)) { - if (ss.ss_size < MINSIGSTKSZ) { - _kse_critical_leave(crit); - errno = ENOMEM; - return (-1); - } - curthread->sigstk = ss; - } else { - curthread->sigstk.ss_flags |= SS_DISABLE; - } - } - _kse_critical_leave(crit); - if (_oss != NULL) - *_oss = oss; - return (0); -} - -int -_thr_sigonstack(void *sp) -{ - struct pthread *curthread = _get_curthread(); - - return ((curthread->sigstk.ss_flags & SS_DISABLE) == 0 ? - (((size_t)sp - (size_t)curthread->sigstk.ss_sp) < curthread->sigstk.ss_size) - : 0); -} - diff --git a/lib/libpthread/thread/thr_sigmask.c b/lib/libpthread/thread/thr_sigmask.c deleted file mode 100644 index b08ba06..0000000 --- a/lib/libpthread/thread/thr_sigmask.c +++ /dev/null @@ -1,113 +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 <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_sigmask); -LT10_COMPAT_DEFAULT(pthread_sigmask); - -__weak_reference(_pthread_sigmask, pthread_sigmask); - -int -_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) -{ - struct pthread *curthread = _get_curthread(); - sigset_t oldset, newset; - int ret; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - ret = __sys_sigprocmask(how, set, oset); - if (ret != 0) - ret = errno; - /* Get a fresh copy */ - __sys_sigprocmask(SIG_SETMASK, NULL, &curthread->sigmask); - return (ret); - } - - if (set) - newset = *set; - - THR_SCHED_LOCK(curthread, curthread); - - ret = 0; - if (oset != NULL) - /* Return the current mask: */ - oldset = curthread->sigmask; - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - /* Process according to what to do: */ - switch (how) { - /* Block signals: */ - case SIG_BLOCK: - /* Add signals to the existing mask: */ - SIGSETOR(curthread->sigmask, newset); - break; - - /* Unblock signals: */ - case SIG_UNBLOCK: - /* Clear signals from the existing mask: */ - SIGSETNAND(curthread->sigmask, newset); - break; - - /* Set the signal process mask: */ - case SIG_SETMASK: - /* Set the new mask: */ - curthread->sigmask = newset; - break; - - /* Trap invalid actions: */ - default: - /* Return an invalid argument: */ - ret = EINVAL; - break; - } - SIG_CANTMASK(curthread->sigmask); - THR_SCHED_UNLOCK(curthread, curthread); - - /* - * Run down any pending signals: - */ - if (ret == 0) - _thr_sig_check_pending(curthread); - } else - THR_SCHED_UNLOCK(curthread, curthread); - - if (ret == 0 && oset != NULL) - *oset = oldset; - return (ret); -} diff --git a/lib/libpthread/thread/thr_sigpending.c b/lib/libpthread/thread/thr_sigpending.c deleted file mode 100644 index 5c666bf..0000000 --- a/lib/libpthread/thread/thr_sigpending.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 1999 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 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 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 <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_sigpending); -LT10_COMPAT_DEFAULT(sigpending); - -__weak_reference(_sigpending, sigpending); - -int -_sigpending(sigset_t *set) -{ - struct pthread *curthread = _get_curthread(); - kse_critical_t crit; - sigset_t sigset; - int ret = 0; - - /* Check for a null signal set pointer: */ - if (set == NULL) { - /* Return an invalid argument: */ - ret = EINVAL; - } - else { - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigpending(set)); - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - sigset = curthread->sigpend; - KSE_SCHED_UNLOCK(curthread->kse, curthread->kseg); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_signal_lock); - SIGSETOR(sigset, _thr_proc_sigpending); - KSE_LOCK_RELEASE(curthread->kse, &_thread_signal_lock); - _kse_critical_leave(crit); - *set = sigset; - } - /* Return the completion status: */ - return (ret); -} diff --git a/lib/libpthread/thread/thr_sigprocmask.c b/lib/libpthread/thread/thr_sigprocmask.c deleted file mode 100644 index f646834..0000000 --- a/lib/libpthread/thread/thr_sigprocmask.c +++ /dev/null @@ -1,55 +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 <sys/param.h> -#include <sys/types.h> -#include <sys/signalvar.h> -#include <signal.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_sigprocmask); -LT10_COMPAT_DEFAULT(sigprocmask); - -__weak_reference(_sigprocmask, sigprocmask); - -int -_sigprocmask(int how, const sigset_t *set, sigset_t *oset) -{ - int ret; - - ret = pthread_sigmask(how, set, oset); - if (ret) { - errno = ret; - ret = -1; - } - return (ret); -} diff --git a/lib/libpthread/thread/thr_sigsuspend.c b/lib/libpthread/thread/thr_sigsuspend.c deleted file mode 100644 index 7e56eae..0000000 --- a/lib/libpthread/thread/thr_sigsuspend.c +++ /dev/null @@ -1,110 +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 <sys/types.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <string.h> - -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__sigsuspend); -LT10_COMPAT_PRIVATE(_sigsuspend); -LT10_COMPAT_DEFAULT(sigsuspend); - -__weak_reference(__sigsuspend, sigsuspend); - -int -_sigsuspend(const sigset_t *set) -{ - struct pthread *curthread = _get_curthread(); - sigset_t oldmask, newmask, tempset; - int ret = -1; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sigsuspend(set)); - - /* Check if a new signal set was provided by the caller: */ - if (set != NULL) { - newmask = *set; - SIG_CANTMASK(newmask); - THR_LOCK_SWITCH(curthread); - - /* Save current sigmask: */ - oldmask = curthread->sigmask; - curthread->oldsigmask = &oldmask; - - /* Change the caller's mask: */ - curthread->sigmask = newmask; - tempset = curthread->sigpend; - SIGSETNAND(tempset, newmask); - if (SIGISEMPTY(tempset)) { - THR_SET_STATE(curthread, PS_SIGSUSPEND); - /* Wait for a signal: */ - _thr_sched_switch_unlocked(curthread); - } else { - curthread->check_pending = 1; - THR_UNLOCK_SWITCH(curthread); - /* check pending signal I can handle: */ - _thr_sig_check_pending(curthread); - } - if ((curthread->cancelflags & THR_CANCELLING) != 0) - curthread->oldsigmask = NULL; - else { - THR_ASSERT(curthread->oldsigmask == NULL, - "oldsigmask is not cleared"); - } - - /* Always return an interrupted error: */ - errno = EINTR; - } else { - /* Return an invalid argument error: */ - errno = EINVAL; - } - - /* Return the completion status: */ - return (ret); -} - -int -__sigsuspend(const sigset_t * set) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = _sigsuspend(set); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_sigwait.c b/lib/libpthread/thread/thr_sigwait.c deleted file mode 100644 index 532251c..0000000 --- a/lib/libpthread/thread/thr_sigwait.c +++ /dev/null @@ -1,209 +0,0 @@ -//depot/projects/kse/lib/libpthread/thread/thr_sigwait.c#1 - branch change 15154 (text+ko) -/* - * 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 <signal.h> -#include <sys/param.h> -#include <sys/signalvar.h> -#include <errno.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__sigwait); -LT10_COMPAT_PRIVATE(_sigwait); -LT10_COMPAT_DEFAULT(sigwait); -LT10_COMPAT_PRIVATE(__sigtimedwait); -LT10_COMPAT_PRIVATE(_sigtimedwait); -LT10_COMPAT_DEFAULT(sigtimedwait); -LT10_COMPAT_PRIVATE(__sigwaitinfo); -LT10_COMPAT_PRIVATE(_sigwaitinfo); -LT10_COMPAT_DEFAULT(sigwaitinfo); - -__weak_reference(__sigwait, sigwait); -__weak_reference(__sigtimedwait, sigtimedwait); -__weak_reference(__sigwaitinfo, sigwaitinfo); - -static int -lib_sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - int i; - struct sigwait_data waitdata; - sigset_t waitset; - kse_critical_t crit; - siginfo_t siginfo; - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - if (info == NULL) - info = &siginfo; - return (__sys_sigtimedwait((sigset_t *)set, info, - (struct timespec *)timeout)); - } - - /* - * Initialize the set of signals that will be waited on: - */ - waitset = *set; - - /* These signals can't be waited on. */ - SIGDELSET(waitset, SIGKILL); - SIGDELSET(waitset, SIGSTOP); - - /* - * POSIX says that the _application_ must explicitly install - * a dummy handler for signals that are SIG_IGN in order - * to sigwait on them. Note that SIG_IGN signals are left in - * the mask because a subsequent sigaction could enable an - * ignored signal. - */ - - crit = _kse_critical_enter(); - KSE_SCHED_LOCK(curthread->kse, curthread->kseg); - for (i = 1; i <= _SIG_MAXSIG; ++i) { - if (SIGISMEMBER(waitset, i) && - SIGISMEMBER(curthread->sigpend, i)) { - SIGDELSET(curthread->sigpend, i); - siginfo = curthread->siginfo[i - 1]; - KSE_SCHED_UNLOCK(curthread->kse, - curthread->kseg); - _kse_critical_leave(crit); - ret = i; - goto OUT; - } - } - curthread->timeout = 0; - curthread->interrupted = 0; - _thr_set_timeout(timeout); - /* Wait for a signal: */ - siginfo.si_signo = 0; - waitdata.waitset = &waitset; - waitdata.siginfo = &siginfo; - curthread->data.sigwait = &waitdata; - THR_SET_STATE(curthread, PS_SIGWAIT); - _thr_sched_switch_unlocked(curthread); - /* - * Return the signal number to the caller: - */ - if (siginfo.si_signo > 0) { - ret = siginfo.si_signo; - } else { - if (curthread->interrupted) - errno = EINTR; - else if (curthread->timeout) - errno = EAGAIN; - ret = -1; - } - curthread->timeout = 0; - curthread->interrupted = 0; - /* - * Probably unnecessary, but since it's in a union struct - * we don't know how it could be used in the future. - */ - curthread->data.sigwait = NULL; - -OUT: - if (ret > 0 && info != NULL) - *info = siginfo; - - return (ret); -} - -int -__sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, timeout); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int _sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec * timeout) -{ - return lib_sigtimedwait(set, info, timeout); -} - -int -__sigwaitinfo(const sigset_t *set, siginfo_t *info) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, info, NULL); - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_sigwaitinfo(const sigset_t *set, siginfo_t *info) -{ - return lib_sigtimedwait(set, info, NULL); -} - -int -__sigwait(const sigset_t *set, int *sig) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } - _thr_cancel_leave(curthread, 1); - return (ret); -} - -int -_sigwait(const sigset_t *set, int *sig) -{ - int ret; - - ret = lib_sigtimedwait(set, NULL, NULL); - if (ret > 0) { - *sig = ret; - ret = 0; - } else { - ret = errno; - } - return (ret); -} - diff --git a/lib/libpthread/thread/thr_single_np.c b/lib/libpthread/thread/thr_single_np.c deleted file mode 100644 index 5720006..0000000 --- a/lib/libpthread/thread/thr_single_np.c +++ /dev/null @@ -1,51 +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 <pthread.h> -#include <pthread_np.h> - -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_single_np); -LT10_COMPAT_DEFAULT(pthread_single_np); - -__weak_reference(_pthread_single_np, pthread_single_np); - -int _pthread_single_np() -{ - - /* Enter single-threaded (non-POSIX) scheduling mode: */ - pthread_suspend_all_np(); - /* - * XXX - Do we want to do this? - * __is_threaded = 0; - */ - return (0); -} diff --git a/lib/libpthread/thread/thr_sleep.c b/lib/libpthread/thread/thr_sleep.c deleted file mode 100644 index 0a11876..0000000 --- a/lib/libpthread/thread/thr_sleep.c +++ /dev/null @@ -1,71 +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 <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -extern unsigned int __sleep(unsigned int); -extern int __usleep(useconds_t); - -LT10_COMPAT_PRIVATE(_sleep); -LT10_COMPAT_DEFAULT(sleep); -LT10_COMPAT_PRIVATE(_usleep); -LT10_COMPAT_DEFAULT(usleep); - -__weak_reference(_sleep, sleep); -__weak_reference(_usleep, usleep); - -unsigned int -_sleep(unsigned int seconds) -{ - struct pthread *curthread = _get_curthread(); - unsigned int ret; - - _thr_cancel_enter(curthread); - ret = __sleep(seconds); - _thr_cancel_leave(curthread, 1); - - return (ret); -} - -int -_usleep(useconds_t useconds) -{ - struct pthread *curthread = _get_curthread(); - unsigned int ret; - - _thr_cancel_enter(curthread); - ret = __usleep(useconds); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_spec.c b/lib/libpthread/thread/thr_spec.c deleted file mode 100644 index 6059375..0000000 --- a/lib/libpthread/thread/thr_spec.c +++ /dev/null @@ -1,240 +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 <signal.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <pthread.h> - -#include "thr_private.h" - - -struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX]; - -/* - * XXX - This breaks the linker if LT10_COMPAT_DEFAULT doesn't - * also include a weak reference to the default symbol. - */ -LT10_COMPAT_PRIVATE(_thread_keytable); - -LT10_COMPAT_PRIVATE(_pthread_key_create); -LT10_COMPAT_DEFAULT(pthread_key_create); -LT10_COMPAT_PRIVATE(_pthread_key_delete); -LT10_COMPAT_DEFAULT(pthread_key_delete); -LT10_COMPAT_PRIVATE(_pthread_getspecific); -LT10_COMPAT_DEFAULT(pthread_getspecific); -LT10_COMPAT_PRIVATE(_pthread_setspecific); -LT10_COMPAT_DEFAULT(pthread_setspecific); - -__weak_reference(_pthread_key_create, pthread_key_create); -__weak_reference(_pthread_key_delete, pthread_key_delete); -__weak_reference(_pthread_getspecific, pthread_getspecific); -__weak_reference(_pthread_setspecific, pthread_setspecific); - - -int -_pthread_key_create(pthread_key_t *key, void (*destructor) (void *)) -{ - struct pthread *curthread = _get_curthread(); - int i; - - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - for (i = 0; i < PTHREAD_KEYS_MAX; i++) { - - if (_thread_keytable[i].allocated == 0) { - _thread_keytable[i].allocated = 1; - _thread_keytable[i].destructor = destructor; - _thread_keytable[i].seqno++; - - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - *key = i; - return (0); - } - - } - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - return (EAGAIN); -} - -int -_pthread_key_delete(pthread_key_t key) -{ - struct pthread *curthread = _get_curthread(); - int ret = 0; - - if ((unsigned int)key < PTHREAD_KEYS_MAX) { - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - - if (_thread_keytable[key].allocated) - _thread_keytable[key].allocated = 0; - else - ret = EINVAL; - - /* Unlock the key table: */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - } else - ret = EINVAL; - return (ret); -} - -void -_thread_cleanupspecific(void) -{ - struct pthread *curthread = _get_curthread(); - void (*destructor)( void *); - void *data = NULL; - int key; - int i; - - if (curthread->specific == NULL) - return; - - /* Lock the key table: */ - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - for (i = 0; (i < PTHREAD_DESTRUCTOR_ITERATIONS) && - (curthread->specific_data_count > 0); i++) { - for (key = 0; (key < PTHREAD_KEYS_MAX) && - (curthread->specific_data_count > 0); key++) { - destructor = NULL; - - if (_thread_keytable[key].allocated && - (curthread->specific[key].data != NULL)) { - if (curthread->specific[key].seqno == - _thread_keytable[key].seqno) { - data = (void *) - curthread->specific[key].data; - destructor = _thread_keytable[key].destructor; - } - curthread->specific[key].data = NULL; - curthread->specific_data_count--; - } - - /* - * If there is a destructore, call it - * with the key table entry unlocked: - */ - if (destructor != NULL) { - /* - * Don't hold the lock while calling the - * destructor: - */ - THR_LOCK_RELEASE(curthread, &_keytable_lock); - destructor(data); - THR_LOCK_ACQUIRE(curthread, &_keytable_lock); - } - } - } - THR_LOCK_RELEASE(curthread, &_keytable_lock); - free(curthread->specific); - curthread->specific = NULL; - if (curthread->specific_data_count > 0) - stderr_debug("Thread %p has exited with leftover " - "thread-specific data after %d destructor iterations\n", - curthread, PTHREAD_DESTRUCTOR_ITERATIONS); -} - -static inline struct pthread_specific_elem * -pthread_key_allocate_data(void) -{ - struct pthread_specific_elem *new_data; - - new_data = (struct pthread_specific_elem *) - malloc(sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX); - if (new_data != NULL) { - memset((void *) new_data, 0, - sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX); - } - return (new_data); -} - -int -_pthread_setspecific(pthread_key_t key, const void *value) -{ - struct pthread *pthread; - int ret = 0; - - /* Point to the running thread: */ - pthread = _get_curthread(); - - if ((pthread->specific) || - (pthread->specific = pthread_key_allocate_data())) { - if ((unsigned int)key < PTHREAD_KEYS_MAX) { - if (_thread_keytable[key].allocated) { - if (pthread->specific[key].data == NULL) { - if (value != NULL) - pthread->specific_data_count++; - } else if (value == NULL) - pthread->specific_data_count--; - pthread->specific[key].data = value; - pthread->specific[key].seqno = - _thread_keytable[key].seqno; - ret = 0; - } else - ret = EINVAL; - } else - ret = EINVAL; - } else - ret = ENOMEM; - return (ret); -} - -void * -_pthread_getspecific(pthread_key_t key) -{ - struct pthread *pthread; - void *data; - - /* Point to the running thread: */ - pthread = _get_curthread(); - - /* Check if there is specific data: */ - if (pthread->specific != NULL && (unsigned int)key < PTHREAD_KEYS_MAX) { - /* Check if this key has been used before: */ - if (_thread_keytable[key].allocated && - (pthread->specific[key].seqno == _thread_keytable[key].seqno)) { - /* Return the value: */ - data = (void *) pthread->specific[key].data; - } else { - /* - * This key has not been used before, so return NULL - * instead: - */ - data = NULL; - } - } else - /* No specific data has been created, so just return NULL: */ - data = NULL; - return (data); -} diff --git a/lib/libpthread/thread/thr_spinlock.c b/lib/libpthread/thread/thr_spinlock.c deleted file mode 100644 index 8a6e0d6..0000000 --- a/lib/libpthread/thread/thr_spinlock.c +++ /dev/null @@ -1,149 +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 <sys/types.h> -#include <machine/atomic.h> - -#include <libc_private.h> -#include "spinlock.h" -#include "thr_private.h" - -#define MAX_SPINLOCKS 72 - -struct spinlock_extra { - spinlock_t *owner; - pthread_mutex_t lock; -}; - -static void init_spinlock(spinlock_t *lck); - -static struct pthread_mutex_attr static_mutex_attr = - PTHREAD_MUTEXATTR_STATIC_INITIALIZER; -static pthread_mutexattr_t static_mattr = &static_mutex_attr; - -static pthread_mutex_t spinlock_static_lock; -static struct spinlock_extra extra[MAX_SPINLOCKS]; -static int spinlock_count = 0; -static int initialized = 0; - -LT10_COMPAT_PRIVATE(_spinlock); -LT10_COMPAT_PRIVATE(_spinlock_debug); -LT10_COMPAT_PRIVATE(_spinunlock); - -/* - * These are for compatability only. Spinlocks of this type - * are deprecated. - */ - -void -_spinunlock(spinlock_t *lck) -{ - struct spinlock_extra *extra; - - extra = (struct spinlock_extra *)lck->fname; - _pthread_mutex_unlock(&extra->lock); -} - -/* - * Lock a location for the running thread. Yield to allow other - * threads to run if this thread is blocked because the lock is - * not available. Note that this function does not sleep. It - * assumes that the lock will be available very soon. - */ -void -_spinlock(spinlock_t *lck) -{ - struct spinlock_extra *extra; - - if (!__isthreaded) - PANIC("Spinlock called when not threaded."); - if (!initialized) - PANIC("Spinlocks not initialized."); - /* - * Try to grab the lock and loop if another thread grabs - * it before we do. - */ - if (lck->fname == NULL) - init_spinlock(lck); - extra = (struct spinlock_extra *)lck->fname; - _pthread_mutex_lock(&extra->lock); -} - -/* - * Lock a location for the running thread. Yield to allow other - * threads to run if this thread is blocked because the lock is - * not available. Note that this function does not sleep. It - * assumes that the lock will be available very soon. - * - * This function checks if the running thread has already locked the - * location, warns if this occurs and creates a thread dump before - * returning. - */ -void -_spinlock_debug(spinlock_t *lck, char *fname, int lineno) -{ - _spinlock(lck); -} - -static void -init_spinlock(spinlock_t *lck) -{ - _pthread_mutex_lock(&spinlock_static_lock); - if ((lck->fname == NULL) && (spinlock_count < MAX_SPINLOCKS)) { - lck->fname = (char *)&extra[spinlock_count]; - extra[spinlock_count].owner = lck; - spinlock_count++; - } - _pthread_mutex_unlock(&spinlock_static_lock); - if (lck->fname == NULL) - PANIC("Exceeded max spinlocks"); -} - -void -_thr_spinlock_init(void) -{ - int i; - - if (initialized != 0) { - _thr_mutex_reinit(&spinlock_static_lock); - for (i = 0; i < spinlock_count; i++) - _thr_mutex_reinit(&extra[i].lock); - } else { - if (_pthread_mutex_init(&spinlock_static_lock, &static_mattr)) - PANIC("Cannot initialize spinlock_static_lock"); - for (i = 0; i < MAX_SPINLOCKS; i++) { - if (_pthread_mutex_init(&extra[i].lock, &static_mattr)) - PANIC("Cannot initialize spinlock extra"); - } - initialized = 1; - } -} diff --git a/lib/libpthread/thread/thr_stack.c b/lib/libpthread/thread/thr_stack.c deleted file mode 100644 index f634055..0000000 --- a/lib/libpthread/thread/thr_stack.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org> - * Copyright (c) 2000-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, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must 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 AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (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 <sys/mman.h> -#include <sys/queue.h> -#include <stdlib.h> -#include <pthread.h> -#include "thr_private.h" - -/* Spare thread stack. */ -struct stack { - LIST_ENTRY(stack) qe; /* Stack queue linkage. */ - size_t stacksize; /* Stack size (rounded up). */ - size_t guardsize; /* Guard size. */ - void *stackaddr; /* Stack address. */ -}; - -/* - * Default sized (stack and guard) spare stack queue. Stacks are cached - * to avoid additional complexity managing mmap()ed stack regions. Spare - * stacks are used in LIFO order to increase cache locality. - */ -static LIST_HEAD(, stack) dstackq = LIST_HEAD_INITIALIZER(dstackq); - -/* - * Miscellaneous sized (non-default stack and/or guard) spare stack queue. - * Stacks are cached to avoid additional complexity managing mmap()ed - * stack regions. This list is unordered, since ordering on both stack - * size and guard size would be more trouble than it's worth. Stacks are - * allocated from this cache on a first size match basis. - */ -static LIST_HEAD(, stack) mstackq = LIST_HEAD_INITIALIZER(mstackq); - -/** - * Base address of the last stack allocated (including its red zone, if - * there is one). Stacks are allocated contiguously, starting beyond the - * top of the main stack. When a new stack is created, a red zone is - * typically created (actually, the red zone is mapped with PROT_NONE) above - * the top of the stack, such that the stack will not be able to grow all - * the way to the bottom of the next stack. This isn't fool-proof. It is - * possible for a stack to grow by a large amount, such that it grows into - * the next stack, and as long as the memory within the red zone is never - * accessed, nothing will prevent one thread stack from trouncing all over - * the next. - * - * low memory - * . . . . . . . . . . . . . . . . . . - * | | - * | stack 3 | start of 3rd thread stack - * +-----------------------------------+ - * | | - * | Red Zone (guard page) | red zone for 2nd thread - * | | - * +-----------------------------------+ - * | stack 2 - PTHREAD_STACK_DEFAULT | top of 2nd thread stack - * | | - * | | - * | | - * | | - * | stack 2 | - * +-----------------------------------+ <-- start of 2nd thread stack - * | | - * | Red Zone | red zone for 1st thread - * | | - * +-----------------------------------+ - * | stack 1 - PTHREAD_STACK_DEFAULT | top of 1st thread stack - * | | - * | | - * | | - * | | - * | stack 1 | - * +-----------------------------------+ <-- start of 1st thread stack - * | | (initial value of last_stack) - * | Red Zone | - * | | red zone for main thread - * +-----------------------------------+ - * | USRSTACK - PTHREAD_STACK_INITIAL | top of main thread stack - * | | ^ - * | | | - * | | | - * | | | stack growth - * | | - * +-----------------------------------+ <-- start of main thread stack - * (USRSTACK) - * high memory - * - */ -static void *last_stack = NULL; - -/* - * Round size up to the nearest multiple of - * _thr_page_size. - */ -static inline size_t -round_up(size_t size) -{ - if (size % _thr_page_size != 0) - size = ((size / _thr_page_size) + 1) * - _thr_page_size; - return size; -} - -int -_thr_stack_alloc(struct pthread_attr *attr) -{ - struct stack *spare_stack; - struct kse *curkse; - kse_critical_t crit; - size_t stacksize; - size_t guardsize; - char *stackaddr; - - /* - * Round up stack size to nearest multiple of _thr_page_size so - * that mmap() * will work. If the stack size is not an even - * multiple, we end up initializing things such that there is - * unused space above the beginning of the stack, so the stack - * sits snugly against its guard. - */ - stacksize = round_up(attr->stacksize_attr); - guardsize = round_up(attr->guardsize_attr); - - attr->stackaddr_attr = NULL; - attr->flags &= ~THR_STACK_USER; - - /* - * Use the garbage collector lock for synchronization of the - * spare stack lists and allocations from usrstack. - */ - crit = _kse_critical_enter(); - curkse = _get_curkse(); - KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); - /* - * If the stack and guard sizes are default, try to allocate a stack - * from the default-size stack cache: - */ - if ((stacksize == _thr_stack_default) && - (guardsize == _thr_guard_default)) { - if ((spare_stack = LIST_FIRST(&dstackq)) != NULL) { - /* Use the spare stack. */ - LIST_REMOVE(spare_stack, qe); - attr->stackaddr_attr = spare_stack->stackaddr; - } - } - /* - * The user specified a non-default stack and/or guard size, so try to - * allocate a stack from the non-default size stack cache, using the - * rounded up stack size (stack_size) in the search: - */ - else { - LIST_FOREACH(spare_stack, &mstackq, qe) { - if (spare_stack->stacksize == stacksize && - spare_stack->guardsize == guardsize) { - LIST_REMOVE(spare_stack, qe); - attr->stackaddr_attr = spare_stack->stackaddr; - break; - } - } - } - if (attr->stackaddr_attr != NULL) { - /* A cached stack was found. Release the lock. */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - } - else { - /* Allocate a stack from usrstack. */ - if (last_stack == NULL) - last_stack = _usrstack - _thr_stack_initial - - _thr_guard_default; - - /* Allocate a new stack. */ - stackaddr = last_stack - stacksize - guardsize; - - /* - * Even if stack allocation fails, we don't want to try to - * use this location again, so unconditionally decrement - * last_stack. Under normal operating conditions, the most - * likely reason for an mmap() error is a stack overflow of - * the adjacent thread stack. - */ - last_stack -= (stacksize + guardsize); - - /* Release the lock before mmap'ing it. */ - KSE_LOCK_RELEASE(curkse, &_thread_list_lock); - _kse_critical_leave(crit); - - /* Map the stack and guard page together, and split guard - page from allocated space: */ - if ((stackaddr = mmap(stackaddr, stacksize+guardsize, - PROT_READ | PROT_WRITE, MAP_STACK, - -1, 0)) != MAP_FAILED && - (guardsize == 0 || - mprotect(stackaddr, guardsize, PROT_NONE) == 0)) { - stackaddr += guardsize; - } else { - if (stackaddr != MAP_FAILED) - munmap(stackaddr, stacksize + guardsize); - stackaddr = NULL; - } - attr->stackaddr_attr = stackaddr; - } - if (attr->stackaddr_attr != NULL) - return (0); - else - return (-1); -} - -/* This function must be called with _thread_list_lock held. */ -void -_thr_stack_free(struct pthread_attr *attr) -{ - struct stack *spare_stack; - - if ((attr != NULL) && ((attr->flags & THR_STACK_USER) == 0) - && (attr->stackaddr_attr != NULL)) { - spare_stack = (attr->stackaddr_attr + attr->stacksize_attr - - sizeof(struct stack)); - spare_stack->stacksize = round_up(attr->stacksize_attr); - spare_stack->guardsize = round_up(attr->guardsize_attr); - spare_stack->stackaddr = attr->stackaddr_attr; - - if (spare_stack->stacksize == _thr_stack_default && - spare_stack->guardsize == _thr_guard_default) { - /* Default stack/guard size. */ - LIST_INSERT_HEAD(&dstackq, spare_stack, qe); - } else { - /* Non-default stack/guard size. */ - LIST_INSERT_HEAD(&mstackq, spare_stack, qe); - } - attr->stackaddr_attr = NULL; - } -} diff --git a/lib/libpthread/thread/thr_suspend_np.c b/lib/libpthread/thread/thr_suspend_np.c deleted file mode 100644 index 37ca783..0000000 --- a/lib/libpthread/thread/thr_suspend_np.c +++ /dev/null @@ -1,111 +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 <errno.h> -#include <pthread.h> -#include "thr_private.h" - -static void suspend_common(struct pthread *thread); - -LT10_COMPAT_PRIVATE(_pthread_suspend_np); -LT10_COMPAT_DEFAULT(pthread_suspend_np); -LT10_COMPAT_PRIVATE(_pthread_suspend_all_np); -LT10_COMPAT_DEFAULT(pthread_suspend_all_np); - -__weak_reference(_pthread_suspend_np, pthread_suspend_np); -__weak_reference(_pthread_suspend_all_np, pthread_suspend_all_np); - -/* Suspend a thread: */ -int -_pthread_suspend_np(pthread_t thread) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - /* Suspending the current thread doesn't make sense. */ - if (thread == _get_curthread()) - ret = EDEADLK; - - /* Add a reference to the thread: */ - else if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) - == 0) { - /* Lock the threads scheduling queue: */ - THR_SCHED_LOCK(curthread, thread); - suspend_common(thread); - /* Unlock the threads scheduling queue: */ - THR_SCHED_UNLOCK(curthread, thread); - - /* Don't forget to remove the reference: */ - _thr_ref_delete(curthread, thread); - } - return (ret); -} - -void -_pthread_suspend_all_np(void) -{ - struct pthread *curthread = _get_curthread(); - struct pthread *thread; - kse_critical_t crit; - - /* Take the thread list lock: */ - crit = _kse_critical_enter(); - KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); - - TAILQ_FOREACH(thread, &_thread_list, tle) { - if (thread != curthread) { - THR_SCHED_LOCK(curthread, thread); - suspend_common(thread); - THR_SCHED_UNLOCK(curthread, thread); - } - } - - /* Release the thread list lock: */ - KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); - _kse_critical_leave(crit); -} - -void -suspend_common(struct pthread *thread) -{ - if ((thread->state != PS_DEAD) && - (thread->state != PS_DEADLOCK) && - ((thread->flags & THR_FLAGS_EXITING) == 0)) { - thread->flags |= THR_FLAGS_SUSPENDED; - if ((thread->flags & THR_FLAGS_IN_RUNQ) != 0) { - THR_RUNQ_REMOVE(thread); - THR_SET_STATE(thread, PS_SUSPENDED); - } -#ifdef NOT_YET - if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) - /* ??? */ -#endif - } -} diff --git a/lib/libpthread/thread/thr_switch_np.c b/lib/libpthread/thread/thr_switch_np.c deleted file mode 100644 index 247b879..0000000 --- a/lib/libpthread/thread/thr_switch_np.c +++ /dev/null @@ -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 <errno.h> -#include <pthread.h> -#include <pthread_np.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_pthread_switch_add_np); -LT10_COMPAT_DEFAULT(pthread_switch_add_np); -LT10_COMPAT_PRIVATE(_pthread_switch_delete_np); -LT10_COMPAT_DEFAULT(pthread_switch_delete_np); - -__weak_reference(_pthread_switch_add_np, pthread_switch_add_np); -__weak_reference(_pthread_switch_delete_np, pthread_switch_delete_np); - -int -_pthread_switch_add_np(pthread_switch_routine_t routine) -{ - return (ENOTSUP); -} - -int -_pthread_switch_delete_np(pthread_switch_routine_t routine) -{ - return (ENOTSUP); -} diff --git a/lib/libpthread/thread/thr_symbols.c b/lib/libpthread/thread/thr_symbols.c deleted file mode 100644 index 248fad9..0000000 --- a/lib/libpthread/thread/thr_symbols.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2004 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. - * 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 <sys/types.h> -#include <stddef.h> -#include <pthread.h> -#include <rtld.h> - -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_thread_off_tcb); -LT10_COMPAT_PRIVATE(_thread_off_tmbx); -LT10_COMPAT_PRIVATE(_thread_off_next); -LT10_COMPAT_PRIVATE(_thread_off_attr_flags); -LT10_COMPAT_PRIVATE(_thread_off_kse); -LT10_COMPAT_PRIVATE(_thread_off_kse_locklevel); -LT10_COMPAT_PRIVATE(_thread_off_thr_locklevel); -LT10_COMPAT_PRIVATE(_thread_off_linkmap); -LT10_COMPAT_PRIVATE(_thread_off_tlsindex); -LT10_COMPAT_PRIVATE(_thread_size_key); -LT10_COMPAT_PRIVATE(_thread_off_key_allocated); -LT10_COMPAT_PRIVATE(_thread_off_key_destructor); -LT10_COMPAT_PRIVATE(_thread_max_keys); -LT10_COMPAT_PRIVATE(_thread_off_dtv); -LT10_COMPAT_PRIVATE(_thread_off_state); -LT10_COMPAT_PRIVATE(_thread_state_running); -LT10_COMPAT_PRIVATE(_thread_state_zoombie); - -/* A collection of symbols needed by debugger */ - -/* int _libkse_debug */ -int _thread_off_tcb = offsetof(struct pthread, tcb); -int _thread_off_tmbx = offsetof(struct tcb, tcb_tmbx); -int _thread_off_next = offsetof(struct pthread, tle.tqe_next); -int _thread_off_attr_flags = offsetof(struct pthread, attr.flags); -int _thread_off_kse = offsetof(struct pthread, kse); -int _thread_off_kse_locklevel = offsetof(struct kse, k_locklevel); -int _thread_off_thr_locklevel = offsetof(struct pthread, locklevel); -int _thread_off_linkmap = offsetof(Obj_Entry, linkmap); -int _thread_off_tlsindex = offsetof(Obj_Entry, tlsindex); -int _thread_size_key = sizeof(struct pthread_key); -int _thread_off_key_allocated = offsetof(struct pthread_key, allocated); -int _thread_off_key_destructor = offsetof(struct pthread_key, destructor); -int _thread_max_keys = PTHREAD_KEYS_MAX; -int _thread_off_dtv = DTV_OFFSET; -int _thread_off_state = offsetof(struct pthread, state); -int _thread_state_running = PS_RUNNING; -int _thread_state_zoombie = PS_DEAD; -int _thread_off_sigmask = offsetof(struct pthread, sigmask); -int _thread_off_sigpend = offsetof(struct pthread, sigpend); diff --git a/lib/libpthread/thread/thr_system.c b/lib/libpthread/thread/thr_system.c deleted file mode 100644 index 5e4fe1c..0000000 --- a/lib/libpthread/thread/thr_system.c +++ /dev/null @@ -1,54 +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 <stdlib.h> -#include <pthread.h> -#include "thr_private.h" - -extern int __system(const char *); - -LT10_COMPAT_PRIVATE(_system); -LT10_COMPAT_DEFAULT(system); - -__weak_reference(_system, system); - -int -_system(const char *string) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __system(string); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_tcdrain.c b/lib/libpthread/thread/thr_tcdrain.c deleted file mode 100644 index e231d52..0000000 --- a/lib/libpthread/thread/thr_tcdrain.c +++ /dev/null @@ -1,54 +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 <termios.h> -#include <pthread.h> -#include "thr_private.h" - -extern int __tcdrain(int); - -LT10_COMPAT_PRIVATE(_tcdrain); -LT10_COMPAT_DEFAULT(tcdrain); - -__weak_reference(_tcdrain, tcdrain); - -int -_tcdrain(int fd) -{ - struct pthread *curthread = _get_curthread(); - int ret; - - _thr_cancel_enter(curthread); - ret = __tcdrain(fd); - _thr_cancel_leave(curthread, 1); - - return (ret); -} diff --git a/lib/libpthread/thread/thr_vfork.c b/lib/libpthread/thread/thr_vfork.c deleted file mode 100644 index 428c129..0000000 --- a/lib/libpthread/thread/thr_vfork.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * $FreeBSD$ - */ -#include <unistd.h> - -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_vfork); -LT10_COMPAT_DEFAULT(vfork); - -__weak_reference(_vfork, vfork); - -int -_vfork(void) -{ - return (fork()); -} diff --git a/lib/libpthread/thread/thr_wait.c b/lib/libpthread/thread/thr_wait.c deleted file mode 100644 index 8f61a0c..0000000 --- a/lib/libpthread/thread/thr_wait.c +++ /dev/null @@ -1,53 +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 <pthread.h> -#include "thr_private.h" - -extern int __wait(int *); - -LT10_COMPAT_PRIVATE(_wait); -LT10_COMPAT_DEFAULT(wait); - -__weak_reference(_wait, wait); - -pid_t -_wait(int *istat) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = __wait(istat); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_wait4.c b/lib/libpthread/thread/thr_wait4.c deleted file mode 100644 index 6810e65..0000000 --- a/lib/libpthread/thread/thr_wait4.c +++ /dev/null @@ -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 <sys/types.h> - -#include "namespace.h" -#include <errno.h> -#include <sys/wait.h> -#include <pthread.h> -#include "un-namespace.h" - -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__wait4); -LT10_COMPAT_DEFAULT(wait4); - -__weak_reference(__wait4, wait4); - -pid_t -__wait4(pid_t pid, int *istat, int options, struct rusage *rusage) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = _wait4(pid, istat, options, rusage); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_waitpid.c b/lib/libpthread/thread/thr_waitpid.c deleted file mode 100644 index 1244c12..0000000 --- a/lib/libpthread/thread/thr_waitpid.c +++ /dev/null @@ -1,55 +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 <sys/types.h> -#include <sys/wait.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_waitpid); -LT10_COMPAT_DEFAULT(waitpid); - -extern int __waitpid(pid_t, int *, int); - -__weak_reference(_waitpid, waitpid); - -pid_t -_waitpid(pid_t wpid, int *status, int options) -{ - struct pthread *curthread = _get_curthread(); - pid_t ret; - - _thr_cancel_enter(curthread); - ret = __waitpid(wpid, status, options); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_write.c b/lib/libpthread/thread/thr_write.c deleted file mode 100644 index 6596540..0000000 --- a/lib/libpthread/thread/thr_write.c +++ /dev/null @@ -1,56 +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 <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__write); -LT10_COMPAT_DEFAULT(write); - -__weak_reference(__write, write); - -ssize_t -__write(int fd, const void *buf, size_t nbytes) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_write(fd, buf, nbytes); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_writev.c b/lib/libpthread/thread/thr_writev.c deleted file mode 100644 index 9cda908..0000000 --- a/lib/libpthread/thread/thr_writev.c +++ /dev/null @@ -1,58 +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 <sys/types.h> -#include <sys/fcntl.h> -#include <sys/uio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(__writev); -LT10_COMPAT_DEFAULT(writev); - -__weak_reference(__writev, writev); - -ssize_t -__writev(int fd, const struct iovec *iov, int iovcnt) -{ - struct pthread *curthread = _get_curthread(); - ssize_t ret; - - _thr_cancel_enter(curthread); - ret = __sys_writev(fd, iov, iovcnt); - _thr_cancel_leave(curthread, 1); - - return ret; -} diff --git a/lib/libpthread/thread/thr_yield.c b/lib/libpthread/thread/thr_yield.c deleted file mode 100644 index 7665ac6..0000000 --- a/lib/libpthread/thread/thr_yield.c +++ /dev/null @@ -1,75 +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 <pthread.h> -#include "thr_private.h" - -LT10_COMPAT_PRIVATE(_sched_yield); -LT10_COMPAT_DEFAULT(sched_yield); -LT10_COMPAT_PRIVATE(_pthread_yield); -LT10_COMPAT_DEFAULT(pthread_yield); - -__weak_reference(_sched_yield, sched_yield); -__weak_reference(_pthread_yield, pthread_yield); - -int -_sched_yield(void) -{ - struct pthread *curthread = _get_curthread(); - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - return (__sys_sched_yield()); - - /* Reset the accumulated time slice value for the current thread: */ - curthread->slice_usec = -1; - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); - /* Always return no error. */ - return(0); -} - -/* Draft 4 yield */ -void -_pthread_yield(void) -{ - struct pthread *curthread = _get_curthread(); - - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { - __sys_sched_yield(); - return; - } - - /* Reset the accumulated time slice value for the current thread: */ - curthread->slice_usec = -1; - - /* Schedule the next thread: */ - _thr_sched_switch(curthread); -} |