On 2/20/07, <b class="gmail_sendername">Lang Martin</b> <<a href="mailto:lang-gb@coptix.com">lang-gb@coptix.com</a>> wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I have a (possibly irrational) bias against mutexes, and attempted to<br>solve a threading problem with just message passing. The code works,<br>but only part of the time.</blockquote><div><br>I haven't run your code myself, but I think I see a few things wrong with it.
<br> </div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">This code:<br><br>(let ((th (thread-start!<br>            (make-thread<br>             (lambda ()
<br>               (let lp ()<br>                 (let ((p (thread-receive 0 #f)))<br>                   (if p<br>                       (p 40)<br>                       (begin<br>                         (thread-yield!)<br>
                         (lp))))))))))<br>        (+ 2 (call/cc<br>         (lambda (ret)<br>           (thread-send th ret)<br>           (thread-sleep! 4)))))<br><br><br>Occasionally fails by attempting to add 2 to #!void. 
</blockquote><div><br>Let's call the original thread "thread #1" and the newly created one "thread #2".  <br><br>Thread #1 will start thread #2, capture its own continuation and send it to thread #2.  Then it adds the result of (thread-sleep! 4) [which is #!void] to 2, which cause your error after 4 seconds.
<br><br>In thread #2, calling (p 40) will make that thread invoke thread #1's continuation, resulting in a final result of 42.  Note that thread #2 will not loop if it gets the continuation as a message, because it discards its own continuation when invoking (p 40).  It basically becomes thread #1 at that point.
<br><br>Other notes: you should just wait in thread #2 for a message instead of waiting in a spin lock (ie using 'thread-receive' with a timeout of 0).  Also, calling 'thread-yield!' isn't necessary since Gambit's thread system is preemptive.
<br><br>Finally, for debugging it might help to use Gambit's command-line options so that threads other than the primordial thread will also start a repl on crashes, using for example:<br>% gsi -:dar <br>(for more details see Gambit's documentation).
<br><br><br>Hope this helps and that I didn't misinterpret the code.  Personally, I don't think you will have to use mutexes if you design your program correctly.<br><br><br>Guillaume<br><br><br></div></div>