<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
For that matter, we can just provide Thread.ForkAll.<BR>
  special implementation on pthreads.<BR>
  Just call Unix.fork() on user threads.<BR>
  No implementation for Win32.<BR>
 <BR>
 - Jay<BR>
 <BR>
<HR id=stopSpelling>
From: jay.krell@cornell.edu<BR>To: wagner@elegosoft.com; m3devel@elegosoft.com<BR>Date: Wed, 17 Mar 2010 11:02:02 +0000<BR>Subject: Re: [M3devel] cvsup<BR><BR>
<STYLE>
.ExternalClass .ecxhmmessage P
{padding:0px;}
.ExternalClass body.ecxhmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Another good option might be<BR>"RecreateThreadsAfterFork()"<BR> <BR>that cvsup can call. I'm trying that.<BR>If that doesn't work, I'll track down all of cvsup's thread creates.<BR> <BR> - Jay<BR> <BR>
<HR id=ecxstopSpelling>
From: jay.krell@cornell.edu<BR>To: wagner@elegosoft.com; m3devel@elegosoft.com<BR>Date: Wed, 17 Mar 2010 10:50:31 +0000<BR>Subject: Re: [M3devel] cvsup<BR><BR>
<STYLE>
.ExternalClass .ecxhmmessage P
{padding:0px;}
.ExternalClass body.ecxhmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Here's a shorter more direct version.<BR><BR><BR>Please start here:<BR><A href="http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html">http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html</A><BR>  "There are at least two serious problems with the semantics of <A href="http://www.opengroup.org/onlinepubs/009695399/functions/fork.html"><I>fork</I>()</A> in a multi-threaded program"<BR><BR> <BR>I have a good theory as to the problem and the fix.<BR> <BR> <BR>Problem:<BR> <BR>With user threads, when you fork(), all the threads keep running in the new child.<BR>   Because the data that causes them to exist is carried forward.<BR> <BR> <BR>With kernel threads, they don't, just the caller of fork().<BR> <BR> <BR>Fix:<BR>  A few small uses of pthread_atfork both in m3core and cvsup.<BR>  Abstracted behind Thread.PThreadAtFork that does nothing for user threads and Win32.<BR>  They would do things like "reinitialize globals" and "recreate worker threads".<BR> <BR> <BR>You can't just call all the module initializers over.<BR>That would ultimately I believe reset too much data.<BR>   ?<BR> <BR> <BR>It might be possible, though, to setjmp, run the module initializers, longjmp.<BR>Something like, perhaps, a flag to RTLinker.InitRuntime that causes it to<BR>longjmp instead of calling main. However this would still e.g. give the initial thread<BR>the wrong stackbase and mess up garbage collection.<BR> <BR> <BR>I'm much more keen on selective use of pthread_atfork, in m3core and cvsup.<BR> <BR> <BR>A more conventional approach is the program to rerun itself with some flags<BR>that "push" it fast to "resume" point, but that somewhat defeats the<BR>purpose of the fork + do work model -- cheap reuse of already established state.<BR> <BR> <BR>Lingering problem:<BR>  Any libraries that create worker threads need to use Thread.PThreadAtFork in order to be compatible with the fork + do more work pattern.<BR> <BR> <BR>fork + exec is fine.<BR> <BR> <BR> - Jay<BR>                                    </body>
</html>