<br><br><div class="gmail_quote">On Wed, Jan 27, 2010 at 7:31 AM, Brian Denheyer <span dir="ltr">&lt;<a href="mailto:briand@aracnet.com">briand@aracnet.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Tue, 26 Jan 2010 22:41:44 -0800<br>
<div class="im">Thomas DuBuisson &lt;<a href="mailto:thomas.dubuisson@gmail.com">thomas.dubuisson@gmail.com</a>&gt; wrote:<br>
<br>
&gt; Brian Denheyer &lt;<a href="mailto:briand@aracnet.com">briand@aracnet.com</a>&gt; wrote:<br>
&gt;<br>
&gt; &gt; On Tue, 26 Jan 2010 10:54:03 -0800<br>
&gt; &gt; Thomas DuBuisson &lt;<a href="mailto:thomas.dubuisson@gmail.com">thomas.dubuisson@gmail.com</a>&gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt; &gt; &gt; doEvent f usDelay = forkIO $<br>
&gt; &gt; &gt; &gt;   threadDelay usDelay<br>
&gt; &gt; &gt; &gt;   doEvent f usDelay<br>
&gt; &gt; &gt; &gt;   f<br>
&gt; &gt;<br>
&gt; &gt; Are you sure that&#39;s right ? It seems to be a memory-gobbling<br>
&gt; &gt; infinite loop...<br>
&gt; &gt;<br>
&gt;<br>
&gt; Infinite loop?  yes, that is what you wanted.  Memory gobbling?  Why<br>
&gt; would you think that? Are you assuming no TCO and a full stack push<br>
&gt; on every function call?  Haskell compilers don&#39;t work that way.<br>
<br>
</div>Why would I think that ?<br>
I think that because the following code:<br>
<br>
import Control.Concurrent<br>
<br>
f = putStrLn &quot;foo&quot;<br>
<br>
doEvent f usDelay = do forkIO $ threadDelay usDelay<br>
                       doEvent f usDelay<br>
                       f<br>
<br>
_really_ _does_ start to consume all of the memory on my system, that&#39;s<br>
why.  I don&#39;t know why, but that&#39;s what it does on my system.  It&#39;s not<br>
obvious to me that it should do that.  So maybe ghci is not doing TCO.<br></blockquote><div><br>That would be a bug!  I&#39;m using GHC 6.12.1 i386 and both interpreted
using GHCi CLI and compiled (even without optimization) there is no
memory growth using either of the two versions.  If you are using the
latest GHC then consider filing a report at <a href="http://haskell.org/ghc">haskell.org/ghc</a><br>
<br>
<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">&gt; 2) It strikes me as funny you suspect the first way when there is zero<br>

&gt; fundamental difference between that and the way you posted except<br>
&gt; that: a) My version maintains the correct delay.<br>
&gt; b) My version forks the doEvent call and runs the action in the older<br>
&gt; thread while yours forks the action thread and keeps the doEvent in<br>
&gt; the older thread.  I suppose keeping the doEvent as the old thread is<br>
&gt; good so you can kill it with the original ThreadID that would be<br>
&gt; returned to the caller.<br>
&gt;<br>
<br>
</div>Thanks for the explanation, as I said I&#39;m a little fuzzy on what<br>
constitutes a thread, so the two versions will help.<br></blockquote><div><br>Well Concurrent Haskell has a version of green threads [1] which are scheduled (via the GHC RTS) on some number of OS threads (typically either 1 or equal to the number of cores on the machine).  These light weight &quot;green threads&quot; are extremely cheap to create and destroy, costing a matter of 1K or less per thread, benchmarks can create/destory 100k threads in seconds.  &quot;forkIO&quot; creates green threads while &quot;forkOS&quot; (which you generally should not use) creates OS threads. <br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
One interesting thing I noticed in the docs (which is not important<br>
for what I am trying to do, just interesting):<br>
<br>
There is no guarantee that the thread will be rescheduled promptly when<br>
the delay has expired, but the thread will never continue to run<br>
earlier than specified.<br></blockquote><div><br>Right, and this is the same as any commodity OS - you can delay for a certain amount of time and once the delay is up you will get rescheduled but the computer is likely busy with other processes/interrupts etc at the exact microsecond you are done.  I think the GHC RTS schedules threads in 50us slices by default.  Also, GHC uses (or used to use) allocation as a scheduling point so if you have long-running tight loops that don&#39;t allocate (and don&#39;t explicitly call &#39;yield&#39;) then this could be quite long.  In practice I&#39;ve only once had a problem (GTK GUI didn&#39;t update during a long computation - still not sure this was the reason).<br>
<br></div>Cheers,<br>Thomas<br><br></div>[1] <a href="http://en.wikipedia.org/wiki/Green_threads">http://en.wikipedia.org/wiki/Green_threads</a><br>