[plt-scheme] Continuations memory accumulation problem

From: Ciprian Dorin, Craciun (ciprian.craciun at gmail.com)
Date: Sun Mar 14 16:47:22 EDT 2010

    Hello all!

    I have a small problem with continuations, more exactly memory
builds up and I don't seem to find the problem... (This is the first
time I seriously play with continuations so if I'm doing something
really stupid please bare with me...) :)

    So maybe someone has 5 minutes to look at my code... :)

    What I'm trying to do: re-implement GnuRobots for PLT Scheme.
(Actually it's done but I have this issue with the continuations.)

    So how I've implemented it (the code presented is extracted from
my real code, but this snippet actually works on itself if one wants
to try it):
    * there is a timer that calls the `step-robots!` function; (here
the `step-robots!` just recurses with no timeout;)
    * each robot has a behaviour (in this case `do-robot!`) function
which should after each robot-operation yield control back to the
framework; (this way the robot behaviour can be very easily
implemented as a tail recursive function);
    * in order to obtain this, I first capture a continuation just
before calling the behaviour function (in this case `do-robot!`);
    * then at each step I capture the current continuation, dive in in
the last saved continuation from `do-robot!`;
    * when the `do-robot!` function calls `exit-robot!` (this is the
yield function) I just save the current continuation and fall-back to
the old one (which is just inside the stepping loop);

    But I'm certainly doing something wrong as memory adds up and is
freed only after a robot dies (meaning it exits the `do-robot!`) (and
I manually call `(collect-garbage)` inside the `step-robots!`).
Unfortunately I don't seem to find the bug...

    Thanks for your time!
    Ciprian.

    P.S.: I intend to share the source code under GPL... :)

    P.P.S.: I've also attached the file because Gmail tends to wrap
lines badly...


~~~~
#lang scheme


(define-struct robot
	(continuation continuation-tag) #:mutable)

(define (create-robot)
	(make-robot (void) (make-continuation-prompt-tag)))


(define (step-robots! robots)
	
	(for ((robot (in-list robots)))
		(cond
			((void? (robot-continuation robot))
				(start-robot! robot))
			((continuation? (robot-continuation robot))
				(enter-robot! robot))
			(else
				(display 'died)
				(newline))))
	
	(step-robots! robots))

(define (start-robot! robot)
	
	(define continuation-tag (robot-continuation-tag robot))
	
	(set-robot-continuation! robot #f)
	(set-robot-continuation! robot
		(call-with-continuation-prompt
			(lambda ()
				(call-with-current-continuation
					(lambda (new-framework-continuation)
						(set-robot-continuation! robot new-framework-continuation)
						(exit-robot! robot)
						(do-robot! robot)
						(done-robot! robot))
					continuation-tag))
			continuation-tag))
	
	(void))

(define (enter-robot! robot)
	
	(define continuation-tag (robot-continuation-tag robot))
	(define old-behaviour-continuation (robot-continuation robot))
	
	(set-robot-continuation! robot #f)
	(set-robot-continuation! robot
		(call-with-continuation-prompt
			(lambda ()
				(call-with-current-continuation
					old-behaviour-continuation
					continuation-tag))
			continuation-tag))
	
	(void))

(define (exit-robot! robot)
	
	(define continuation-tag (robot-continuation-tag robot))
	(define old-framework-continuation (robot-continuation robot))
	
	(set-robot-continuation! robot #f)
	(set-robot-continuation! robot
		(call-with-current-continuation
			old-framework-continuation
			continuation-tag))
	
	(void))

(define (done-robot! robot)
	
	(define old-framework-continuation (robot-continuation robot))
	
	(set-robot-continuation! robot #f)
	
	(old-framework-continuation #f))

(define (do-robot! robot (steps 100000))
	(unless (zero? steps)
		(exit-robot! robot)
		(do-robot! robot (- steps 1))))


(define robots (list (create-robot) (create-robot) (create-robot)))

(step-robots! robots)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cont-test.ss
Type: application/octet-stream
Size: 2023 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20100314/54cc71d6/attachment.obj>

Posted on the users mailing list.