summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-10-13 20:32:33 +0000
committeralc <alc@FreeBSD.org>2003-10-13 20:32:33 +0000
commitb1c274e0beb146fe947969a6dbed45723999637c (patch)
treec7a7e2b67a4d36e8297bc6a7f5a06dedfe0298e2 /lib
parentb8ead5692b0bd0246b2cadab55cf54faf683ef45 (diff)
downloadFreeBSD-src-b1c274e0beb146fe947969a6dbed45723999637c.zip
FreeBSD-src-b1c274e0beb146fe947969a6dbed45723999637c.tar.gz
Add rfork_thread(3).
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/amd64/gen/Makefile.inc2
-rw-r--r--lib/libc/amd64/gen/rfork_thread.S101
2 files changed, 102 insertions, 1 deletions
diff --git a/lib/libc/amd64/gen/Makefile.inc b/lib/libc/amd64/gen/Makefile.inc
index 9a932bc..053c9c9 100644
--- a/lib/libc/amd64/gen/Makefile.inc
+++ b/lib/libc/amd64/gen/Makefile.inc
@@ -1,7 +1,7 @@
# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
# $FreeBSD$
-SRCS+= _setjmp.S setjmp.S sigsetjmp.S \
+SRCS+= _setjmp.S rfork_thread.S setjmp.S sigsetjmp.S \
fabs.S modf.S \
frexp.c infinity.c isinf.c ldexp.c \
makecontext.c signalcontext.c \
diff --git a/lib/libc/amd64/gen/rfork_thread.S b/lib/libc/amd64/gen/rfork_thread.S
new file mode 100644
index 0000000..aa7001c
--- /dev/null
+++ b/lib/libc/amd64/gen/rfork_thread.S
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org>
+ * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * With thanks to John Dyson for the original version of this.
+ */
+
+#include <SYS.h>
+
+/*
+ * %edi %rsi %rdx %rcx
+ * rfork_thread(flags, stack_addr, start_fnc, start_arg);
+ *
+ * flags: Flags to rfork system call. See rfork(2).
+ * 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)
+ pushq %rbx
+ pushq %r12
+ movq %rdx, %rbx
+ movq %rcx, %r12
+
+ /*
+ * Prepare and execute the thread creation syscall
+ */
+ movq $SYS_rfork, %rax
+ KERNCALL
+ jb 2f
+
+ /*
+ * Check to see if we are in the parent or child
+ */
+ cmpl $0, %edx
+ jnz 1f
+ popq %r12
+ popq %rbx
+ ret
+
+ /*
+ * If we are in the child (new thread), then
+ * set-up the call to the internal subroutine. If it
+ * returns, then call __exit.
+ */
+1:
+ movq %rsi, %rsp
+ movq %r12, %rdi
+ call *%rbx
+ movl %eax, %edi
+
+ /*
+ * Exit system call
+ */
+#ifdef SYS_exit
+ movq $SYS_exit, %rax
+#else
+ movq $SYS_sys_exit, %rax
+#endif
+ KERNCALL
+
+ /*
+ * Branch here if the thread creation fails:
+ */
+2:
+ popq %r12
+ popq %rbx
+#ifdef PIC
+ movq PIC_GOT(HIDENAME(cerror)), %rdx
+ jmp *%rdx
+#else
+ jmp HIDENAME(cerror)
+#endif
OpenPOWER on IntegriCloud