<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 6, 2015 at 10:47 PM, Craig Latta <span dir="ltr">&lt;<a href="mailto:craig@netjam.org" target="_blank">craig@netjam.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
<br>
Hi all--<br>
<br>
     Apologies, my newsreader&#39;s thread database got trashed, and I<br>
missed the responses to my previous message until now.<br>
<br>
     John McIntosh writes:<br>
<br>
&gt; Craig so how does using pthread_cond_timedwait affect socket<br>
&gt; processing?<br>
<br>
     It makes it actually work well. :)  This was the whole point of<br>
using pthread_cond_timedwait. Please read the manpage at [1]. It waits<br>
until either a condition is met (hence the &quot;cond&quot;) or a timeout elapses.<br>
<br>
     In the Flow virtual machine plugin, I have a<br>
synchronizedSignalSemaphoreWithIndex function that calls the usual<br>
signalSemaphoreWithIndex provided by the virtual machine, and also sets<br>
the activity condition that the relinquish primitive cares about. The<br>
host threads which service external I/O requests from primitives use<br>
synchronizedSignalSemaphoreWithIndex when signalling the semaphores on<br>
which Smalltalk-level code is waiting. This includes not only the<br>
semaphores for reading and writing sockets, but also those for<br>
activities with other external resources entirely, like MIDI ports.<br>
<br>
     So you get a generalized scheme which is not tied to the arcana of<br>
any particular kind of external resource, and it works the same way on<br>
any platform which supports the POSIX API (which now is all the Unix-ish<br>
ones). This has seemed the obvious way to go for over ten years now.<br>
<br>
     Until I implemented this scheme, remote messaging throughput (and<br>
MIDI throughput) was horrible. Believe me, I tried all the other schemes<br>
that everyone has mentioned in the Squeak community and its descendants<br>
since 1996, and none of them were anything better than deeply embarrassing.<br>
<br>
     From the Flow plugin, check out flow.c[2], which implements<br>
synchronizedSignalSemaphoreWithIndex, the activity condition, and the<br>
relinquish primitive, and ip.c[3] which creates host threads to do<br>
background work for external resource primitives and uses<br>
synchronizedSignalSemaphoreWithIndex to coordinate with the<br>
Smalltalk-level code and the relinquish primitive.<br>
<br>
     It&#39;s so frustrating and weird that we&#39;re still talking about this<br>
in 2015.<br>
<br>
&gt; The promise of nanosleep was to wake up if an interrupt arrived say<br>
&gt; on a socket (Mind I never actually confirmed this the case, complete<br>
&gt; hearsay...)<br>
<br>
     Right, nanosleep promises this and doesn&#39;t deliver on MacOS, so I<br>
say forget it. pthread_cond_timedwait works as advertised on MacOS and<br>
Linux (all distros).<br>
<br>
     Eliot writes:<br>
<br>
&gt; +1.  What [John] said.<br>
<br>
     ...except John admitted himself that he hadn&#39;t verified his<br>
suggestion, and you both assumed for some reason that I didn&#39;t have the<br>
same goals in mind.<br>
<br>
&gt; The problem with pthread_cond_timed_wait, or any other merely<br>
&gt; delaying call...<br>
<br>
     But pthread_cond_timedwait is *not* a &quot;merely delaying call&quot;. It<br>
does exactly what we want (wait until *either* a condition is met or a<br>
timeout elapses), and it actually works, and the code is the same across<br>
POSIX platforms.<br>
<br>
     What you go on to say is based on a false premise.<br>
<br>
&gt; ...is that, unless all file descriptors have been set up to send<br>
&gt; signals on read/writability and unless the blocking call is<br>
&gt; interruptible, the call may block for as long as it is asked, not<br>
&gt; until that or the read/writeability of the file descriptor.<br>
<br>
     In the scheme I described above, we can do what we need without<br>
