<br><br><div class="gmail_quote">On Sun, Sep 20, 2009 at 1:00 PM, Eliot Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi Josh,<br><br><div class="gmail_quote"><div><div></div><div class="h5">On Sun, Sep 20, 2009 at 12:43 PM, Joshua Gargus <span dir="ltr"><<a href="mailto:schwa@fastmail.us" target="_blank">schwa@fastmail.us</a>></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've always assumed that signalSemaphoreWithIndex() must be thread-safe;<br>
after all, it's the "official" 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'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></div><div>There's no need for this heavyweight approach because the VM can only respond to these signals synchronously.</div></div></blockquote><div><br>
</div><div>On second reading I think what I wrote below is exactly what you implied. Sorry.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="gmail_quote"><div> 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(&externalSignalRequests[i].lock))</div>
<div> usleep(1);</div><div><br></div><div> ++externalSignalRequests[i].requests;</div><div><br></div><div> unlock(&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 < 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>
</blockquote></div><br>