<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div apple-content-edited="true"><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>I am a little uneasy about calloc being used instead of RTAllocator.  We lose the single point of allocation that is useful for all sorts of things like accounting, etc.  I'll take a look at what you have done and think about it some...</div><div><font class="Apple-style-span" face="GillSans-Light"><br></font></div></span></span></span></span></span></span></span></span></div></span></div><div><div>On 31 Mar 2009, at 09:15, Jay wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><br>hm, thinking about this more...<br>What about threads not created by Modula-3 Fork() (or the first thread)?<br><br><br>It looks like exception handling had a chance of working on them<br>before. Now they'll crash upon entering functions<br>with try or raise or I presume lock.<br><br><br>1) ok?<br><br><br>2) do the heap alloc on demand?<br>  But is that enough? Can it be initialized without further context?<br>  Let's see..the circular list can be maintained without further context.<br>  handle := pthread_self, ok. stack can probably be figured out, though<br>  that is probably just for gc and could be left alone for now, continuing<br>  to not work (or fixed)...getcontext at least on some platforms can<br>  fill this in, or VirtualQuery/msomething (mmap family?)?<br><br><br>3) put back the second thread local?<br><br><br>#2 has a chance of working better than before -- letting GC<br>work on threads not created by Modula-3 runtime, something<br>that has long bothered me...but I haven't done a complete analysis.<br>Or at least maybe keep it working as it was<br>For now there is somewhat of a regression, ie, when calling<br>Modula-3 code on threads not created from Modula-3.<br>Possibly the gc in this case was already dangerous?<br>Failing to find references on other stacks?<br>Or failing all allocations (should be easy to check but I have to run..)<br><br><br> - Jay<br><br><br><br><br><br><br><br><br><br><br><br>----------------------------------------<br><blockquote type="cite">From: <a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br></blockquote><blockquote type="cite">To: <a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br></blockquote><blockquote type="cite">CC: <a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br></blockquote><blockquote type="cite">Subject: RE: [M3devel] per thread data?<br></blockquote><blockquote type="cite">Date: Mon, 30 Mar 2009 13:23:10 +0000<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">This was surprisingly difficult.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">InitHandlers is called much earlier than InitActivations.<br></blockquote><blockquote type="cite">InitActivations does a heap allocation.<br></blockquote><blockquote type="cite">InitHandlers did not.<br></blockquote><blockquote type="cite">The types involved are not yet initialized at this point, or somesuch.<br></blockquote><blockquote type="cite">You cannot NEW(Activation) in the first call to PushFrame.<br></blockquote><blockquote type="cite">So, maybe, use a global for the first one,<br></blockquote><blockquote type="cite">but then what happens is it gets reinitialized later by<br></blockquote><blockquote type="cite">the module initializer -- which is perhaps another indictment<br></blockquote><blockquote type="cite">of initializers..or maybe a special case in the depths of the system --<br></blockquote><blockquote type="cite">this module and anything it uses are subject to be called by<br></blockquote><blockquote type="cite">compiler-generated calls -- they can be called before their initializers<br></blockquote><blockquote type="cite">run.. seems to me the initialization could have happened "statically"<br></blockquote><blockquote type="cite">like in C.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Anyway, I should have this done shortly.<br></blockquote><blockquote type="cite">Trick is to use a local value and assign it to a heap block<br></blockquote><blockquote type="cite">allocated directly with calloc instead of RTAllocator.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">The result is maybe faster, maybe slower.<br></blockquote><blockquote type="cite">Before, "try" cost pthread_getspecific and setspecific.<br></blockquote><blockquote type="cite">Now it will just cost getspecific.<br></blockquote><blockquote type="cite">But with another pointer deref and call to GetActivation<br></blockquote><blockquote type="cite">with its on-demand initialization.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Before, popframe only called setspecific.<br></blockquote><blockquote type="cite">Now it will only call getspecific, plus the indirect<br></blockquote><blockquote type="cite">and on-demand initialization.<br></blockquote><blockquote type="cite">The on-demand seems bogus in pop, given that push already had to occur.<br></blockquote><blockquote type="cite">So maybe that could be optimized.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">This stuff is highly optimized in C and C++ on NT..<br></blockquote><blockquote type="cite">NT/x86 has a special thread local just for exception handling,<br></blockquote><blockquote type="cite">faster than all other thread locals.<br></blockquote><blockquote type="cite">All non-x86 NT platforms have stack walkers -- no cost for "try",<br></blockquote><blockquote type="cite">and then "throw" maps instruction pointer to data about how to<br></blockquote><blockquote type="cite">to unwind the stack, using a little mini-assembly code.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">- Jay<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">________________________________<br></blockquote><blockquote type="cite"><blockquote type="cite">From: <a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">To: <a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Date: Thu, 19 Mar 2009 01:03:57 +0000<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">CC: <a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Subject: Re: [M3devel] per thread data?<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"><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"><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">Thanks, I should get around to that "soon" then.<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"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">- Jay<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"><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">From: <a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">To: <a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Date: Thu, 19 Mar 2009 10:14:59 +1100<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">CC: <a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Subject: Re: [M3devel] per thread data?<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">I have no problem putting the exception handler stack thread local into the activation thread local.<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"><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"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">On 18 Mar 2009, at 20:11, Jay wrote:<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"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">I'm not looking at it right now, but doesn't seem rather piggy to have two thread locals and data on the side?<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">I'm guessing the data on the side is needed because we need to be able to enumerate our threads, to suspend them all?<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">I understand that having multiple thread locals optimizes their use, but it seems greedy.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">vs. a small heap allocation that combines them.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Or in fact.. presumably there could just be one thread local that is the thread pointer, and the handler link could be put at the start, for architectures where zero offset is smaller/faster than non-zero offset.<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">Another idea, of course, is to look into "__thread", "__declspec(thread)".<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">On Windows and probably all platforms they exist on, they are nicely more efficient than pthread_get/setspecific, except on Windows they don't really work acceptably prior to Vista -- they only work in .exes and their static dependencies, not any .dll you load after the process starts with LoadLibrary (dlopen).<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">Does "__thread" work well on most non-Windows platforms?<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">i.e. even if shared object is loaded with dlopen?<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">I could have sworn I saw code out there that was "adaptive".<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">It easily/efficiently checked if it was loaded with LoadLibrary or not.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">If so, it'd TlsGet/SetValue (pthread_get/setspecific).<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">If not, it'd use __declspec(thread) (__thread).<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">The check was based on if __tlsindex was not zero or somesuch. I couldn't track it down though.<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">In either case, yes, I know, one of the thread locals at least is gone on platforms that have stack walkers, e.g. Solaris, and potentially NT, and maybe others.<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">- Jay<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></div></blockquote></div><br></body></html>