Hi Josh,<br><br><div class="gmail_quote">On Sun, Sep 20, 2009 at 12:43 PM, Joshua Gargus <span dir="ltr"><<a href="mailto:schwa@fastmail.us">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>There'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(&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>