<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">It doesn't work because of security enhancements that prevent forgery of a context as the current system does.  swapcontext *is* used on Solaris (as currently implemented) but the InitContext code needs replacing with makecontext.  longjmp is not async-signal-safe, and so just as bad as swapcontext when called from a signal handler.  Indeed, BSD seems to imply swapcontext can be used in a signal handler.<div><br></div><div>I don't want to leap into explicit polling of a yield flag without further thought.  Better to get <br><div><br><div> <span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; 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-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div><font class="Apple-style-span" color="#0000FF"><font class="Apple-style-span" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; ">Antony Hosking</span></span></font></font><font class="Apple-style-span" face="Gill Sans"><span class="Apple-style-span" style="font-family: Gill Sans; "><span class="Apple-style-span" style="font-family: Gill Sans; "> | </span></span><span class="Apple-style-span" style="font-family: Gill Sans; "><span class="Apple-style-span" style="font-family: Gill Sans; ">Associate Professor</span></span><span class="Apple-style-span" style="font-family: Gill Sans; "><span class="Apple-style-span" style="font-family: Gill Sans; "> | Computer Science | Purdue University</span></span></font></div><div><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; ">305 N. University Street | West Lafayette | IN 47907 | USA</span></font></div><div><font class="Apple-style-span" color="#0000FF" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; ">Office</span></span></font><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; "><span class="Apple-style-span" style="font-family: GillSans-Light; "> +1 765 494 6001 | </span></span></font><font class="Apple-style-span" color="#0000FF" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: Gill Sans; ">Mobile</span></span></font><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; "><span class="Apple-style-span" style="font-family: GillSans-Light; "> +1 765 427 5484</span></span></font></div><div><font class="Apple-style-span" face="GillSans-Light"><br class="khtml-block-placeholder"></font></div></span></span></span></span></span></span></span><br class="Apple-interchange-newline"></span></div></span> </div><br><div><div>On 31 Jan 2009, at 14:46, Jay wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><br>I think setjmp/longjmp would continue to be ok.<br>It has very little machine dependency, and I /guess/ works and is portable.<br>I guess. We are both leary, but it's been there a while.<br>It is InitContext imho that could be "better" --  more portable, remove all the<br>mucking around with frames and stack pointers.<br>I was late to see this because it is in the machine-independent chunk of code.<br><br><br>What does swapcontext buy over setjmp/longjmp, once a thread is "already started"?<br>I can see there is a "unifying" reason.<br>If makecontext is used to InitContext, then swapcontext is needed to "start" a thread.<br>setjmp/longjmp could be used to suspend/resume, but if you phrase "start" and "resume" as the same thing, then "stuck" with swapcontext.<br><br><br>For some time I was under the impression that Modula-3 repeatedly longjmped to a buffer that only had setjmp called once, or where the function that setjmp was called from had returned, but I'm not sure of that now. It seems viable to "follow the rules" wrt setjmp/longjmp, other than the "escaping from a signal handler" aspect.<br><br><br><blockquote type="cite">The safest solution for all of this is to have the timer signal <br></blockquote><blockquote type="cite">handler set a flag and for the M3 compiler to inject a test of the <br></blockquote><blockquote type="cite">flag at calls/backward branches, and explicitly yield if the flag is <br></blockquote><blockquote type="cite">set. <br></blockquote><br><br>Yes that makes me much more comfortable as well.<br><br><br>Is it cut & dry agreed to and such?<br><br><br>Someone should just do it?<br><br><br> Or there are concerns that: <br>  - it might not be often enough? <br>    There are no "forward" or "backward" branches at the Modula-3 level, are there?<br>    It is at the whim of the backend, right? I guess you might be able to<br>    conceptually label branches as forward or backward, even if the backend "rotates" things or<br>     adds  more branches (you know, like loops often starting with a forward branch).<br>  - it might be too often? <br>  - it might be too code bloating? Or too slow when "checks" greatly outweight actual switches? <br>  - a call out to a function or a check of a variable? <br>  - only do it if a compiler command line switch is given? Or for platforms known to support user threads? (given the design though..it could be every platform)<br><br><br> Though I raise the issues, it still seems the right thing, vs. longjmping out of a signal handler.<br><br><br>The OpenBSD sigaction manpage does seem to have in mind an ability to "switch threads" in a signal handler:<br><br><br>     "When a caught<br>     signal is delivered, the current state of the process is saved, a new<br>     signal mask is calculated (as described below), and the signal handler is<br>     invoked.  The call to the handler is arranged so that if the signal han-<br>     dling routine returns normally the process will resume execution in the<br>     context from before the signal's delivery.  If the process wishes to re-<br>     sume in a different context, then it must arrange to restore the previous<br>     context itself.<br>     "<br><br> but the idea here is not longjmp or I think exactly swapcontext, but manually swapping a context with the third parameter to the signal handler.<br><br><br><blockquote type="cite">single-threaded process, but I don't know if that really prevents a <br></blockquote><blockquote type="cite">timer signal arriving inside the signal handler, and what impact that <br></blockquote><blockquote type="cite">might have. <br></blockquote><br><br>Right. I don't see that control-c can't come in at about the same time as timer.<br>Though I think sigaction allows for fixing this -- block all signals during the signal handler.<br>I'll reread some manpages.<br><br><br> - Jay<br><br><br><br>----------------------------------------<br><blockquote type="cite">From: <a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br></blockquote><blockquote type="cite">To: <a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br></blockquote><blockquote type="cite">Date: Sat, 31 Jan 2009 14:09:23 +1100<br></blockquote><blockquote type="cite">CC: <a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br></blockquote><blockquote type="cite">Subject: Re: [M3devel] using *context functions for user threading?<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">On 31 Jan 2009, at 09:49, Jay wrote:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">Tony, can you tell me more of what you have in mind here?<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I didn't plan anything other than using swapcontext instead of longjmp<br></blockquote><blockquote type="cite">in switch_thread, and using makecontext instead of InitContext to get<br></blockquote><blockquote type="cite">a forked thread's context.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">In particular...I /think/ it goes like:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">use getcontext + makecontext to "create a thread"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">use simple struct copying/memcpy of the third parameter to the<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">signal handler for context switching<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">No, swapcontext.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">in particular -- setcontext/makecontext never used -- except to<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">start a thread, but not to switch to/from already started threads.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Right.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">?<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Implication here is that even on systems without context APIs, our<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">ucontext_t needs to match what the signal handler gets. That isn't<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">the case for what I just got "working" (prototype, proof of concept,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">whatever) on OpenBSD, but easy enough.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I don't know what you are saying here. swapcontext should be enough.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">An alternative is to call setcontext in the signal handler, but that<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">makes me nervous.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">It seems best to exit "cleanly" out of a signal handler?<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">You're right, but this is probably broken for the current longjmp-<br></blockquote><blockquote type="cite">based implementation too.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">And then I get to seeing very murky things, like, can a system call<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">be interrupted by an alarm signal? If so, switching threads<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">then...what would that do? Seems bad.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Yes, I was never convinced that the longjmp-based implementation was<br></blockquote><blockquote type="cite">safe either. I figured that it probably worked only because it was a<br></blockquote><blockquote type="cite">single-threaded process, but I don't know if that really prevents a<br></blockquote><blockquote type="cite">timer signal arriving inside the signal handler, and what impact that<br></blockquote><blockquote type="cite">might have.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">So then I guess I see the origin of all the original system call<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">wrappers -- to turn of thread switching during system calls.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">No, those were only for GC.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">?<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">The current code does appear to longjmp out of a system call -- or<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">rather, to longjmp from one alarm signal to another. Again this<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">seems confusing if alarm signals can interrupt system calls.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Right...<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">Some abstraction that encompasses Win32 fibers might be nice, though<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">there would remain the question of how to preempt.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">The safest solution for all of this is to have the timer signal<br></blockquote><blockquote type="cite">handler set a flag and for the M3 compiler to inject a test of the<br></blockquote><blockquote type="cite">flag at calls/backward branches, and explicitly yield if the flag is<br></blockquote><blockquote type="cite">set.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">- Jay<br></blockquote></blockquote><blockquote type="cite"><br></blockquote></div></blockquote></div><br></div></div></body></html>