164000Speter/*- 264000Speter * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 364000Speter * All rights reserved. 464000Speter * 564000Speter * Redistribution and use in source and binary forms, with or without 664000Speter * modification, are permitted provided that the following conditions 764000Speter * are met: 864000Speter * 1. Redistributions of source code must retain the above copyright 964000Speter * notice, this list of conditions and the following disclaimer. 1064000Speter * 2. Redistributions in binary form must reproduce the above copyright 1164000Speter * notice, this list of conditions and the following disclaimer in the 1264000Speter * documentation and/or other materials provided with the distribution. 1364000Speter * 1464000Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1564000Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1664000Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1764000Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1864000Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1964000Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2064000Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2164000Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2264000Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2364000Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2464000Speter * SUCH DAMAGE. 2564000Speter */ 2664000Speter 2793000Sobrien#include <machine/asm.h> 2893000Sobrien__FBSDID("$FreeBSD$"); 2993000Sobrien 3064000Speter/* 3164000Speter * With thanks to John Dyson for the original version of this. 3264000Speter */ 3364000Speter 3464000Speter#include <SYS.h> 3564000Speter 3664000Speter/* 3764000Speter * 8 12 16 20 3864000Speter * rfork_thread(flags, stack_addr, start_fnc, start_arg); 3964000Speter * 4064000Speter * flags: Flags to rfork system call. See rfork(2). 4164000Speter * stack_addr: Top of stack for thread. 4264000Speter * start_fnc: Address of thread function to call in child. 4364000Speter * start_arg: Argument to pass to the thread function in child. 4464000Speter */ 4564000Speter 4664000SpeterENTRY(rfork_thread) 4764000Speter pushl %ebp 4864000Speter movl %esp, %ebp 4964000Speter pushl %esi 5064000Speter 5164000Speter /* 5264000Speter * Push thread info onto the new thread's stack 5364000Speter */ 5464000Speter movl 12(%ebp), %esi # get stack addr 5564000Speter 5664000Speter subl $4, %esi 5764000Speter movl 20(%ebp), %eax # get start argument 5864000Speter movl %eax, (%esi) 5964000Speter 6064000Speter subl $4, %esi 6164000Speter movl 16(%ebp), %eax # get start thread address 6264000Speter movl %eax, (%esi) 6364000Speter 6464000Speter /* 6564000Speter * Prepare and execute the thread creation syscall 6664000Speter */ 6764000Speter pushl 8(%ebp) 6864003Speter pushl $0 6987006Sjhb movl $SYS_rfork, %eax 7064000Speter KERNCALL 7164000Speter jb 2f 7264000Speter 7364000Speter /* 7464000Speter * Check to see if we are in the parent or child 7564000Speter */ 7664000Speter cmpl $0, %edx 7764000Speter jnz 1f 7864000Speter addl $8, %esp 7964000Speter popl %esi 8064000Speter movl %ebp, %esp 8164000Speter popl %ebp 8264000Speter ret 8364000Speter .p2align 2 8464000Speter 8564000Speter /* 8664000Speter * If we are in the child (new thread), then 8764000Speter * set-up the call to the internal subroutine. If it 8864000Speter * returns, then call __exit. 8964000Speter */ 9064000Speter1: 9164000Speter movl %esi,%esp 9264000Speter popl %eax 9364000Speter call *%eax 9464003Speter addl $4, %esp 9564000Speter 9664000Speter /* 9764000Speter * Exit system call 9864000Speter */ 9964000Speter pushl %eax 10064003Speter pushl $0 10164000Speter#ifdef SYS_exit 10287006Sjhb movl $SYS_exit, %eax 10364000Speter#else 10487006Sjhb movl $SYS_sys_exit, %eax 10564000Speter#endif 10664000Speter KERNCALL 10764000Speter 10864000Speter /* 10964000Speter * Branch here if the thread creation fails: 11064000Speter */ 11164000Speter2: 112114804Sjhb addl $8, %esp 113114804Sjhb popl %esi 114114804Sjhb movl %ebp, %esp 115114804Sjhb popl %ebp 11664000Speter PIC_PROLOGUE 11764000Speter jmp PIC_PLT(HIDENAME(cerror)) 118184548SpeterEND(rfork_thread) 119217106Skib 120217106Skib .section .note.GNU-stack,"",%progbits 121