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