This is a discussion on Re: rfork() strangeness in v3.6 within the mailing.openbsd.tech forums, part of the OpenBSD category; --> On Mon, 4 Apr 2005, Jason W. Kim wrote: > Hi, I've been poking around the kernel sources, and ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| On Mon, 4 Apr 2005, Jason W. Kim wrote: > Hi, I've been poking around the kernel sources, and got stuck trying to > write some test programs for sharing data across processes (beyond SYSV > SHM which works great) via rfork() and minherit(). if that's what you want, you don't need rfork. > Furthermore, the regression code that use rfork() with the RFMEM flag > all seem to crash (dmesg attached) it doesn't work the way it used to. before, existing memory was shared, except the stack. but new allocations were not shared, which made it pretty useless as a basis for a thread library. i changed it so that the two process have exactly the same address space. this causes problems when they both return to the same stack frame. > So my question regarding rfork()/RFMEM what is the preferred use of the > calls? From what I can gather from previous posts here, (for example, > take a look at this snippet of strangeness -) > > Note, the OpenBSD rfork() doesn't actually share the address space, > > but > > rather uses sharing maps ... sharing maps don't exist in UVM. Also, > ^^^^^^^^^^ ^^^^^ > > I don't know what to make of this (!) outdated. > > the original rfork() API specifies that RFMEM _does not actually share > > the address space_, but only shares text/data (i.e. stack, heap, etc. > > are apparently NOT shared). So, calling the new call rfork() seems > > rather lame, to me. yeah, that's the old way, but in practice it doesn't work too well. absolutely nothing used it. RFMEM now behaves more like traditional vfork wrt to address spaces. if you want to use rfork, you may find the following useful. /*- * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> * 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> #if 0 __FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/i386/gen/rfork_thread.S,v 1.5 2003/05/07 17:23:25 jhb Exp $"); #endif /* * With thanks to John Dyson for the original version of this. */ #include <SYS.h> /* * 8 12 16 20 * 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) pushl %ebp movl %esp, %ebp pushl %esi /* * Push thread info onto the new thread's stack */ movl 12(%ebp), %esi # get stack addr subl $4, %esi movl 20(%ebp), %eax # get start argument movl %eax, (%esi) subl $4, %esi movl 16(%ebp), %eax # get start thread address movl %eax, (%esi) /* * Prepare and execute the thread creation syscall */ pushl 8(%ebp) pushl $0 movl $SYS_rfork, %eax int $0x80 #if 0 jb 2f #endif /* * Check to see if we are in the parent or child */ cmpl $0, %edx jnz 1f addl $8, %esp popl %esi movl %ebp, %esp popl %ebp ret .p2align 2 /* * If we are in the child (new thread), then * set-up the call to the internal subroutine. If it * returns, then call __exit. */ 1: movl %esi,%esp popl %eax call *%eax addl $4, %esp /* * Exit system call */ pushl %eax pushl $0 #ifdef SYS_exit movl $SYS_exit, %eax #else movl $SYS_sys_exit, %eax #endif int $0x80 /* * Branch here if the thread creation fails: */ 2: addl $8, %esp popl %esi movl %ebp, %esp popl %ebp #if 0 /* FreeBSD code. how to translate? */ PIC_PROLOGUE jmp PIC_PLT(HIDENAME(cerror)) #endif jmp CERROR -- let's stop saying "don't quote me" because if no one quotes you you probably haven't said a thing worth saying |