Feature #2126
closedruby_init_stack() - add ability to specify or query max_stack_size
Description
=begin
Hello,
== Background ==
I am embedding Ruby 1.9 inside a callback function of a C program (a Verilog
simulator, to be precise):
-
The first time when the callback function is called, I will initialize Ruby
and create a Fiber (to run some Ruby code). -
For all subsequent times when the callback function is called, I will resume
the Fiber. The Fiber will then run some Ruby code and return control back to
the callback function, using Fiber.yield(). -
This process repeats until the callback function is no longer called by the C
program.
== Problem ==
Each time when the callback function is called, the C program's current stack
pointer is different: sometimes it descends below Ruby's stack start
addresss!
For this reason, it is not safe to use the default RUBY_INIT_STACK macro (which
assumes that the C program's current stack pointer never descends below Ruby's
stack start addresss).
== Request for Solution ==
To solve the problem, I need one of the following features:
-
Add a max_stack_size parameter to ruby_init_stack():
void ruby_init_stack(VALUE* stack_start, size_t max_stack_size);
And also add a function to return Ruby's preferred stack size:
size_t ruby_preferred_stack_size();
This way, I can provide a custom stack to Ruby:
size_t stack_size = ruby_preferred_stack_size();
VALUE* stack_end = malloc(sizeof(VALUE) * stack_size);
VALUE* stack_start = stack_end + stack_size;ruby_init_stack(stack_start, stack_size);
-
Make ruby_init_stack() return the maximum stack size it has chosen:
size_t ruby_init_stack(VALUE* stack_start);
This way, I can grow my custom stack to fit Ruby's needs:
VALUE* stack_end = malloc(sizeof(VALUE));
size_t stack_size = ruby_init_stack(stack_end);
VALUE* new_stack_end = realloc(stack_end, stack_size); -
Add a RUBY_AUTO_STACK macro which makes Ruby allocate its own stack on the
heap using malloc(). I would call this macro instead of RUBY_INIT_STACK.
Thanks for your consideration.
=end
Updated by sunaku (Suraj Kurapati) over 15 years ago
=begin
Whoops, I assumed that the native machine's stack direction grows from
high to low. That is not protable, so here is my corrected request:
Add a max_stack_size parameter to ruby_init_stack():
void ruby_init_stack(
VALUE* stack_start,
size_t max_stack_size,
bool stack_descends /* stack grows from high to low? */
);
Add a function to return Ruby's preferred stack size:
size_t ruby_stack_size_preference();
Add a function to return Ruby's preferred stack direction:
bool ruby_stack_descends_p(); /* stack grows from high to low? */
This way, I can provide a custom stack to Ruby:
size_t stack_size = ruby_stack_size_preference();
bool stack_descends = ruby_stack_descends_p();
VALUE* stack_start = malloc(stack_size);
if (stack_descends) {
stack_start += stack_size;
}
ruby_init_stack(stack_start, stack_size);
If you wish to minimize the number of new functions added to the Ruby
C API, then perhaps you could add a RUBY_INIT_STACK_ON_HEAP macro
which makes Ruby do (internally) everything in the code shown above.
Thanks for your consideration.
=end
Updated by sunaku (Suraj Kurapati) over 15 years ago
=begin
Sigh, yet another mistake. Below is my corrected request. Sorry for
the trouble.
Add a max_stack_size parameter to ruby_init_stack():
void ruby_init_stack(VALUE* stack_start, size_t max_stack_size);
Add a function to return Ruby's preferred stack size:
size_t ruby_stack_size_preference();
Add a function to return Ruby's preferred stack direction:
bool ruby_stack_descends_p(); /* stack grows from high to low? */
This way, I can provide a custom stack to Ruby:
size_t stack_size = ruby_stack_size_preference();
bool stack_descends = ruby_stack_descends_p();
VALUE* stack_start = malloc(stack_size);
if (stack_descends) {
stack_start += stack_size;
}
ruby_init_stack(stack_start, stack_size);
If you wish to minimize the number of new functions added to the Ruby
C API, then perhaps you could add a RUBY_INIT_STACK_ON_HEAP macro
which makes Ruby do (internally) everything in the code shown above.
Thanks for your consideration.
=end
Updated by matz (Yukihiro Matsumoto) about 15 years ago
=begin
Hi,
In message "Re: [ruby-core:25674] [Feature #2126] ruby_init_stack() - add ability to specify or query max_stack_size"
on Mon, 21 Sep 2009 02:42:14 +0900, Suraj Kurapati redmine@ruby-lang.org writes:
| This way, I can provide a custom stack to Ruby:
|
| size_t stack_size = ruby_stack_size_preference();
| bool stack_descends = ruby_stack_descends_p();
|
| VALUE* stack_start = malloc(stack_size);
|
| if (stack_descends) {
| stack_start += stack_size;
| }
|
| ruby_init_stack(stack_start, stack_size);
As far as I know, there's no portable way to switch machine stack to
pre-allocated heap region. I'm happy to be proven wrong.
matz.
=end
Updated by sunaku (Suraj Kurapati) about 15 years ago
=begin
Hi Matz,
Please take a look at issue #2258 (from note 16 onwards) which
provides a practical example of the need for a stack-informing
function in the Ruby C API.
That example uses UNIX System V contexts to switch the
machine stack to a pre-allocated heap region. Other1, more
cross-platform libraries, such as libpcl (portable coroutine
library), are also capable of doing this.
For your convenience, I will create a variation of that
example which uses libpcl and other libraries to demonstrate
the feasibility of this request.
Thanks for your consideration.
=end
Updated by sunaku (Suraj Kurapati) about 15 years ago
Updated by sunaku (Suraj Kurapati) about 15 years ago
Updated by nobu (Nobuyoshi Nakada) about 15 years ago
- Status changed from Open to Closed
=begin
This issue was solved with changeset r25842.
Suraj, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end