<div dir="ltr"><div class="gmail_extra">Hi Tim,</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 10, 2013 at 12:43 PM, tim Rowledge <span dir="ltr">&lt;<a href="mailto:tim@rowledge.org" target="_blank">tim@rowledge.org</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
I have a whole 8 methods that I changed to make generating sources appear to work on RISC OS, so I&#39;ll attempt to submit them later.<br>
<br>
Next question; what sort of changes were made to platform code to work with the new core? I&#39;ve noted the mention of the heartbeat ticker, which is actually something that may seriously benefit RISC OS and is probably something that ought to have been put in the plain VM years ago.<br>
</blockquote><div><br></div><div>The main changes (on the stack vm) are</div><div>- a heartbeat.  preferrably this is a thread in a spin-loop, blocking on a delay, and forcing a poll when it unblocks.  see <a href="http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/unix/vm/sqUnixHeartbeat.c">http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/unix/vm/sqUnixHeartbeat.c</a> &amp; <a href="http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/win32/vm/sqWin32Heartbeat.c">http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/win32/vm/sqWin32Heartbeat.c</a>.  but for this to work the heartbeat thread must have a higher priority than the VM thread and on linux only the superuser can create real-time threads that have settable priorities, so.... there-on one has to use an interval timer, which sucks as it a) interrupts system calls (SA_RESTART is essential but third-party libraries may be phased by the interval timer) and b) it&#39;s a pain to debug through cuz gdb will stop in the signal handler until one says &quot;handle 14 ignore&quot;, or some such.</div>
<div><br></div><div>- a 64-bit microsecond clock as the basis of time, see the heartbeat files.</div><div><br></div><div>- a thread-safe external semaphore registry, see <a href="http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/Cross/vm/sqExternalSemaphores.c">http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/Cross/vm/sqExternalSemaphores.c</a></div>
<div><br></div><div>- some atomic access primitives used to implement both the 64-bit microsecond clock and the external semaphore registry in a lock-free form.  see <a href="http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/Cross/vm/{sqAtomicOps.h,sqMemoryFence.h}">http://www.squeakvm.org/svn/squeak/branches/Cog/platforms/Cross/vm/{sqAtomicOps.h,sqMemoryFence.h}</a></div>
<div><br></div><div>There&#39;s also some Qwaq/teleplace/Term left-overs in the form of a ticker thread for running multi-media processing in parallel with the VM.  See sqTicker.c, but I wouldn&#39;t worry about that.</div>
<div><br></div><div>There&#39;s also some experimental stuff to do with support for a multi-threaded VM along the lines of e.g. the S# or Python VMs where any number of threads can share the VM, but only one is actually running the VM at any one time, and hand-over between threads is carefully mediated.  See various COGMTVM defines in the VM.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

