C
Christoffer Lernö
Hello continuation gurus and others!
I still don't understand why I keep having so many non-gc:ed
continuations in my code.
Below is some sample code where each coroutine seem intent on hogging
3 continuations each. I don't see why I shouldn't be able to cut that
number down to a single continuation each.
Cutting and pasting the code below and running it should give a
printout of
continuations-------------------------------------
wait<3>
wait<2>
exit<b>
exit<a>
init
init
Currently using: 6 continuations
--------------------------------------------------
I would prefer to only keep the first 2, but I can't seem to make
that happen. *sigh*
/Christoffer
8<----------------------------- ugly test code starts here
-----------------------------------
class StateLess
end
class Continuation
attr_accessor :tag
def to_s
"#{tag}"
end
end
class TestStateLess < StateLess
attr_reader :value
def initialize
@value = ""
callcc do |continuation|
continuation.tag = "init"
@continuation = continuation
return
end
run
end
def run(*arg)
@value += "retry;" while wait(1) !~ /password/
@value += "passed;"
wait(2)
@value +="passed2;"
wait(3)
end
def wait(position)
@value += "waiting_at_#{position};"
@continuation = nil
callcc do |continuation|
continuation.tag = "wait<#{position}>"
@continuation = continuation
@exit.call
end
end
def go(*arg)
callcc do |exit|
exit.tag = "exit<#{arg}>"
@exit = exit
@continuation.call(*arg)
end
@exit = nil
end
end
include ObjectSpace
def count_cc
garbage_collect
i = 0
puts "continuations-------------------------------------"
ObjectSpace.each_object(Continuation) {|x| puts x; i += 1 }
puts "Currently using: " + i.to_s + " continuations"
puts "--------------------------------------------------"
end
require 'test/unit'
class Tests < Test::Unit::TestCase
def test_twin
a = TestStateLess.new
b = TestStateLess.new
assert_equal("", a.value)
a.go('a')
assert_equal("waiting_at_1;", a.value)
b.go('b')
a.go("passvoid")
assert_equal("waiting_at_1;retry;waiting_at_1;", a.value)
b.go("password")
assert_equal("waiting_at_1;passed;waiting_at_2;", b.value)
a.go("password")
assert_equal
("waiting_at_1;retry;waiting_at_1;passed;waiting_at_2;", a.value)
b.go("spam")
assert_equal
("waiting_at_1;passed;waiting_at_2;passed2;waiting_at_3;", b.value)
count_cc
end
end
I still don't understand why I keep having so many non-gc:ed
continuations in my code.
Below is some sample code where each coroutine seem intent on hogging
3 continuations each. I don't see why I shouldn't be able to cut that
number down to a single continuation each.
Cutting and pasting the code below and running it should give a
printout of
continuations-------------------------------------
wait<3>
wait<2>
exit<b>
exit<a>
init
init
Currently using: 6 continuations
--------------------------------------------------
I would prefer to only keep the first 2, but I can't seem to make
that happen. *sigh*
/Christoffer
8<----------------------------- ugly test code starts here
-----------------------------------
class StateLess
end
class Continuation
attr_accessor :tag
def to_s
"#{tag}"
end
end
class TestStateLess < StateLess
attr_reader :value
def initialize
@value = ""
callcc do |continuation|
continuation.tag = "init"
@continuation = continuation
return
end
run
end
def run(*arg)
@value += "retry;" while wait(1) !~ /password/
@value += "passed;"
wait(2)
@value +="passed2;"
wait(3)
end
def wait(position)
@value += "waiting_at_#{position};"
@continuation = nil
callcc do |continuation|
continuation.tag = "wait<#{position}>"
@continuation = continuation
@exit.call
end
end
def go(*arg)
callcc do |exit|
exit.tag = "exit<#{arg}>"
@exit = exit
@continuation.call(*arg)
end
@exit = nil
end
end
include ObjectSpace
def count_cc
garbage_collect
i = 0
puts "continuations-------------------------------------"
ObjectSpace.each_object(Continuation) {|x| puts x; i += 1 }
puts "Currently using: " + i.to_s + " continuations"
puts "--------------------------------------------------"
end
require 'test/unit'
class Tests < Test::Unit::TestCase
def test_twin
a = TestStateLess.new
b = TestStateLess.new
assert_equal("", a.value)
a.go('a')
assert_equal("waiting_at_1;", a.value)
b.go('b')
a.go("passvoid")
assert_equal("waiting_at_1;retry;waiting_at_1;", a.value)
b.go("password")
assert_equal("waiting_at_1;passed;waiting_at_2;", b.value)
a.go("password")
assert_equal
("waiting_at_1;retry;waiting_at_1;passed;waiting_at_2;", a.value)
b.go("spam")
assert_equal
("waiting_at_1;passed;waiting_at_2;passed2;waiting_at_3;", b.value)
count_cc
end
end