<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
There are no public suspend/resume primitives exposed.<br>You can see in the debugger what happens.<br>The signal handling thread calls NtSuspendThread/NtResumeThread.<br>I suppose there is a chance they use the target thread's stack to hold<br>the full previous context, I can dig in the debugger and see.<br>I don't think what I have is too awful though.<br>You see the test_interix.c file?<br><br><br>I believe Cygwin does similar, though in that case the thread<br> probably doesn't have the constrained access and you can use<br> the public Win32 GetCurrentThread/DuplicateHandle/SuspendThread/ResumeThread functions.<br>Remember how I had that turning of pthread_self into GetThreadForThis, GetThreadForThat?<br>e.g. one is pthread_self, the other is GetCurrentThread/DuplicateHandle.<br>That might come back.<br><br> - Jay<br><br><hr id="stopSpelling">Subject: Re: pthread/Interix<br>From: hosking@cs.purdue.edu<br>Date: Wed, 16 Dec 2009 12:08:09 -0500<br>CC: m3devel@elegosoft.com<br>To: jay.krell@cornell.edu<br><br>

<base><div><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div style="word-wrap: break-word;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="ecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div><span class="ecxApple-style-span" style="font-size: medium;">On 16 Dec 2009, at 11:49, Jay K wrote:</span></div></span></span></span></span></span></span></span></span></div></span></span></div><div><br class="ecxApple-interchange-newline"><blockquote><span class="ecxApple-style-span" style="border-collapse: separate; font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="ecxhmmessage" style="font-size: 10pt; font-family: Verdana;">Signals are handled by a separate thread suspending the target thread and setting the context to run the signal handler. Therefore the state is on that thread's stack, not discoverable.<br></div></span></blockquote><div><br></div><div>Interesting, this is exactly the way Mach does signals (which is why we use the Mach suspend/resume primitives for Darwin/OSX).  If that is how they work, then can't you use the suspend/resume primitives directly?</div><br><blockquote><span class="ecxApple-style-span" style="border-collapse: separate; font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="ecxhmmessage" style="font-size: 10pt; font-family: Verdana;"> There is only single parameter signal handlers.</div></span></blockquote><blockquote><span class="ecxApple-style-span" style="border-collapse: separate; font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="ecxhmmessage" style="font-size: 10pt; font-family: Verdana;"><br>Normally we could suspend/resume the thread "directly" but the thread is I think created by an outside process and we don't have sufficient access. There is a handle with sufficient access, used by that signal handling thread, but it isn't accessible either.<br>That is what is particularly unfortunate.<br> <br>I think putting the two files in unconditionally and passing to the various functions, plus one other #ifdefed function "OpenInterixFiles" is a reasonable compromise. I've coded it up, haven't compiled/tested yet.<br> <br>An improvement would be to use the (normally) zero sized record and pass that to the C code instead, not wasting the storage on othe platforms.<br> <br>(A direct suspend/resume/getcontext solution will be good for Cygwin I'm sure.)<br> <br> - Jay<br><br> <br><hr id="ecxstopSpelling">Subject: Re: pthread/Interix<br>From:<span class="ecxApple-converted-space"> </span><a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>Date: Wed, 16 Dec 2009 11:40:56 -0500<br>CC:<span class="ecxApple-converted-space"> </span><a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>To:<span class="ecxApple-converted-space"> </span><a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br><br>I really dislike this... just for a broken platform...<div><br></div><div><div><div><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><div style="word-wrap: break-word;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px;"><div><font class="ecxecxApple-style-span" color="#0000ff" face="'Gill Sans'"><span class="ecxecxApple-style-span" style="font-size: medium;">Is there really no way to know that the context on is not on the stack somewhere?</span></font></div><div><font class="ecxecxApple-style-span" color="#0000ff" face="'Gill Sans'"><span class="ecxecxApple-style-span" style="font-size: medium;"><br></span></font></div><div><span class="ecxecxApple-style-span" style="font-size: medium;">On 16 Dec 2009, at 10:36, Jay K wrote:</span></div></span></span></span></span></span></span></span></span></div></span></span></div><div><br class="ecxecxApple-interchange-newline"><blockquote><span class="ecxecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: medium; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; white-space: normal; letter-spacing: normal; word-spacing: 0px;"><div class="ecxecxhmmessage" style="font-family: Verdana; font-size: 10pt;">[again, expect a bounce, but the mail does get through]<br> <br> <br>Tony, for Interix, suspend/resume thread can be achieved writing to a file.<br>Getting a suspended thread's registers can be gotten reading from a file.<br>(I believe the same thing works on Solaris.)<br>It appears to be intended for debuggers.<br>I can see that it works well.<br>I doubt that a thread's context is on a signal handler's stack.<br>I propose:<br> <br> <br>  ActState = { Starting, Started, Stopping, Stopped };<br>  REVEAL Activation = UNTRACED BRANDED REF RECORD<br>    frame: ADDRESS := NIL;              (* exception handling support *)<br>    handle: pthread_t := NIL;           (* LL = activeMu; thread handle *)<br>    statusFile: int := -1;              (* for Interix *)<br>    controlFile: int := -1;             (* for Interix *)<br>    (* C code knows the structure above this point *)<br>...<br>  END;<br><br> <br>ThreadPThread.h:<br> <br> <br>typedef struct _Activation_t {<br>    void* frame;<br>    void* pthread;<br>    int statusFile;  /* for Interix */<br>    int controlFile; /* for Interix */<br>} Activation_t;<br><br> <br>and then whereever we pass act.handle off to C code, pass act instead.<br> <br> <br>frame is kept first so that it is offset 0 in case that gives codegen efficiencies<br>on the often used push/popframe.<br>The other three are moved up to the top to reduce maintainence of ThreadPThread.h.<br> <br> <br>I assume "branding" doesn't introduce data in the record.<br>I'd have to check the codegen to verify frame is at offset 0.<br> <br> <br>#ifdef code will open the files.<br>Modula-3 code can check if the files are >= 0 and close them,<br>or it can be a call out to #ifdefed C.<br> <br> <br>An alternative is that wherever we pass act.handle, also pass act.statusFile and act.controlFile.<br>(as VAR for initialization).<br>That is less fragile and less extensible.<br>I'm fine with that approach too.<br> <br> <br>As well though, I was wondering, maybe we should have:<br> <br> <br>common/InterixThreadState.i3<br> T = RECORD END; (* zero size? *)<br> <br> <br>interix/InterixThreadState.i3<br>  T = RECORD statusFile, controlFile := -1; END;<br> <br> <br>and then put InterixThreadState.T in Activation.<br>That way saving the other platforms from spending the space.<br> Just two integers, not much, but in principle..<br> (We also sometimes use up 8 bytes for the pthread_t when 4 would suffice,<br>  on 64bit platforms with pthread_t == int, I think HP-UX is like that at least.)<br> <br> <br>I could also open/close the files for every suspend/resume/processStopped,<br>though that seems too lame.<br> <br> <br>Another idea, that I don't really like, is to never optimize and<br>ignore the registers and just use the stack.<br>I rarely optimize, but depending on that seems bad.<br> <br> <br>Your "safe points" proposal would also make this work, though<br>I'd rather not wait for that.<br> <br> <br>?<br> <br>Ok to add the two integers all the time?<br>Ok to either depend on the record layout in C, or to always pass the integers around?<br> <br> <br>Thanks,<br> - Jay<br></div></span></blockquote></div><br></div></div></div></span><br class="ecxApple-interchange-newline"></blockquote></div><br>                                           </body>
</html>