1*cdecda8dSBrooks Davis/*- 2*cdecda8dSBrooks Davis * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 3*cdecda8dSBrooks Davis * All rights reserved. 4*cdecda8dSBrooks Davis * 5*cdecda8dSBrooks Davis * Redistribution and use in source and binary forms, with or without 6*cdecda8dSBrooks Davis * modification, are permitted provided that the following conditions 7*cdecda8dSBrooks Davis * are met: 8*cdecda8dSBrooks Davis * 1. Redistributions of source code must retain the above copyright 9*cdecda8dSBrooks Davis * notice, this list of conditions and the following disclaimer. 10*cdecda8dSBrooks Davis * 2. Redistributions in binary form must reproduce the above copyright 11*cdecda8dSBrooks Davis * notice, this list of conditions and the following disclaimer in the 12*cdecda8dSBrooks Davis * documentation and/or other materials provided with the distribution. 13*cdecda8dSBrooks Davis * 14*cdecda8dSBrooks Davis * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*cdecda8dSBrooks Davis * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*cdecda8dSBrooks Davis * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*cdecda8dSBrooks Davis * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*cdecda8dSBrooks Davis * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*cdecda8dSBrooks Davis * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*cdecda8dSBrooks Davis * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*cdecda8dSBrooks Davis * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*cdecda8dSBrooks Davis * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*cdecda8dSBrooks Davis * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*cdecda8dSBrooks Davis * SUCH DAMAGE. 25*cdecda8dSBrooks Davis */ 26*cdecda8dSBrooks Davis 27*cdecda8dSBrooks Davis#include <machine/asm.h> 28*cdecda8dSBrooks Davis/* 29*cdecda8dSBrooks Davis * With thanks to John Dyson for the original version of this. 30*cdecda8dSBrooks Davis */ 31*cdecda8dSBrooks Davis 32*cdecda8dSBrooks Davis#include <SYS.h> 33*cdecda8dSBrooks Davis 34*cdecda8dSBrooks Davis/* 35*cdecda8dSBrooks Davis * 8 12 16 20 36*cdecda8dSBrooks Davis * rfork_thread(flags, stack_addr, start_fnc, start_arg); 37*cdecda8dSBrooks Davis * 38*cdecda8dSBrooks Davis * flags: Flags to rfork system call. See rfork(2). 39*cdecda8dSBrooks Davis * stack_addr: Top of stack for thread. 40*cdecda8dSBrooks Davis * start_fnc: Address of thread function to call in child. 41*cdecda8dSBrooks Davis * start_arg: Argument to pass to the thread function in child. 42*cdecda8dSBrooks Davis */ 43*cdecda8dSBrooks Davis 44*cdecda8dSBrooks DavisENTRY(rfork_thread) 45*cdecda8dSBrooks Davis pushl %ebp 46*cdecda8dSBrooks Davis movl %esp, %ebp 47*cdecda8dSBrooks Davis pushl %esi 48*cdecda8dSBrooks Davis 49*cdecda8dSBrooks Davis /* 50*cdecda8dSBrooks Davis * Push thread info onto the new thread's stack 51*cdecda8dSBrooks Davis */ 52*cdecda8dSBrooks Davis movl 12(%ebp), %esi # get stack addr 53*cdecda8dSBrooks Davis 54*cdecda8dSBrooks Davis subl $4, %esi 55*cdecda8dSBrooks Davis movl 20(%ebp), %eax # get start argument 56*cdecda8dSBrooks Davis movl %eax, (%esi) 57*cdecda8dSBrooks Davis 58*cdecda8dSBrooks Davis subl $4, %esi 59*cdecda8dSBrooks Davis movl 16(%ebp), %eax # get start thread address 60*cdecda8dSBrooks Davis movl %eax, (%esi) 61*cdecda8dSBrooks Davis 62*cdecda8dSBrooks Davis /* 63*cdecda8dSBrooks Davis * Prepare and execute the thread creation syscall 64*cdecda8dSBrooks Davis */ 65*cdecda8dSBrooks Davis pushl 8(%ebp) 66*cdecda8dSBrooks Davis pushl $0 67*cdecda8dSBrooks Davis _SYSCALL(rfork) 68*cdecda8dSBrooks Davis jb 2f 69*cdecda8dSBrooks Davis 70*cdecda8dSBrooks Davis /* 71*cdecda8dSBrooks Davis * Check to see if we are in the parent or child 72*cdecda8dSBrooks Davis */ 73*cdecda8dSBrooks Davis cmpl $0, %edx 74*cdecda8dSBrooks Davis jnz 1f 75*cdecda8dSBrooks Davis addl $8, %esp 76*cdecda8dSBrooks Davis popl %esi 77*cdecda8dSBrooks Davis movl %ebp, %esp 78*cdecda8dSBrooks Davis popl %ebp 79*cdecda8dSBrooks Davis ret 80*cdecda8dSBrooks Davis .p2align 2 81*cdecda8dSBrooks Davis 82*cdecda8dSBrooks Davis /* 83*cdecda8dSBrooks Davis * If we are in the child (new thread), then 84*cdecda8dSBrooks Davis * set-up the call to the internal subroutine. If it 85*cdecda8dSBrooks Davis * returns, then call __exit. 86*cdecda8dSBrooks Davis */ 87*cdecda8dSBrooks Davis1: 88*cdecda8dSBrooks Davis movl %esi,%esp 89*cdecda8dSBrooks Davis popl %eax 90*cdecda8dSBrooks Davis call *%eax 91*cdecda8dSBrooks Davis addl $4, %esp 92*cdecda8dSBrooks Davis 93*cdecda8dSBrooks Davis /* 94*cdecda8dSBrooks Davis * Exit system call 95*cdecda8dSBrooks Davis */ 96*cdecda8dSBrooks Davis pushl %eax 97*cdecda8dSBrooks Davis pushl $0 98*cdecda8dSBrooks Davis _SYSCALL(exit) 99*cdecda8dSBrooks Davis 100*cdecda8dSBrooks Davis /* 101*cdecda8dSBrooks Davis * Branch here if the thread creation fails: 102*cdecda8dSBrooks Davis */ 103*cdecda8dSBrooks Davis2: 104*cdecda8dSBrooks Davis addl $8, %esp 105*cdecda8dSBrooks Davis popl %esi 106*cdecda8dSBrooks Davis movl %ebp, %esp 107*cdecda8dSBrooks Davis popl %ebp 108*cdecda8dSBrooks Davis jmp HIDENAME(cerror) 109*cdecda8dSBrooks DavisEND(rfork_thread) 110*cdecda8dSBrooks Davis 111*cdecda8dSBrooks Davis .section .note.GNU-stack,"",%progbits 112