using formal Unix signals at all (happily avoiding that whole can of<br>
worms). The notion of interruptible blocking calls is a red herring<br>
generally. All the blocking calls in Flow happen in host threads which<br>
are decoupled from any function call a Smalltalk primitive would make.<br>
<br>
&gt; IMO a better solution here is to a) use epoll or its equivalent<br>
&gt; kqueue; these are like select but the state of which selectors to<br>
&gt; examine is kept in kernel space, so the set-up overhead is vastly<br>
&gt; reduced, and b) wait for no longer than the next scheduled delay if<br>
&gt; one is in progres.<br>
<br>
     I claim they are not better solutions, because they don&#39;t work for<br>
all kinds of external resources (e.g., MIDI ports). Also, I found that<br>
&quot;waiting for no longer than the next scheduled delay&quot; is often still far<br>
too long, when there is external resource activity before that time comes.<br>
<br>
&gt; Of course, the VM can do both of these things, and then there&#39;s no<br>
&gt; need for a background [Smalltalk] process at all.  Instead, when the<br>
&gt; VM scheduler finds there&#39;s nothing to run it calls epoll or kqueue<br>
&gt; with either an infinite timeout (if no delay is in progress) or the<br>
&gt; time until the next delay expiration.<br>
<br>
     This would still leave us with poor performance when using new<br>
kinds of external resources that don&#39;t use selectors. (That is, the<br>
external resource access would perform poorly; I&#39;m sure the main virtual<br>
machine would scream right along, blissfully oblivious to it all. :)<br>
<br>
&gt; It strikes me that the VM can have a flag that makes it behave like<br>
&gt; this so that e.g. some time in the Spur release cycle we can set the<br>
&gt; flag, nuke the background process and get on with our lives.<br>
<br>
     If the only external resources in our lives were selector-using<br>
ones, I might agree.<br>
<br>
<br>
     thanks,<br>
<br>
-C<br>
<br>
[1] <a href="http://linux.die.net/man/3/pthread_cond_timedwait" target="_blank">http://linux.die.net/man/3/pthread_cond_timedwait</a><br>
[2] <a href="https://github.com/ccrraaiigg/flow/blob/master/flow.c" target="_blank">https://github.com/ccrraaiigg/flow/blob/master/flow.c</a><br>
[3] <a href="https://github.com/ccrraaiigg/flow/blob/master/ip.c" target="_blank">https://github.com/ccrraaiigg/flow/blob/master/ip.c</a><br>
<div><div><br>
</div><div><br></div></div></blockquote><div><br></div><div>(Sorry for this late response. I discovered it sitting in my Draft folder.)</div><div><br></div><div>Finding this an interesting topic, I googled around to learn more and bumped into a few things maybe of random interest for some. </div><div><br></div><div><div>* Condition variables performance of boost, Win32, and the C++11 standard library<br><a href="https://codesequoia.wordpress.com/2013/03/27/condition-variables-performance-of-boost-win32-and-the-c11-standard-library/" target="_blank">https://codesequoia.wordpress.com/2013/03/27/condition-variables-performance-of-boost-win32-and-the-c11-standard-library/</a><br></div></div><div><br></div><div>* pthread_cond_timedwait behaving differently on different platforms<br><a href="http://blogs.msdn.com/b/cellfish/archive/2009/09/01/pthread-cond-timedwait-behaving-differently-on-different-platforms.aspx" target="_blank">http://blogs.msdn.com/b/cellfish/archive/2009/09/01/pthread-cond-timedwait-behaving-differently-on-different-platforms.aspx</a>  </div><div><br></div><div>* pthread-win32 pthread_cond_timedwait is SLOW?<br><a href="http://comp.programming.threads.narkive.com/fZU5gh0K/pthread-win32-pthread-cond-timedwait-is-slow" target="_blank">http://comp.programming.threads.narkive.com/fZU5gh0K/pthread-win32-pthread-cond-timedwait-is-slow</a><br></div><div><br></div><div>* Fast Event Processing in SDL (since Pharo is getting SDL)</div><div><a href="http://gameprogrammer.com/fastevents/fastevents1.html" target="_blank">http://gameprogrammer.com/fastevents/fastevents1.html</a><br></div><div><br></div><div>cheers -ben</div></div></div></div>