Oh and I&#39;ve been trying to make sense of the global struct related changes. Umm…. a bit confused. Help.<br></blockquote><div><br></div><div>Ah.... well, one of my directions in modifying Slang for Cog/Qwaq was to defer decisions until compile time, getting Slang to generate source which could determine</div>
<div>- whether a plugin was internal or external</div><div>- whether a plugin was included</div><div>- whether to use the global struct or flat variables</div><div>could be chosen when compiling the VM, not when generating the source.  It makes the generated C source cross-platform, cuts down on duplication, and makes it much easier to run experiments to measure if the global struct is faster or not.</div>
<div><br></div><div>So... to defer the choice of global struct to compile time we...</div><div><br></div><div>a) wrap all references to variable which might be in the global struct in the GIV macro (Global Interpreter Variable), see CCodeGeneratorGlobalStructure&gt;&gt;#returnPrefixFromVariable:, so in the source you see e.g.</div>
<div><br></div><div><div>sqInt</div><div>interpret(void)</div><div>{   DECL_MAYBE_SQ_GLOBAL_STRUCT</div><div>    register sqInt currentBytecode CB_REG;</div><div>    register char* localFP FP_REG;</div><div>    register char* localIP IP_REG;</div>
<div>...</div><div><br></div><div>    if (GIV(stackLimit) == 0) {</div><div>        /* begin initStackPagesAndInterpret */</div></div><div><br></div><div>b) define GIV optionally, and output the variables that could be in the struct in a block with a suitable prefix.  It looks like:</div>
<div><br></div><div><div><span class="" style="white-space:pre">        </span>/*** Variables ***/</div><div><span class="" style="white-space:pre">        </span>#if SQ_USE_GLOBAL_STRUCT</div><div><span class="" style="white-space:pre">        </span># define _iss /* define in-struct static as void */</div>
<div><span class="" style="white-space:pre">        </span>static struct foo {</div><div><span class="" style="white-space:pre">        </span>#else</div><div><span class="" style="white-space:pre">        </span># define _iss static</div><div>
<span class="" style="white-space:pre">        </span>#endif</div><div><span class="" style="white-space:pre">        </span>_iss char * stackPointer;</div></div><div><span class="" style="white-space:pre">        </span>...</div><div><div><span class="" style="white-space:pre">        </span>_iss sqInt theUnknownShort;</div>
<div><span class="" style="white-space:pre">        </span>#undef _iss</div><div><span class="" style="white-space:pre">        </span>#if SQ_USE_GLOBAL_STRUCT</div><div><span class="" style="white-space:pre">        </span> } fum;</div><div>
<span class="" style="white-space:pre">        </span># define DECL_MAYBE_SQ_GLOBAL_STRUCT register struct foo * foo = &amp;fum;</div><div><span class="" style="white-space:pre">        </span># define DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT volatile register struct foo * foo = &amp;fum;</div>
<div><span class="" style="white-space:pre">        </span># define GIV(interpreterInstVar) (foo-&gt;interpreterInstVar)</div><div><span class="" style="white-space:pre">        </span>#else</div><div><span class="" style="white-space:pre">        </span># define DECL_MAYBE_SQ_GLOBAL_STRUCT /* oh, no mr bill! */</div>
<div><span class="" style="white-space:pre">        </span># define DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT /* oh no, mr bill! */</div><div><span class="" style="white-space:pre">        </span># define GIV(interpreterInstVar) interpreterInstVar</div>
<div><span class="" style="white-space:pre">        </span>#endif</div><div><span class="" style="white-space:pre">        </span>#if SQ_USE_GLOBAL_STRUCT</div><div><span class="" style="white-space:pre">        </span>static struct foo * foo = &amp;fum;</div>
<div><span class="" style="white-space:pre">        </span>#endif</div></div><div><br></div><div>which is effectively either</div><div><br></div><div><span class="" style="white-space:pre">        </span>static struct foo {<br></div><div>
<span class="" style="white-space:pre">        </span>    char * stackPointer;</div><div><span class="" style="white-space:pre">        </span>    ....</div><div><span class="" style="white-space:pre">        </span>    char * stackPointer;</div>
<div><span class="" style="white-space:pre">        </span>} fum;</div><div><br></div><div><span class="" style="white-space:pre">        </span>#define GIV(v) (foo-&gt;v)</div><div><br></div><div>or</div><div><br></div><div><span class="" style="white-space:pre">        </span>static char * stackPointer;</div>
<div><span class="" style="white-space:pre">        </span>...</div><div><span class="" style="white-space:pre">        </span>static sqInt theUnknownShort;</div><div><span class="" style="white-space:pre">        </span>#define GIV(v) v</div>
</div><br clear="all"><div>c) define an optional macro for declaring a local reference to foo in functions that need it, so you see</div><div><br></div><div><div>sqInt</div><div>interpret(void)</div><div>{   DECL_MAYBE_SQ_GLOBAL_STRUCT</div>
</div><div><br></div><div>and there&#39;s either</div><div><br></div><div><div><span class="" style="white-space:pre">        </span># define DECL_MAYBE_SQ_GLOBAL_STRUCT register struct foo * foo = &amp;fum;</div><div><span class="" style="white-space:pre">        </span># define DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT volatile register struct foo * foo = &amp;fum;</div>
</div><div><br></div><div>or</div><div><br></div><div><div><span class="" style="white-space:pre">        </span># define DECL_MAYBE_SQ_GLOBAL_STRUCT /* oh, no mr bill! */</div><div><span class="" style="white-space:pre">        </span># define DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT /* oh no, mr bill! */</div>
</div><div><br></div><div><br></div><div>Then in your makefile you can do -DUSE_GLOBAL_STRUCT=1 if it floats your boat.  This is a great idea on PPC but doesn&#39;t work on x86.  I&#39;d be interested to know which is better on ARM.</div>
<div><br></div><div>Make sense?  If not, uncork a Bowmore and read at leisure...</div>-- <br>best,<div>Eliot</div>
</div></div>