Project

General

Profile

Feature #3187 ยป fiber_stacksize.patch

nagachika (Tomoyuki Chikanaga), 10/19/2011 11:26 PM

View differences:

cont.c
static VALUE rb_cContinuation;
static VALUE rb_cFiber;
static VALUE rb_eFiberError;
static ID id_default_vm_stacksize;
static ID id_vm_stacksize;
#define GetContPtr(obj, ptr) \
TypedData_Get_Struct((obj), rb_context_t, &cont_data_type, (ptr))
......
}
static VALUE
fiber_init(VALUE fibval, VALUE proc)
fiber_init(VALUE fibval, VALUE proc, VALUE vm_stacksize)
{
rb_fiber_t *fib = fiber_t_alloc(fibval);
rb_context_t *cont = &fib->cont;
......
fiber_link_join(fib);
th->stack_size = FIBER_VM_STACK_SIZE;
th->stack_size = NUM2ULONG(vm_stacksize);
th->stack = ALLOC_N(VALUE, th->stack_size);
th->cfp = (void *)(th->stack + th->stack_size);
......
}
/* :nodoc: */
static VALUE rb_fiber_s_get_default_vm_stacksize(VALUE);
static VALUE
rb_fiber_init(VALUE fibval)
rb_fiber_init(int argc, VALUE *argv, VALUE fibval)
{
return fiber_init(fibval, rb_block_proc());
VALUE opt;
VALUE stacksize;
rb_scan_args(argc, argv, "0:", &opt);
if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, ID2SYM(id_vm_stacksize))))
stacksize = rb_fiber_s_get_default_vm_stacksize(rb_obj_class(fibval));
else
stacksize = rb_to_int(rb_hash_aref(opt, ID2SYM(id_vm_stacksize)));
if (NUM2ULONG(stacksize) < (unsigned long)FIBER_VM_STACK_SIZE)
rb_raise(rb_eArgError,
"Fiber vm stacksize must equal or bigger than %d",
FIBER_VM_STACK_SIZE);
return fiber_init(fibval, rb_block_proc(), stacksize);
}
VALUE
rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj)
{
return fiber_init(fiber_alloc(rb_cFiber), rb_proc_new(func, obj));
return fiber_init(fiber_alloc(rb_cFiber), rb_proc_new(func, obj),
rb_fiber_s_get_default_vm_stacksize(rb_cFiber));
}
static VALUE
......
/*
* call-seq:
* fiber.vm_stacksize() -> integer
*
* Returns VM stack size of the fiber.
*/
static VALUE
rb_fiber_vm_stacksize(VALUE fibval)
{
rb_fiber_t *fib;
GetFiberPtr(fibval, fib);
return ULONG2NUM(fib->cont.saved_thread.stack_size);
}
/*
* call-seq:
* Fiber.yield(args, ...) -> obj
*
* Yields control back to the context that resumed the fiber, passing
......
return rb_fiber_current();
}
/*
* call-seq:
* Fiber.default_vm_stacksize() -> integer
*
* Returns the default VM stack size. Note that this is a maximum number of
* object in VM stack, not a size in byte.
*/
static VALUE
rb_fiber_s_get_default_vm_stacksize(VALUE klass)
{
return rb_ivar_get(klass, id_default_vm_stacksize);
}
/*
* call-seq:
* Fiber.default_vm_stacksize = num -> integer
*
* Sets the default VM stack size.
* Returns +num+.
* Raises TypeError if +num+ is not Numeric and
* raises ArgumentError if num is less than FIBER_VM_STACK_SIZE.
*/
static VALUE
rb_fiber_s_set_default_vm_stacksize(VALUE klass, VALUE num)
{
num = rb_to_int(num);
if (NUM2ULONG(num) < (unsigned long)FIBER_VM_STACK_SIZE)
rb_raise(rb_eArgError,
"Fiber default_vm_stacksize must equal or bigger than %d",
FIBER_VM_STACK_SIZE);
rb_ivar_set(klass, id_default_vm_stacksize, num);
return num;
}
/*
* Document-class: FiberError
......
SET_MACHINE_STACK_END(&th->machine_stack_end);
#endif
id_default_vm_stacksize = rb_intern("default_vm_stacksize");
id_vm_stacksize = rb_intern("vm_stacksize");
rb_cFiber = rb_define_class("Fiber", rb_cObject);
rb_define_alloc_func(rb_cFiber, fiber_alloc);
rb_eFiberError = rb_define_class("FiberError", rb_eStandardError);
rb_ivar_set(rb_cFiber, id_default_vm_stacksize,
INT2NUM(FIBER_VM_STACK_SIZE));
rb_define_singleton_method(rb_cFiber, "default_vm_stacksize",
rb_fiber_s_get_default_vm_stacksize, 0);
rb_define_singleton_method(rb_cFiber, "default_vm_stacksize=",
rb_fiber_s_set_default_vm_stacksize, 1);
rb_define_singleton_method(rb_cFiber, "yield", rb_fiber_s_yield, -1);
rb_define_method(rb_cFiber, "initialize", rb_fiber_init, 0);
rb_define_method(rb_cFiber, "initialize", rb_fiber_init, -1);
rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1);
rb_define_method(rb_cFiber, "vm_stacksize", rb_fiber_vm_stacksize, 0);
}
#if defined __GNUC__ && __GNUC__ >= 4
test/ruby/test_fiber.rb
end
assert_equal("Can't call on top of Fiber or Thread", error.message, bug5083)
end
def test_default_vm_stacksize
begin
default_vm_stacksize = Fiber.default_vm_stacksize
assert_equal(4*1024, default_vm_stacksize)
Fiber.default_vm_stacksize = 8 * 1024
assert_equal(8*1024, Fiber.default_vm_stacksize)
assert_raise(TypeError) do
Fiber.default_vm_stacksize = Object.new
end
assert_raise(ArgumentError) do
Fiber.default_vm_stacksize = 0
end
ensure
if default_vm_stacksize
Fiber.default_vm_stacksize = default_vm_stacksize
end
end
end
def test_vm_stacksize
fib = Fiber.new { }
assert_equal(Fiber.default_vm_stacksize, fib.vm_stacksize)
fib = Fiber.new(:vm_stacksize => 8*1024) {}
assert_equal(8*1024, fib.vm_stacksize)
assert_raise(TypeError) do
Fiber.new(:vm_stacksize => Object.new) {}
end
assert_raise(ArgumentError) do
Fiber.new(:vm_stacksize => 2 * 1024) {}
end
end
end
    (1-1/1)