Hi!
I'm trying to figure out a parallel implementation of for-each (I'm going
to use it for spawning system processes mostly).
Anyway, the problem is like this: If I use any kind of recursion inside the
thread created in the (new-thread) proc, I get this error:
*** ERROR IN for-each -- Uncaught exception: #<type-exception #31>
(thread-join! '#<thread #32>)
As soon as I remove the call to (recur) (it would happen also with letrec
for instance), it works as expected. I really don't understand how internal
recursion in the thread could yield this error.
Thanks for your help
(define (parallel-for-each f l #!key (max-thread-number 2))
(let* ((pending-jobs l)
(jobs-mutex (make-mutex))
(available-jobs? (lambda ()
(mutex-lock! jobs-mutex)
(let ((more? (not (null? pending-jobs))))
(mutex-unlock! jobs-mutex)
more?)))
(next-element (lambda ()
(mutex-lock! jobs-mutex)
(let ((next (car pending-jobs)))
(set! pending-jobs (cdr pending-jobs))
(mutex-unlock! jobs-mutex)
next)))
(results '())
(results-mutex (make-mutex))
(add-to-results! (lambda (r)
(mutex-lock! results-mutex)
(set! results (cons r results))
(mutex-unlock! results-mutex))))
(let ((new-thread
(lambda ()
(thread-start! (make-thread
(lambda ()
(let recur ()
(add-to-results! (f (next-element)))
(if (available-jobs?)
(recur)
(thread-yield!)))))))))
(let do-times ((n 0)
(thread-pool '()))
(if (< n max-thread-number)
(do-times (++ n)
(cons (new-thread) thread-pool))
(for-each thread-join! thread-pool))))
(reverse results)))