Feature #3187 ยป fiber_stacksize.patch
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
|
||