Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Sep 1997 10:17:57 -0400 (EDT)
From:      Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
To:        "John S. Dyson" <toor@dyson.iquest.net>
Cc:        current@FreeBSD.ORG
Subject:   Re: FYI: regarding our rfork(2)
Message-ID:  <199709191417.KAA28139@khavrinen.lcs.mit.edu>
In-Reply-To: <199709190119.UAA00556@dyson.iquest.net>
References:  <199709190012.CAA11932@ocean.campus.luth.se> <199709190119.UAA00556@dyson.iquest.net>

next in thread | previous in thread | raw e-mail | index | archive | help
<<On Thu, 18 Sep 1997 20:19:13 -0500 (EST), "John S. Dyson" <toor@dyson.iquest.net> said:

> We are actually doing a pure memory sharing operation.  We will be sharing
> everything, plan 9 doesn't appear to share the stack.  In order to support
> pthreads, (and most thread schemes that I have seen), it is best to allow
> full access to all of the thread stacks.  The 'full sharing' scheme is very
> fast.

We ought to emulate SGI's sproc(2) system call as well, which does
essentially the same thing.  It has the useful feature that it takes
as an argument the address of a function to call, and does all the
stack creation magic internally before calling same.  So, the inner
loop of a program I wrote a long time ago on an SGI looks like this:

void do_sproc(volatile int *manyRows[]) {
  int pids[MAXPROCS];
  struct info infos[MAXPROCS];
  int i;
  double aval = curA;

  for(i=0; i < nprocs - 1; i++,aval -= aincr) {
    infos[i].row = manyRows[i];
    infos[i].curA = aval;
    pids[i] = sproc(doit,PR_SALL,(void *)&infos[i]);
  }
  real_doit(aval,manyRows[i]);

  /*
   * We know we started (nprocs - 1) kids, so we wait for (nprocs - 1) kids
   * to die.
   */
  for(i=0; i < nprocs - 1; i++) {
    (void)wait((int *)0);
  }
}


The prototype is:

int sproc(void (*func)(void *arg), unsigned what, ... /* void */);
int sprocsp(void (*func)(void *arg, size_t stklen), unsigned what,
	    void *arg, caddr_t sp /* 0 == auto */, size_t maxstklen);

There is also a related function:

int prctl(pid_t pid, unsigned what, ...);

which manages some process-related behavior.

The particularly interesting values of `what' for sproc are:
	PR_SADDR (== RFMEM)
	PR_SFD (== RFFDG)
	PR_SDIR (== like RFFDG but for curdir/rootdir)
	PR_SUMASK (== like RFFDG but for umask)
	PR_SULIMIT (== like RFFDG but for resource limits)
	PR_SID (== like RFFDG but for credentials)
	PR_SALL (== all of the above)

There are additionally a couple of of flags, PR_BLOCK (used to provide
vfork-like behavior, if I read the man page right) and PR_NOLIBC
(which disables the C library thread support for the new child).

The prctl(2) system call has a couple of potentially interesting
options and a lot of boring ones.  The potentially interesting ones
are PR_SETEXITSIG (which selects either standard POSIX exit(2)
behavior, or causes each share to get a specified signal if the named
process exits), and PR_TERMCHILD (which causes children of the caller
to receive a SIGHUP if the parent exits).

-GAWollman

--
Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the same
wollman@lcs.mit.edu  | O Siem / The fires of freedom 
Opinions not those of| Dance in the burning flame
MIT, LCS, CRS, or NSA|                     - Susan Aglukark and Chad Irschick



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