summaryrefslogtreecommitdiff
path: root/lib/librthread
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2011-10-17 06:39:21 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2011-10-17 06:39:21 +0000
commit82cbd469f12cd3a22be520db0de2ead1449f271e (patch)
tree7f405c5d2faa96148d6ed5ebe126425e978967c4 /lib/librthread
parent2f6d2040683851ec94ddc66982fcddb408ea5eb2 (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')
-rw-r--r--lib/librthread/Makefile9
-rw-r--r--lib/librthread/__tfork_thread.3138
-rw-r--r--lib/librthread/arch/alpha/cerror.S54
-rw-r--r--lib/librthread/arch/alpha/rfork_thread.S10
-rw-r--r--lib/librthread/arch/amd64/cerror.S55
-rw-r--r--lib/librthread/arch/amd64/rfork_thread.S12
-rw-r--r--lib/librthread/arch/arm/cerror.S44
-rw-r--r--lib/librthread/arch/arm/rfork_thread.S10
-rw-r--r--lib/librthread/arch/hppa/rfork_thread.S10
-rw-r--r--lib/librthread/arch/i386/cerror.S49
-rw-r--r--lib/librthread/arch/i386/rfork_thread.S10
-rw-r--r--lib/librthread/arch/m68k/cerror.S53
-rw-r--r--lib/librthread/arch/m68k/rfork_thread.S8
-rw-r--r--lib/librthread/arch/m88k/rfork_thread.S8
-rw-r--r--lib/librthread/arch/mips64/rfork_thread.S12
-rw-r--r--lib/librthread/arch/powerpc/rfork_thread.S8
-rw-r--r--lib/librthread/arch/sh/cerror.S58
-rw-r--r--lib/librthread/arch/sh/rfork_thread.S14
-rw-r--r--lib/librthread/arch/sparc/cerror.S51
-rw-r--r--lib/librthread/arch/sparc/rfork_thread.S15
-rw-r--r--lib/librthread/arch/sparc64/cerror.S54
-rw-r--r--lib/librthread/arch/sparc64/rfork_thread.S12
-rw-r--r--lib/librthread/arch/vax/cerror.S40
-rw-r--r--lib/librthread/arch/vax/rfork_thread.S8
-rw-r--r--lib/librthread/rthread.c89
-rw-r--r--lib/librthread/rthread.h7
-rw-r--r--lib/librthread/tcb.h139
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(&param, 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_ */