srfi-18 horse racing

View: New views
1 Messages — Rating Filter:   Alert me  

srfi-18 horse racing

by Tristan Colgate-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi All,

  I've been experimenting with guile-1.9 srfi-18 support. I'm trying
to implement a race between threads. I've written a macro that take a
routine and a list of args, starts a thread for each arg and runs the
routine with that argument. The result  returned should be the return
result of the first thread to return. I was originally using some of
guile other thread primitives (monitor in particular), but have
stripped those out in order to try testing against other schemes.

  Chicken currently gives the "correct" result, but that uses
cooperative threading. Guile launches threads, I can see them with a
ps -efL,  but they never seem to start (even after the thread-start!).

  The code is as follows....

(require-extension (srfi 18))

(define-syntax race-each
  (syntax-rules ()
  ((_ func parargs)
   (let* ((result #f)
          (result-ready (make-condition-variable))
          (junktex (make-mutex))
          (junk    (mutex-lock! junktex))
          (resulttex (make-mutex))
          (dotask (lambda(arg)
                     (let ((thisresult (func arg)))
                       (with-exception-handler
                         (lambda(ev)
                           (thread-terminate! (current-thread)))
                         (lambda() (mutex-lock! resulttex)))
                       (set! result thisresult)
                       (condition-variable-signal! result-ready)
                       (thread-terminate! (current-thread)))))
          (threads (map (lambda(x)
                          (thread-start! (make-thread (lambda()
                                                         (dotask
x))))) parargs)))
      (mutex-unlock! junktex result-ready)
      (map (lambda(old-thread) (thread-terminate! old-thread)) threads)
      result))))

(display
  (race-each
    (lambda(value)
      (format #t "In thread~%")
      (thread-sleep! (seconds->time (+ (time->seconds (current-time)) value)))
      value)
    '(3 5 8 9 2)))



--
Tristan Colgate-McFarlane
----
  "You can get all your daily vitamins from 52 pints of guiness, and a
glass of milk"