Hi Josh,<br><br><div class="gmail_quote">On Sun, Sep 20, 2009 at 12:43 PM, Joshua Gargus <span dir="ltr">&lt;<a href="mailto:schwa@fastmail.us">schwa@fastmail.us</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
Hi,<br>
<br>
I&#39;ve always assumed that signalSemaphoreWithIndex() must be thread-safe;<br>
after all, it&#39;s the &quot;official&quot; mechanism for notifying the image that an<br>
asynchronous event has occurred.  However, a pang of paranoia prompted<br>
me to actually look at the code, and it seems clearly unsafe.  This is<br>
bad, because I&#39;ve been using it to signal events from separate native<br>
threads.<br>
<br>
What should we do about this?  It seems to me that it should be wrapped<br>
in a critical section, using the appropriate platform-specific<br>
synchronization primitives.<br></blockquote><div> </div><div>There&#39;s no need for this heavyweight approach because the VM can only respond to these signals synchronously.  Instead we can use three variables per index to implement an exclusion-free solution, thusly:</div>
<div><br></div><div>typedef struct { int lock; // accessed via e.g. XCHG to protect signalRequest</div><div>                       int requests;</div><div>                       int responses;</div><div>           } ExternalSignalRequest;</div>
<div><br></div><div>ExternalSignalRequest *externalSignalRequests;</div><div>int checkExternalSignalRequests;</div><div><br></div><div>void</div><div>requestSignal(int i)</div><div>{</div><div>       while (!lock(&amp;externalSignalRequests[i].lock))</div>
<div>             usleep(1);</div><div><br></div><div>       ++externalSignalRequests[i].requests;</div><div><br></div><div>        unlock(&amp;externalSignalRequests[i].lock);</div><div><br></div><div>        checkExternalSignalRequests = 1;</div>
<div>        forceInterruptCheck();  // set a flag to cause the VM to check for interrupts; in the stack VM this is stackLimit := (usqInt)-1;</div><div>}</div><div>                       </div><div><br></div><div>The VM responds in checkEvents:</div>
<div><br></div><div>    if (checkExternalSignalRequests)</div><div>        for (i = 0; i &lt; numExternalSemaphores; i++)</div><div>            while (externalSignalRequests[i]. responses != externalSignalRequests[i]. requests) {</div>
<div>                signalSemaphoreWithIndex(i);</div><div>                externalSignalRequests[i]. responses;</div><div>            }</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<br>
Thanks,<br>
Josh<br>
</blockquote></div><br>