Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Aug 1998 14:28:40 +0200
From:      Martin Cracauer <cracauer@cons.org>
To:        Jonathan Lemon <jlemon@americantv.com>, Alfred Perlstein <bright@www.hotjobs.com>
Cc:        hackers@FreeBSD.ORG
Subject:   Re: sfork()?
Message-ID:  <19980820142840.A28158@cons.org>
In-Reply-To: <19980819101735.48927@right.PCS>; from Jonathan Lemon on Wed, Aug 19, 1998 at 10:17:35AM -0500
References:  <199808191303.PAA10187@sos.freebsd.dk> <Pine.BSF.3.96.980819095759.17267L-100000@bright.fx.genx.net> <19980819101735.48927@right.PCS>

next in thread | previous in thread | raw e-mail | index | archive | help

--45Z9DzgjV8m4Oswq
Content-Type: text/plain; charset=us-ascii

In <19980819101735.48927@right.PCS>, Jonathan Lemon wrote: 
> On Aug 08, 1998 at 10:43:09AM -0500, Alfred Perlstein wrote:
> > 
> > can someone explain why this doesn't work?
> 
> Look at the -hacker archives, for a message from John Dyson
> titled "malloc() problems in children after using rfork()", 
> circa Nov 1997.  It includes an assembly wrapper around rfork()
> that is needed to make it work in userland.

I once changed that source bit to make it easier to use and wrote an
example use program.

I attached the code, maybe it's useful for you. If you change or
expand it, please notify me.

Martin
-- 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Martin Cracauer <cracauer@cons.org> http://www.cons.org/cracauer
BSD User Group Hamburg, Germany     http://www.bsdhh.org/

--45Z9DzgjV8m4Oswq
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="dyson-rf.h"

int thrfork(int flags, void *stack, void *startrtn, void *startarg, 
	    void *userrtn, void *arg);

--45Z9DzgjV8m4Oswq
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="dyson-rf.S"

        .file   "dyson-rf.S"
#include <sys/syscall.h>
#include "DEFS.h"
#include "SYS.h"
#define KERNEL
#include <sys/errno.h>
#undef KERNEL

#undef DEBUG

/*
 *        8      12     16        20        24       28
 * _rfork(flags, stack, startrtn, startarg, userrtn, arg);
 *
 * flags: RF* flags for rfork in unistd.h.
 * subr:  subroutine to run as a thread.
 * stack: top of stack for thread.
 * arg:   argument to thread.
 */
.stabs "dyson-rf.S",100,0,0,Ltext0
        .text
Ltext0:
        .type   _thrfork,@function
        .stabd 68,0,1
ENTRY(thrfork)
        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    28(%ebp), %eax  / get user argument
        movl    %eax, (%esi)

        subl    $4, %esi
        movl    24(%ebp), %eax  / get user thread address
        movl    %eax, (%esi)

        subl    $4, %esi
        movl    20(%ebp), %eax  / get internal argument
        movl    %eax, (%esi)

        subl    $4, %esi
        movl    16(%ebp), %eax  / get internal subroutine
        movl    %eax, (%esi)

        .stabd 68,0,2
        /*
         * Prepare and execute rfork
         */
        pushl   8(%ebp)
        pushl   %esi
        leal    SYS_rfork, %eax
        KERNCALL
        jb      2f

        .stabd 68,0,3
        /*
         * 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.
         */
        .stabd 68,0,4
1:
        movl    %esi,%esp
#ifdef DEBUG
        movl    %esp, _stackaddr
        movl    (%esp), %eax
        movl    %eax, _stack
        movl    4(%esp), %eax
        movl    %eax,_stack+4
        movl    8(%esp), %eax
        movl    %eax,_stack+8
        movl    12(%esp), %eax
        movl    %eax,_stack+12
#endif
        popl    %eax 
#ifdef DEBUG
        movl    %eax,_fcn
#endif
        call    %eax
        addl    $12, %esp

        /*
         * Exit system call
         */
        pushl   %eax
        pushl   $SYS_exit
        call    _syscall

        .stabd 68,0,5
2:      movl    $EAGAIN, _errno
        movl    $-1, %eax
        leave
        ret
.stabs "thrfork:f67",36,0,6,_thrfork
Lfe1:
        .size    _thrfork,Lfe1-_thrfork

#ifdef DEBUG
        .data
        .globl  _stack
_stack: .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .globl  _stackaddr
_stackaddr:     .long   0
        .globl  _fcn
_fcn:   .long   0
#endif

--45Z9DzgjV8m4Oswq
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="dyson-test.c"

#define SIZE 8192*2

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "dyson-rf.h"

static void testroutine(void *arg)
{
  int i;
  fprintf(stderr,"In test pid %d, stack is %p, val is %d\n"
	  , getpid(), &i, *(int*)arg);
}

int main(void)
{
  char *areas[5];
  int i;
  int childpid;
  int val_for_child = 42;
  int val_for_child2 = 43;

  for (i = 0; i<5 ; i++) {
    if ( (areas[i] = malloc(SIZE)) == NULL) {
      perror("malloc");
      exit(2);
    }
  }
  
  childpid = thrfork(RFPROC|RFMEM
		     , areas[0]
		     , testroutine
		     , &val_for_child
		     , areas[3]
		     , areas[4]
		     );
  if (childpid < 0) {
    perror("thrfork");
    exit(1);
  }
  testroutine(&val_for_child2);
  fprintf(stderr,"Obviously survived, cpid = %d (mypid = %d)\n"
	  , childpid
	  , getpid());
  wait((int *)NULL);
  exit(0);
}

--45Z9DzgjV8m4Oswq--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19980820142840.A28158>