rfork_thread.S revision 64000
1132718Skan/*-
2132718Skan * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org>
3132718Skan * All rights reserved.
4132718Skan *
5132718Skan * Redistribution and use in source and binary forms, with or without
6132718Skan * modification, are permitted provided that the following conditions
7132718Skan * are met:
8132718Skan * 1. Redistributions of source code must retain the above copyright
9132718Skan *    notice, this list of conditions and the following disclaimer.
10132718Skan * 2. Redistributions in binary form must reproduce the above copyright
11132718Skan *    notice, this list of conditions and the following disclaimer in the
12132718Skan *    documentation and/or other materials provided with the distribution.
13132718Skan *
14132718Skan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15132718Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16132718Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17132718Skan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18169689Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19132718Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20132718Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21132718Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22132718Skan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23132718Skan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24132718Skan * SUCH DAMAGE.
25169689Skan *
26132718Skan * $FreeBSD: head/lib/libc/i386/gen/rfork_thread.S 64000 2000-07-29 07:14:04Z peter $
27132718Skan */
28132718Skan
29132718Skan/*
30132718Skan * With thanks to John Dyson for the original version of this.
31132718Skan */
32132718Skan
33132718Skan#include <SYS.h>
34132718Skan
35132718Skan/*
36132718Skan *                8      12          16         20
37169689Skan * rfork_thread(flags, stack_addr, start_fnc, start_arg);
38132718Skan *
39169689Skan * flags:		Flags to rfork system call.  See rfork(2).
40132718Skan * stack_addr:		Top of stack for thread.
41132718Skan * start_fnc:		Address of thread function to call in child.
42132718Skan * start_arg:		Argument to pass to the thread function in child.
43132718Skan */
44132718Skan
45132718SkanENTRY(rfork_thread)
46132718Skan	pushl	%ebp
47132718Skan	movl	%esp, %ebp
48169689Skan	pushl	%esi
49169689Skan
50132718Skan	/*
51132718Skan	 * Push thread info onto the new thread's stack
52132718Skan	 */
53132718Skan	movl	12(%ebp), %esi	# get stack addr
54169689Skan
55169689Skan	subl	$4, %esi
56169689Skan	movl	20(%ebp), %eax	# get start argument
57169689Skan	movl	%eax, (%esi)
58169689Skan
59169689Skan	subl	$4, %esi
60169689Skan	movl	16(%ebp), %eax	# get start thread address
61169689Skan	movl	%eax, (%esi)
62132718Skan
63132718Skan	/*
64132718Skan	 * Prepare and execute the thread creation syscall
65132718Skan	 */
66132718Skan	pushl	12(%ebp)
67132718Skan	pushl	8(%ebp)
68132718Skan	pushl	%esi
69132718Skan	leal	SYS_rfork, %eax
70132718Skan	KERNCALL
71132718Skan	jb 	2f
72132718Skan
73132718Skan	/*
74132718Skan	 * Check to see if we are in the parent or child
75132718Skan	 */
76132718Skan	cmpl	$0, %edx
77132718Skan	jnz	1f
78132718Skan	addl	$8, %esp
79132718Skan	popl	%esi
80132718Skan	movl	%ebp, %esp
81132718Skan	popl	%ebp
82132718Skan	ret
83132718Skan	.p2align 2
84132718Skan
85132718Skan	/*
86132718Skan	 * If we are in the child (new thread), then
87132718Skan	 * set-up the call to the internal subroutine.  If it
88132718Skan	 * returns, then call __exit.
89132718Skan	 */
90132718Skan1:
91132718Skan	movl	%esi,%esp
92132718Skan	popl	%eax
93132718Skan	call	*%eax
94132718Skan	addl	$12, %esp
95132718Skan
96132718Skan	/*
97132718Skan	 * Exit system call
98132718Skan	 */
99132718Skan	pushl	%eax
100132718Skan#ifdef SYS_exit
101132718Skan	pushl	$SYS_exit
102132718Skan#else
103132718Skan	pushl	$SYS_sys_exit
104132718Skan#endif
105132718Skan	KERNCALL
106132718Skan
107132718Skan	/*
108132718Skan	 * Branch here if the thread creation fails:
109132718Skan	 */
110132718Skan2:
111169689Skan	PIC_PROLOGUE
112169689Skan	jmp	PIC_PLT(HIDENAME(cerror))
113169689Skan