diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2011-10-17 06:39:21 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2011-10-17 06:39:21 +0000 |
commit | 82cbd469f12cd3a22be520db0de2ead1449f271e (patch) | |
tree | 7f405c5d2faa96148d6ed5ebe126425e978967c4 /lib/librthread | |
parent | 2f6d2040683851ec94ddc66982fcddb408ea5eb2 (diff) |
Use __tfork, __get_tcb, and __set_tcb to have a real TCB and per-thread
errno. The ASM bits for _cerror are sketchy or missing for some archs
but that can be corrected in-tree.
Diffstat (limited to 'lib/librthread')
27 files changed, 876 insertions, 101 deletions
diff --git a/lib/librthread/Makefile b/lib/librthread/Makefile index 7cea80a12a4..c8670e4abbe 100644 --- a/lib/librthread/Makefile +++ b/lib/librthread/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.15 2010/02/03 20:49:00 miod Exp $ +# $OpenBSD: Makefile,v 1.16 2011/10/17 06:39:20 guenther Exp $ LIB=rthread WANTLINT= @@ -7,13 +7,16 @@ LIBCSRCDIR= ${.CURDIR}/../libc CFLAGS+=-Wall -g -Werror -Wshadow CFLAGS+=-Wstrict-prototypes -Wmissing-prototypes -Wsign-compare -CFLAGS+=-I${LIBCSRCDIR}/include +CFLAGS+=-I${LIBCSRCDIR}/arch/${MACHINE_CPU} -I${LIBCSRCDIR}/include .PATH: ${.CURDIR}/arch/${MACHINE_CPU} SRCS= rthread.c rthread_attr.c rthread_sched.c rthread_sync.c rthread_tls.c \ rthread_sig.c rthread_np.c rthread_debug.c rthread_stack.c \ rthread_libc.c rthread_fork.c rthread_file.c -OBJS+= _atomic_lock.o rfork_thread.o +OBJS+= _atomic_lock.o rfork_thread.o cerror.o + +MAN+= __tfork_thread.3 +MLINKS+=__tfork_thread.3 __tfork.2 .include <bsd.lib.mk> diff --git a/lib/librthread/__tfork_thread.3 b/lib/librthread/__tfork_thread.3 new file mode 100644 index 00000000000..1f8ee967431 --- /dev/null +++ b/lib/librthread/__tfork_thread.3 @@ -0,0 +1,138 @@ +.\" $OpenBSD: __tfork_thread.3,v 1.1 2011/10/17 06:39:20 guenther Exp $ +.\" +.\" Copyright (c) 2011 Philip Guenther <guenther@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: October 17 2011 $ +.Dt __TFORK_THREAD 3 +.Os +.Sh NAME +.Nm __tfork_thread , +.Nm __tfork +.Nd create a new kernel thread in the current process +.Sh SYNOPSIS +.In sys/unistd.h +.Bd -literal +struct __tfork { + void *tf_tcb; /* TCB address for new thread */ + pid_t *tf_tid; /* where to write child's TID */ + int tf_flags; /* must be zero */ +}; +.Ed +.Pp +.Ft int +.Fn __tfork_thread "const struct __tfork *params" "void *stack" "void (*startfunc)(void *)" "void *startarg" +.Ft int +.Fn __tfork "const struct __tfork *params" +.Sh DESCRIPTION +The +.Fn __tfork_thread +function creates a new kernel thread in the current process. +The new thread's initial stack pointer is set to +.Fa stack +and it calls +.Fa startfunc , +passing +.Fa startarg +as the only argument. +If +.Fa startfunc +returns, the thread will exit. +.Pp +The +.Fa params +argument provides parameters used by the kernel during thread creation. +The new thread's thread control block (TCB) address is set to +.Em tf_tcb . +If +.Em tf_tid +is not NULL, the new thread's PID is returned to the user at that +address, with the guarantee that this is done before returning to +userspace in either the current thread or the new thread. +Currently, +.Em tf_flags +must be set to zero. +.Pp +The underlying system call used to create the thread is +.Fn __tfork . +Because the new thread returns on the same stack as the current thread, +the sycall cannot be directly used from C and is therefore not +provided as a function. +However, the syscall may show up in the output of +.Xr kdump 1 . +.Sh RETURN VALUES +Upon successful completion, +.Fn __tfork_thread +returns in the current thread the PID of new thread. +The +.Fn __tfork +syscall itself, on success, returns a value of 0 in the new thread +and returns the PID of the new thread to the current thread. +Otherwise, a value of -1 is returned, no thread is created, and the +global variable +.Va errno +is set to indicate an error. +.Sh ERRORS +.Fn __tfork_thread +and +.Fn __tfork +will fail and no thread will be created if: +.Bl -tag -width Er +.It Bq Er ENOMEM +Cannot allocate memory. +The new process image required more memory than was allowed by the hardware or +by system-imposed memory management constraints. +A lack of swap space is normally temporary; however, a lack of core is not. +Soft limits may be increased to their corresponding hard limits. +.It Bq Er EINVAL +Invalid argument. +Some invalid argument was supplied. +.It Bq Er EAGAIN +Resource temporarily unavailable. +The system-imposed limit on the total +number of threads under execution would be exceeded. +This limit is configuration-dependent. +.It Bq Er EAGAIN +Resource temporarily unavailable. +The system-imposed limit +.Dv MAXUPRC +on the total number of threads under execution by a single user would be +exceeded. +.Dv MAXUPRC +is currently defined in +.Aq Pa sys/param.h +as +.Dv CHILD_MAX , +which is currently defined as 80 in +.Aq Pa sys/syslimits.h . +.It Bq Er ENOTSUP +The kern.rthreads sysctl was not enabled. +.El +.Sh SEE ALSO +.Xr rfork 2 +.Sh STANDARDS +The +.Fn __tfork_thread +function and +.Fn __tfork +syscall are specific to +.Ox +and should not be used in portable applications. +.Sh HISTORY +The +.Fn __tfork_thread +function and +.Fn __tfork +syscall appeared in +.Ox 5.1 . diff --git a/lib/librthread/arch/alpha/cerror.S b/lib/librthread/arch/alpha/cerror.S new file mode 100644 index 00000000000..af21adebee7 --- /dev/null +++ b/lib/librthread/arch/alpha/cerror.S @@ -0,0 +1,54 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/* $NetBSD: cerror.S,v 1.3 1996/10/17 03:08:17 cgd Exp $ */ + +/* + * Copyright (c) 1994, 1995 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include "SYS.h" + +#define FRAME_SIZE 16 +#define FRAME_RA_OFFSET 0 +#define FRAME_V0_OFFSET 8 + +NESTED(__cerror, 0, FRAME_SIZE, ra, IM_RA|IM_V0, 0) +LEAF_NOPROFILE(__cerror, 0) + br t0, L1 +L1: LDGP(t0) + + lda sp, -FRAME_SIZE(sp) + stq ra, FRAME_RA_OFFSET(sp) + stq v0, FRAME_V0_OFFSET(sp) + + CALL(__errno) + + ldq t0, FRAME_V0_OFFSET(sp) + stl t0, 0(v0) + ldiq v0, -1 + ldq ra, FRAME_RA_OFFSET(sp) + lda sp, FRAME_SIZE(sp) + RET +END(__cerror) diff --git a/lib/librthread/arch/alpha/rfork_thread.S b/lib/librthread/arch/alpha/rfork_thread.S index 8bbe879967d..3205958f6a9 100644 --- a/lib/librthread/arch/alpha/rfork_thread.S +++ b/lib/librthread/arch/alpha/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.2 2005/12/25 00:21:59 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.3 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,12 +28,12 @@ #include "../../../libc/arch/alpha/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); */ -LEAF(rfork_thread,0) +LEAF(__tfork_thread,0) /* a0 = flags, a1 = stack, a2 = func, a3 = arg */ mov a3, a5 - CALLSYS_ERROR(rfork) + CALLSYS_ERROR(__tfork) beq v0, 1f @@ -54,4 +54,4 @@ LEAF(rfork_thread,0) mov zero, a0 CALLSYS_NOERROR(threxit) -END(rfork_thread) +END(__tfork_thread) diff --git a/lib/librthread/arch/amd64/cerror.S b/lib/librthread/arch/amd64/cerror.S new file mode 100644 index 00000000000..2d9fe89d6e0 --- /dev/null +++ b/lib/librthread/arch/amd64/cerror.S @@ -0,0 +1,55 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/* $NetBSD: cerror.S,v 1.2 2002/06/03 18:30:33 fvdl Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + * + * from: @(#)cerror.s 5.1 (Berkeley) 4/23/90 + */ + +#include <machine/asm.h> + +#include "SYS.h" + +#define ERRNOPTR_OFFSET 24 + +_ENTRY(CERROR) + movq %fs:(ERRNOPTR_OFFSET), %rcx + movl %eax, (%rcx) + movq $-1,%rax + ret + +#if 0 /* generic code works */ +NENTRY(__errno) + movq %fs:(ERRNOPTR_OFFSET),%rax + ret +#endif + diff --git a/lib/librthread/arch/amd64/rfork_thread.S b/lib/librthread/arch/amd64/rfork_thread.S index 636e60724f7..77b62ef8005 100644 --- a/lib/librthread/arch/amd64/rfork_thread.S +++ b/lib/librthread/arch/amd64/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.4 2011/10/13 01:07:01 guenther Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.5 2011/10/17 06:39:20 guenther Exp $ */ /*- * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu> @@ -38,23 +38,23 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/amd64/gen/rfork_thread.S,v 1.1 #include "../../../libc/arch/amd64/SYS.h" /* - * %edi %rsi %rdx %rcx - * rfork_thread(flags, stack_addr, start_fnc, start_arg); + * %rdi %rsi %rdx %rcx + * __tfork_thread(param, stack_addr, start_fnc, start_arg); * - * flags: Flags to rfork system call. See rfork(2). + * param: Argument to pass to the actual kernel call. * stack_addr: Top of stack for thread. * start_fnc: Address of thread function to call in child. * start_arg: Argument to pass to the thread function in child. */ -ENTRY(rfork_thread) +ENTRY(__tfork_thread) movq %rdx, %r8 movq %rcx, %r9 /* * Prepare and execute the thread creation syscall */ - movl $SYS_rfork, %eax + movl $SYS___tfork, %eax syscall jb 2f diff --git a/lib/librthread/arch/arm/cerror.S b/lib/librthread/arch/arm/cerror.S new file mode 100644 index 00000000000..08dc3706739 --- /dev/null +++ b/lib/librthread/arch/arm/cerror.S @@ -0,0 +1,44 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/* $NetBSD: cerror.S,v 1.5 2003/08/07 16:42:04 agc Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + * + * from: @(#)cerror.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +_ENTRY(CERROR) + stmfd sp!, {r4, lr} + mov r4, r0 + bl PIC_SYM(_C_LABEL(_errno), PLT) + str r4, [r0] + mvn r0, #0x00000000 + mvn r1, #0x00000000 + ldmfd sp!, {r4, pc} diff --git a/lib/librthread/arch/arm/rfork_thread.S b/lib/librthread/arch/arm/rfork_thread.S index 34bec22d5bc..a631b1b8ce3 100644 --- a/lib/librthread/arch/arm/rfork_thread.S +++ b/lib/librthread/arch/arm/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.2 2005/12/31 21:11:49 drahn Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.3 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> * @@ -19,16 +19,16 @@ #include "../../../libc/arch/arm/SYS.h" /* - * r0 r1 r2 r3 - * rfork_thread(flags, stack_addr, start_fnc, start_arg); + * r0 r1 r2 r3 + * __tfork_thread(param, stack_addr, start_fnc, start_arg); */ -ENTRY(rfork_thread) +ENTRY(__tfork_thread) stmdb sp!, {r4} mov r4, r1 - SYSTRAP(rfork) + SYSTRAP(__tfork) bcs 1f /* check if we are parent or child */ diff --git a/lib/librthread/arch/hppa/rfork_thread.S b/lib/librthread/arch/hppa/rfork_thread.S index d10f09300d5..c98d4ee3bac 100644 --- a/lib/librthread/arch/hppa/rfork_thread.S +++ b/lib/librthread/arch/hppa/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.1 2005/12/28 19:11:25 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.2 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,10 +28,10 @@ #include "../../../libc/arch/hppa/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(param, void *stack, void (*func)(void *), void *arg); */ -ENTRY(rfork_thread, 0) - SYSCALL(rfork) +ENTRY(__tfork_thread, 0) + SYSCALL(__tfork) comb,<> r0, ret0, 1f nop @@ -62,4 +62,4 @@ ENTRY(rfork_thread, 0) bv r0(rp) nop -EXIT(rfork_thread) +EXIT(__tfork_thread) diff --git a/lib/librthread/arch/i386/cerror.S b/lib/librthread/arch/i386/cerror.S new file mode 100644 index 00000000000..e2a298b83c8 --- /dev/null +++ b/lib/librthread/arch/i386/cerror.S @@ -0,0 +1,49 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + */ + +#include "SYS.h" + +#define ERRNOPTR_OFFSET 12 + +_ENTRY(CERROR) + movl %gs:(ERRNOPTR_OFFSET),%ecx + movl %eax,(%ecx) + movl $-1,%eax + movl $-1,%edx + ret + +#if 0 /* generic code works */ +NENTRY(__errno) + movl %gs:(ERRNOPTR_OFFSET),%eax + ret +#endif diff --git a/lib/librthread/arch/i386/rfork_thread.S b/lib/librthread/arch/i386/rfork_thread.S index e86484a13c2..1bc1d3e9e32 100644 --- a/lib/librthread/arch/i386/rfork_thread.S +++ b/lib/librthread/arch/i386/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.3 2009/09/27 22:52:16 guenther Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.4 2011/10/17 06:39:20 guenther Exp $ */ /*- * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> * All rights reserved. @@ -38,15 +38,15 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/i386/gen/rfork_thread.S,v 1.5 2 /* * 8 12 16 20 - * rfork_thread(flags, stack_addr, start_fnc, start_arg); + * __tfork_thread(param, stack_addr, start_fnc, start_arg); * - * flags: Flags to rfork system call. See rfork(2). + * param: Arguments to actual system call. * stack_addr: Top of stack for thread. * start_fnc: Address of thread function to call in child. * start_arg: Argument to pass to the thread function in child. */ -ENTRY(rfork_thread) +ENTRY(__tfork_thread) pushl %ebp movl %esp, %ebp pushl %esi @@ -69,7 +69,7 @@ ENTRY(rfork_thread) */ pushl 8(%ebp) pushl $0 - movl $SYS_rfork, %eax + movl $SYS___tfork, %eax int $0x80 jb 2f diff --git a/lib/librthread/arch/m68k/cerror.S b/lib/librthread/arch/m68k/cerror.S new file mode 100644 index 00000000000..0705a4aa841 --- /dev/null +++ b/lib/librthread/arch/m68k/cerror.S @@ -0,0 +1,53 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + */ + +#include "SYS.h" + + .even + .globl ___errno +__cerror: + movl d0,sp@- +#ifdef PIC + movl #__GLOBAL_OFFSET_TABLE_,a0 + lea pc@(0,a0:l),a0 + movl a0@(___errno:l),a0 + jsr a0@ +#else + jbsr ___errno +#endif + movl d0,a0 + movl sp@+,a0@ + movl #-1,d0 + movl #-1,d1 + rts diff --git a/lib/librthread/arch/m68k/rfork_thread.S b/lib/librthread/arch/m68k/rfork_thread.S index e9b37eb2f8f..80c682baf50 100644 --- a/lib/librthread/arch/m68k/rfork_thread.S +++ b/lib/librthread/arch/m68k/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.1 2005/12/23 18:50:23 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.2 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,9 +28,9 @@ #include "../../../libc/arch/m68k/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); */ -ENTRY(rfork_thread) +ENTRY(__tfork_thread) /* * Set up the new thread's stack. */ @@ -42,7 +42,7 @@ ENTRY(rfork_thread) * We did not create a frame, so the stack is ready for an immediate * system call invocation. */ - __DO_SYSCALL(rfork) + __DO_SYSCALL(__tfork) jcs 9f tstl d0 diff --git a/lib/librthread/arch/m88k/rfork_thread.S b/lib/librthread/arch/m88k/rfork_thread.S index 77afd78838d..2c820232a40 100644 --- a/lib/librthread/arch/m88k/rfork_thread.S +++ b/lib/librthread/arch/m88k/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.1 2005/12/23 20:08:27 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.2 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,11 +28,11 @@ #include "../../../libc/arch/m88k/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); */ -ENTRY(rfork_thread) +ENTRY(__tfork_thread) or r6, r3, r0 /* save stack */ - or r13, r0, __SYSCALLNAME(SYS_,rfork) + or r13, r0, __SYSCALLNAME(SYS_,__tfork) tb0 0, r0, 128 /* corrupts r2 and r3 in the child */ br __cerror diff --git a/lib/librthread/arch/mips64/rfork_thread.S b/lib/librthread/arch/mips64/rfork_thread.S index 14db8ab8a20..32ee5307bee 100644 --- a/lib/librthread/arch/mips64/rfork_thread.S +++ b/lib/librthread/arch/mips64/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.1 2005/12/24 12:01:26 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.2 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,17 +28,17 @@ #include "../../../libc/arch/mips64/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); */ -LEAF(rfork_thread, 32) +LEAF(__tfork_thread, 32) /* a0 = flags, a1 = stack, a2 = func, a3 = arg */ PTR_SUBU sp, 32 - SETUP_GP64(16, _C_LABEL(rfork_thread)) + SETUP_GP64(16, _C_LABEL(__tfork_thread)) move t0, a1 /* stack */ move t1, a3 /* arg */ - __DO_SYSCALL(rfork) + __DO_SYSCALL(__tfork) bnez a3, 9f RESTORE_GP64 @@ -76,4 +76,4 @@ LEAF(rfork_thread, 32) PTR_ADDU sp, 32 jr t9 nop -END(rfork_thread) +END(__tfork_thread) diff --git a/lib/librthread/arch/powerpc/rfork_thread.S b/lib/librthread/arch/powerpc/rfork_thread.S index 15e0667e12f..5731553fbe7 100644 --- a/lib/librthread/arch/powerpc/rfork_thread.S +++ b/lib/librthread/arch/powerpc/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.3 2006/01/05 16:09:39 otto Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.4 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005 Tim Wiess <tim@nop.cx> @@ -19,7 +19,7 @@ #include <sys/syscall.h> #include <machine/asm.h> -ENTRY(rfork_thread) +ENTRY(__tfork_thread) /* sanity check */ cmpwi %r4, 0 beq 1f @@ -28,8 +28,8 @@ ENTRY(rfork_thread) mr %r7,%r4 - /* call rfork */ - li %r0, SYS_rfork + /* call __tfork */ + li %r0, SYS___tfork sc cmpwi %r0, 0 bne 2f diff --git a/lib/librthread/arch/sh/cerror.S b/lib/librthread/arch/sh/cerror.S new file mode 100644 index 00000000000..1f19e2846d5 --- /dev/null +++ b/lib/librthread/arch/sh/cerror.S @@ -0,0 +1,58 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/* $NetBSD: cerror.S,v 1.10 2006/01/06 05:14:39 uwe Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + * + * from: @(#)cerror.s 5.1 (Berkeley) 4/23/90 + */ + +#include "SYS.h" + +NASENTRY(CERROR) + mov.l .L___errno, r1 + PIC_PROLOGUE(.L_got) + sts.l pr, @-sp +1: CALL r1 + mov.l r4, @-sp ! save error code + mov.l @sp+, r4 + lds.l @sp+, pr + PIC_EPILOGUE + mov.l r4, @r0 + mov #-1, r1 + rts + mov #-1, r0 + + .align 2 +.L_got: PIC_GOT_DATUM +.L___errno: CALL_DATUM(_C_LABEL(_errno), 1b) + SET_ASENTRY_SIZE(CERROR) + diff --git a/lib/librthread/arch/sh/rfork_thread.S b/lib/librthread/arch/sh/rfork_thread.S index 80fdf2c3cad..fb6002477fc 100644 --- a/lib/librthread/arch/sh/rfork_thread.S +++ b/lib/librthread/arch/sh/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.1 2007/03/24 18:21:34 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.2 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2007 Miodrag Vallat. @@ -20,11 +20,11 @@ #include "../../../libc/arch/sh/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); - * r4 r5 r6 r7 + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * r4 r5 r6 r7 */ -ENTRY(rfork_thread) - mov.l .LSYS_rfork, r0 +ENTRY(__tfork_thread) + mov.l .LSYS___tfork, r0 .word 0xc380 /* trapa #0x80 */ bf 9f @@ -55,7 +55,7 @@ ENTRY(rfork_thread) JUMP_CERROR .align 2 -.LSYS_rfork: .long SYS_rfork +.LSYS___tfork: .long SYS___tfork .LSYS_threxit: .long SYS_threxit - SET_ENTRY_SIZE(rfork_thread) + SET_ENTRY_SIZE(__tfork_thread) diff --git a/lib/librthread/arch/sparc/cerror.S b/lib/librthread/arch/sparc/cerror.S new file mode 100644 index 00000000000..92b85f0338a --- /dev/null +++ b/lib/librthread/arch/sparc/cerror.S @@ -0,0 +1,51 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + */ + +#include "SYS.h" + +#define ERRNOPTR_OFFSET 12 + + .globl _C_LABEL(errno) +FUNC(_C_LABEL(__cerror)) + ld [%g7 + ERRNOPTR_OFFSET], %g1 + st %o0, [%g1] + mov -1, %o0 + retl + mov -1, %o1 + +#if 0 /* generic code works */ +NENTRY(__errno) + retl + ld [%g7 + ERRNOPTR_OFFSET], %o0 +#endif diff --git a/lib/librthread/arch/sparc/rfork_thread.S b/lib/librthread/arch/sparc/rfork_thread.S index a7dc8135e88..fc4b4f998c7 100644 --- a/lib/librthread/arch/sparc/rfork_thread.S +++ b/lib/librthread/arch/sparc/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.1 2005/12/25 16:00:02 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.2 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,16 +28,16 @@ #include "../../../libc/arch/sparc/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); */ -ENTRY(rfork_thread) +ENTRY(__tfork_thread) mov %o1, %o4 /* save stack */ /* - * We can not invoke rfork as a G2-style system call since we want + * We can not invoke __tfork as a G2-style system call since we want * different return paths. - */ - mov SYS_rfork, %g1 + */ + mov SYS___tfork, %g1 t ST_SYSCALL bcs 9f nop @@ -58,7 +58,8 @@ ENTRY(rfork_thread) * Don't forget to allocate room for a window save on the new * stack! */ - sub %o4, 64, %sp /* stack */ + sub %g0, %g0, %fp + sub %o4, 96, %sp /* stack */ call %o2 /* func */ mov %o3, %o0 /* arg */ diff --git a/lib/librthread/arch/sparc64/cerror.S b/lib/librthread/arch/sparc64/cerror.S new file mode 100644 index 00000000000..18c4663bd44 --- /dev/null +++ b/lib/librthread/arch/sparc64/cerror.S @@ -0,0 +1,54 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + */ + +#include <machine/asm.h> + +#include "SYS.h" + +#define ERRNOPTR_OFFSET 24 + + .globl _C_LABEL(errno) +FUNC(__cerror) + ldx [%g7 + ERRNOPTR_OFFSET], %g1 + st %o0, [%g1] + mov -1, %o0 + retl + mov -1, %o1 + +#if 0 /* generic code works */ +FUNC(__errno) + retl + ldx [%g7 + ERRNOPTR_OFFSET], %o0 +#endif diff --git a/lib/librthread/arch/sparc64/rfork_thread.S b/lib/librthread/arch/sparc64/rfork_thread.S index 9df22a351a0..d35f6ba1d74 100644 --- a/lib/librthread/arch/sparc64/rfork_thread.S +++ b/lib/librthread/arch/sparc64/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.2 2011/10/13 05:29:51 guenther Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.3 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,16 +28,16 @@ #include "../../../libc/arch/sparc64/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); */ -ENTRY(rfork_thread) +ENTRY(__tfork_thread) mov %o1, %o4 /* save stack */ /* - * We can not invoke rfork as a G2-style system call since we want + * We can not invoke __tfork as a G2-style system call since we want * different return paths. - */ - mov SYS_rfork, %g1 + */ + mov SYS___tfork, %g1 t ST_SYSCALL bcs 9f nop diff --git a/lib/librthread/arch/vax/cerror.S b/lib/librthread/arch/vax/cerror.S new file mode 100644 index 00000000000..b5c468deeac --- /dev/null +++ b/lib/librthread/arch/vax/cerror.S @@ -0,0 +1,40 @@ +/* $OpenBSD: cerror.S,v 1.1 2011/10/17 06:39:20 guenther Exp $ */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must 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 University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED 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. + */ + +#include "SYS.h" + + .globl _C_LABEL(__errno) +_C_LABEL(_cerror): + pushl r0 + calls $0, _C_LABEL(__errno) + movl (sp)+, (r0) + mnegl $1,r0 + movl r0,r1 + ret diff --git a/lib/librthread/arch/vax/rfork_thread.S b/lib/librthread/arch/vax/rfork_thread.S index 85648cb8918..a7e6259b9e0 100644 --- a/lib/librthread/arch/vax/rfork_thread.S +++ b/lib/librthread/arch/vax/rfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: rfork_thread.S,v 1.2 2008/05/21 20:39:32 miod Exp $ */ +/* $OpenBSD: rfork_thread.S,v 1.3 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,9 +28,9 @@ #include "../../../libc/arch/vax/SYS.h" /* - * int rfork_thread(int flags, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); */ -ENTRY(rfork_thread, R2|R3|R4) +ENTRY(__tfork_thread, R2|R3|R4) /* * Save thread creation arguments into registers. */ @@ -38,7 +38,7 @@ ENTRY(rfork_thread, R2|R3|R4) movl 12(ap), r3 /* func */ movl 16(ap), r4 /* arg */ - __DO_SYSCALL(rfork) + __DO_SYSCALL(__tfork) jcs 9f cmpl r0, $0 diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index 9c9f4a6a37f..eb5cbadc89c 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.42 2009/11/27 19:45:54 guenther Exp $ */ +/* $OpenBSD: rthread.c,v 1.43 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -41,6 +41,7 @@ #include "thread_private.h" /* in libc/include */ #include "rthread.h" +#include "tcb.h" static int concurrency_level; /* not used */ @@ -51,8 +52,9 @@ static struct pthread_queue _thread_gc_list = TAILQ_HEAD_INITIALIZER(_thread_gc_list); static _spinlock_lock_t _thread_gc_lock = _SPINLOCK_UNLOCKED; struct pthread _initial_thread; +struct thread_control_block _initial_thread_tcb; -int rfork_thread(int, void *, void (*)(void *), void *); +int __tfork_thread(const struct __tfork *, void *, void (*)(void *), void *); /* * internal support functions @@ -72,6 +74,28 @@ _spinunlock(_spinlock_lock_t *lock) *lock = _SPINLOCK_UNLOCKED; } +/* + * This sets up the thread base for the initial thread so that it + * references the errno location provided by libc. For other threads + * this is handled by the block in _rthread_start(). + */ +void _rthread_initlib(void) __attribute__((constructor)); +void _rthread_initlib(void) +{ + struct thread_control_block *tcb = &_initial_thread_tcb; + + /* use libc's errno for the main thread */ + TCB_INIT(tcb, &_initial_thread, ___errno()); + TCB_SET(tcb); +} + +int * +__errno(void) +{ + return (TCB_ERRNOPTR()); +} + + static pthread_t _rthread_findself(void) { @@ -92,9 +116,6 @@ _rthread_start(void *v) pthread_t thread = v; void *retval; - /* ensure parent returns from rfork, sets up tid */ - _spinlock(&_thread_lock); - _spinunlock(&_thread_lock); retval = thread->fn(thread->arg); pthread_exit(retval); } @@ -141,11 +162,13 @@ _rthread_free(pthread_t thread) if (thread != &_initial_thread) { struct stack *stack = thread->stack; pid_t tid = thread->tid; + void *arg = thread->arg; /* catch wrongdoers for the moment */ memset(thread, 0xd0, sizeof(*thread)); thread->stack = stack; thread->tid = tid; + thread->arg = arg; _spinlock(&_thread_gc_lock); TAILQ_INSERT_TAIL(&_thread_gc_list, thread, waiting); _spinunlock(&_thread_gc_lock); @@ -201,6 +224,8 @@ restart:_spinlock(&_thread_gc_lock); _rthread_debug(3, "rthread reaping %p stack %p\n", (void *)thread, (void *)thread->stack); _rthread_free_stack(thread->stack); + _rtld_free_tls(thread->arg, + sizeof(struct thread_control_block), sizeof(void *)); free(thread); goto restart; } @@ -211,8 +236,6 @@ void pthread_exit(void *retval) { struct rthread_cleanup_fn *clfn; - pid_t tid; - struct stack *stack; pthread_t thread = pthread_self(); thread->retval = retval; @@ -228,8 +251,11 @@ pthread_exit(void *retval) LIST_REMOVE(thread, threads); _spinunlock(&_thread_lock); - stack = thread->stack; - tid = thread->tid; +#ifdef TCB_GET + thread->arg = TCB_GET(); +#else + thread->arg = __get_tcb(); +#endif if (thread->flags & THREAD_DETACHED) _rthread_free(thread); else { @@ -292,8 +318,9 @@ int pthread_create(pthread_t *threadp, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { + struct thread_control_block *tcb; pthread_t thread; - pid_t tid; + struct __tfork param; int rc = 0; if (!_threads_ready) @@ -309,6 +336,8 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, thread->flags_lock = _SPINLOCK_UNLOCKED; thread->fn = start_routine; thread->arg = arg; + thread->tid = -1; + if (attr) thread->attr = *(*attr); else { @@ -318,43 +347,45 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, } if (thread->attr.detach_state == PTHREAD_CREATE_DETACHED) thread->flags |= THREAD_DETACHED; - - _spinlock(&_thread_lock); + thread->flags |= THREAD_CANCEL_ENABLE|THREAD_CANCEL_DEFERRED; thread->stack = _rthread_alloc_stack(thread); if (!thread->stack) { rc = errno; goto fail1; } - LIST_INSERT_HEAD(&_thread_list, thread, threads); - tid = rfork_thread(RFPROC | RFTHREAD | RFMEM | RFNOWAIT, - thread->stack->sp, _rthread_start, thread); - if (tid == -1) { + tcb = _rtld_allocate_tls(NULL, sizeof(*tcb), sizeof(void *)); + if (tcb == NULL) { rc = errno; goto fail2; } - /* new thread will appear _rthread_start */ - thread->tid = tid; - thread->flags |= THREAD_CANCEL_ENABLE|THREAD_CANCEL_DEFERRED; - *threadp = thread; + TCB_INIT(tcb, thread, &thread->myerrno); - /* - * Since _rthread_start() aquires the thread lock and due to the way - * signal delivery is implemented, this is not a race. - */ - if (thread->attr.create_suspended) - kill(thread->tid, SIGSTOP); + param.tf_tcb = tcb; + param.tf_tid = &thread->tid; + param.tf_flags = 0; + _spinlock(&_thread_lock); + LIST_INSERT_HEAD(&_thread_list, thread, threads); _spinunlock(&_thread_lock); - return (0); + rc = __tfork_thread(¶m, thread->stack->sp, _rthread_start, thread); + if (rc != -1) { + /* success */ + *threadp = thread; + return (0); + } + + rc = errno; + _spinlock(&_thread_lock); + LIST_REMOVE(thread, threads); + _spinunlock(&_thread_lock); + _rtld_free_tls(tcb, sizeof(*tcb), sizeof(void *)); fail2: _rthread_free_stack(thread->stack); - LIST_REMOVE(thread, threads); fail1: - _spinunlock(&_thread_lock); _rthread_free(thread); return (rc); diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h index 19af1f12eae..c0dc626ca9f 100644 --- a/lib/librthread/rthread.h +++ b/lib/librthread/rthread.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.h,v 1.25 2009/11/27 19:45:54 guenther Exp $ */ +/* $OpenBSD: rthread.h,v 1.26 2011/10/17 06:39:20 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -27,6 +27,7 @@ #include <sys/queue.h> #include <semaphore.h> +#include <machine/tcb.h> /* for TLS_VARIANT */ #ifdef __LP64__ #define RTHREAD_STACK_SIZE_DEF (512 * 1024) @@ -112,6 +113,9 @@ struct rthread_cleanup_fn { struct pthread { struct sem donesem; +#if TLS_VARIANT == 1 + int *errno_ptr; +#endif pid_t tid; unsigned int flags; _spinlock_lock_t flags_lock; @@ -127,6 +131,7 @@ struct pthread { struct sched_param sched_param; struct rthread_storage *local_storage; struct rthread_cleanup_fn *cleanup_fns; + int myerrno; }; #define THREAD_DONE 0x001 #define THREAD_DETACHED 0x002 diff --git a/lib/librthread/tcb.h b/lib/librthread/tcb.h new file mode 100644 index 00000000000..a3485c8a973 --- /dev/null +++ b/lib/librthread/tcb.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2011 Philip Guenther <guenther@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _TCB_H_ +#define _TCB_H_ + +/* + * We define the structure for the TCB, plus three macros: + * TCB_THREAD() + * Expands to a pointer-to-pthread rvalue that points + * to this thread's struct pthread + * TCB_ERRNOPTR() + * Expands to a pointer-to-int lvalue that points to + * this thread's errno + * TCB_INIT(tcb, thread, errnoptr) + * Expands to a code to initialize the TCB pointed to by + * its first argument + * + * <machine/tcb.h> must define the TLS_VARIANT macro. If it defines + * that to 1, then it must also defined the macro + * THREAD_ERRNOPTR_OFFSET + * Byte offset in struct pthread of the pointer to the + * thread's errno + * + * By default, we get and set the TCB pointer for a thread using the + * __get_tcb() and __set_tcb() syscalls. If there's a faster way to do + * either of those, <machine/tcb.h> should define the macros + * TCB_SET(tcb) + * Set the TCB pointer for this thread + * TCB_GET() + * Return the TCB pointer for this thread + * If it defines TCB_GET, then it must also define: + * TCB_GET_MEMBER(member) + * Return the pointer in the 'member' slot in the TCB + */ + +#include <machine/tcb.h> + +struct pthread; + +void *__get_tcb(void); +void __set_tcb(void *); + +#ifdef TCB_GET_MEMBER +#define TCB_THREAD() ((struct pthread *)TCB_GET_MEMBER(tcb_thread)) +#else +#define TCB_THREAD() \ + (((struct thread_control_block *)__get_tcb())->tcb_thread) +#endif + + +#if TLS_VARIANT == 1 +/* + * Small TCB, with TLS data after the TCB. Used on IA64 and PowerPC + * Errno pointer stored in struct pthread + */ + +struct thread_control_block { + void *tcb_dtv; /* internal to the runtime linker */ + struct pthread *tcb_thread; +}; + +#define __ERRNOPTR(thread) \ + (((int **)(thread))[THREAD_ERRNOPTR_OFFSET / sizeof(int *)]) +#define TCB_ERRNOPTR() \ + __ERRNOPTR(TCB_THREAD()) +#define TCB_INIT(tcb, thread, errnoptr) \ + do { \ + (tcb)->tcb_dtv = 0; \ + (tcb)->tcb_thread = (thread); \ + __ERRNOPTR(thread) = (errnoptr); \ + } while (0) + + +#elif TLS_VARIANT == 2 +/* + * Large TCB, with TLS data before the TCB (i.e., negative offsets) + * Used everywhere but IA64 and PowerPC + * Errno pointer stored in the TCB + */ + +struct thread_control_block { + struct thread_control_block *__tcb_self; + void *tcb_dtv; /* internal to the runtime linker */ + struct pthread *tcb_thread; + int *__tcb_errno; +}; + +#ifdef TCB_GET_MEMBER +#define TCB_ERRNOPTR() ((int *)TCB_GET_MEMBER(__tcb_errno)) +#else +#define TCB_ERRNOPTR() \ + (((struct thread_control_block *)__get_tcb())->__tcb_errno) +#endif +#define TCB_INIT(tcb, thread, errnoptr) \ + do { \ + (tcb)->__tcb_self = (tcb); \ + (tcb)->tcb_dtv = 0; \ + (tcb)->tcb_thread = (thread); \ + (tcb)->__tcb_errno = (errnoptr); \ + } while (0) + + +#else +# error "unknown TLS variant" +#endif + + +/* If there isn't a better way, use the default */ +#ifndef TCB_SET +#define TCB_SET(tcb) __set_tcb(tcb) +#endif + +#if 0 +void *_rtld_allocate_tls(void *, size_t, size_t); +void _rtld_free_tls(void *, size_t, size_t); +#else +/* + * XXX Until we have these in ld.so and support __thread, just use + * malloc/free. The main thread's TCB cannot be allocated or freed with these. + */ +#define _rtld_allocate_tls(old, size, align) malloc(size) +#define _rtld_free_tls(old, size, align) free(old) +#endif + +#endif /* _TCB_H_ */ |