guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: about coroutines


From: Michele Bini
Subject: Re: about coroutines
Date: Tue, 20 Nov 2001 04:03:53 +0100

>>>>> "Marius" == Marius Vollmer <address@hidden> writes:
  Marius> Keith Wright <address@hidden> writes:
  >> *bug2 - obscure memory leak in certain uses of call/cc

  Marius> Confirmed as well.  This version of coroutines works:

  ...

  Marius> I don't know why, yet.

I think that there is a problem with storing continuations for
coroutines in lexically scoped (non-global) variables or passing them
as arguments or as return values, since when you create a continuation
to save the current execution point for a coroutine there is the risk
that a reference to the continuation for a previous execution point
still exists (in the stack); when this happens a chain of unfreeable
continuations will accumulate over time.  It is even is even possible
to fool MIT Scheme this way, under some circumstances.

I think using dynamic variables to hold the continuations avoids this
problem, since they do not reside in the stack that gets copied when a
new continuation is created.

;; now working, continuations are not passed anymore as arguments or
;; return values.
(define (coroutines-test)
  (define call/cc call-with-current-continuation)
  (define (coroutine-a yield)
    (define l (string->list "Hello, world!\n"))
    ;; print hello world
    (let loop ()
      (for-each
       (lambda (a)
         (write-char a)
         (yield)) l)
      (loop)))
  (define (coroutine-b yield)
    (let loop ((a 1))
      (write a)
      (yield)
      (loop (- 1 a))))
  (define (run-coroutines . procs)
    (define (next)
      (let ((a (car procs)))
        (set! procs (cdr procs))
        ((a yield))))
    (define (yield)
      (call/cc
       (lambda (new)
         (set! procs (append procs (list new)))
         (next))))
    (next))
  (run-coroutines coroutine-a coroutine-b))

                Michele



reply via email to

[Prev in Thread] Current Thread [Next in Thread]