aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--cont.c16
-rw-r--r--test/ruby/test_fiber.rb17
-rw-r--r--yarvcore.c5
4 files changed, 48 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index c25a300069..3df40a85ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Thu Jun 7 03:17:24 2007 Koichi Sasada <ko1@atdot.net>
+
+ * cont.c (cont_new): add debug message.
+
+ * cont.c (cont_restore_1): copy stack information from fiber.
+
+ * cont.c (rb_fiber_s_new): fix to mark created fiber.
+
+ * test/ruby/test_fiber.rb: add some tests around Thread and Fiber.
+
+ * yarvcore.c (thread_free): fix to skip freeing stack if root fiber
+ is available.
+
Thu Jun 7 01:03:20 2007 Koichi Sasada <ko1@atdot.net>
* eval_intern.h, eval.c (ruby_init): remove POP_TAG_INIT().
diff --git a/cont.c b/cont.c
index 8c2508a094..4210ab97d5 100644
--- a/cont.c
+++ b/cont.c
@@ -111,6 +111,10 @@ cont_new(VALUE klass)
contval = Data_Make_Struct(klass, rb_context_t,
cont_mark, cont_free, cont);
+
+ GC_INFO("cont alloc: %p (klass: %s)\n", cont,
+ klass == rb_cFiber ? "Fiber": "Continuation");
+
cont->self = contval;
cont->alive = Qtrue;
@@ -169,8 +173,15 @@ cont_restore_1(rb_context_t *cont)
}
else {
/* continuation */
- MEMCPY(th->stack, cont->vm_stack, VALUE, sth->stack_size);
th->fiber = sth->fiber;
+
+ if (th->fiber) {
+ rb_context_t *fcont;
+ GetContPtr(th->fiber, fcont);
+ th->stack_size = fcont->saved_thread.stack_size;
+ th->stack = fcont->saved_thread.stack;
+ }
+ MEMCPY(th->stack, cont->vm_stack, VALUE, sth->stack_size);
}
th->cfp = sth->cfp;
@@ -369,6 +380,7 @@ static VALUE
rb_fiber_s_new(VALUE self)
{
rb_context_t *cont = cont_new(self);
+ VALUE contval = cont->self;
rb_thread_t *th = &cont->saved_thread;
/* initialize */
@@ -396,7 +408,7 @@ rb_fiber_s_new(VALUE self)
MEMCPY(&cont->jmpbuf, &th->root_jmpbuf, rb_jmpbuf_t, 1);
- return cont->self;
+ return contval;
}
static VALUE rb_fiber_yield(int argc, VALUE *args, VALUE fval);
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index 97ec09c36b..44caba4520 100644
--- a/test/ruby/test_fiber.rb
+++ b/test/ruby/test_fiber.rb
@@ -40,6 +40,23 @@ class TestFiber < Test::Unit::TestCase
)
end
+ def test_many_fibers_with_threads
+ max = 1000
+ @cnt = 0
+ (1..100).map{|ti|
+ Thread.new{
+ max.times{|i|
+ Fiber.new{
+ @cnt += 1
+ }.yield
+ }
+ }
+ }.each{|t|
+ t.join
+ }
+ assert_equal(:ok, :ok)
+ end
+
def test_error
assert_raise(ArgumentError){
Fiber.new # Fiber without block
diff --git a/yarvcore.c b/yarvcore.c
index 507a2f8c68..6c4f83294c 100644
--- a/yarvcore.c
+++ b/yarvcore.c
@@ -226,7 +226,10 @@ thread_free(void *ptr)
if (ptr) {
th = ptr;
- FREE_UNLESS_NULL(th->stack);
+
+ if (!th->root_fiber) {
+ FREE_UNLESS_NULL(th->stack);
+ }
if (th->local_storage) {
st_free_table(th->local_storage);