* cont.c: add rb_context_t#type.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13843 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0303c1d42b
commit
9f6de20f58
@ -1,3 +1,7 @@
|
|||||||
|
Fri Nov 9 10:10:21 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* cont.c: add rb_context_t#type.
|
||||||
|
|
||||||
Fri Nov 9 10:05:54 2007 Koichi Sasada <ko1@atdot.net>
|
Fri Nov 9 10:05:54 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* ruby.c (set_arg0): fix breaking environ bugs.
|
* ruby.c (set_arg0): fix breaking environ bugs.
|
||||||
|
61
cont.c
61
cont.c
@ -15,6 +15,12 @@
|
|||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
#include "eval_intern.h"
|
#include "eval_intern.h"
|
||||||
|
|
||||||
|
enum context_type {
|
||||||
|
CONTINUATION_CONTEXT = 0,
|
||||||
|
FIBER_CONTEXT = 1,
|
||||||
|
ROOT_FIBER_CONTEXT = 2,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct rb_context_struct {
|
typedef struct rb_context_struct {
|
||||||
VALUE self;
|
VALUE self;
|
||||||
VALUE value;
|
VALUE value;
|
||||||
@ -29,9 +35,9 @@ typedef struct rb_context_struct {
|
|||||||
rb_thread_t saved_thread;
|
rb_thread_t saved_thread;
|
||||||
rb_jmpbuf_t jmpbuf;
|
rb_jmpbuf_t jmpbuf;
|
||||||
int machine_stack_size;
|
int machine_stack_size;
|
||||||
/* for cont */
|
|
||||||
VALUE prev;
|
VALUE prev;
|
||||||
int alive;
|
int alive;
|
||||||
|
enum context_type type;
|
||||||
} rb_context_t;
|
} rb_context_t;
|
||||||
|
|
||||||
static VALUE rb_cContinuation;
|
static VALUE rb_cContinuation;
|
||||||
@ -86,10 +92,11 @@ cont_free(void *ptr)
|
|||||||
RUBY_FREE_UNLESS_NULL(cont->machine_register_stack);
|
RUBY_FREE_UNLESS_NULL(cont->machine_register_stack);
|
||||||
#endif
|
#endif
|
||||||
RUBY_FREE_UNLESS_NULL(cont->vm_stack);
|
RUBY_FREE_UNLESS_NULL(cont->vm_stack);
|
||||||
if (cont->vm_stack && cont->saved_thread.local_storage) {
|
|
||||||
/* fiber */
|
if (cont->type == FIBER_CONTEXT) {
|
||||||
st_free_table(cont->saved_thread.local_storage);
|
st_free_table(cont->saved_thread.local_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
ruby_xfree(ptr);
|
ruby_xfree(ptr);
|
||||||
}
|
}
|
||||||
RUBY_FREE_LEAVE("cont");
|
RUBY_FREE_LEAVE("cont");
|
||||||
@ -205,14 +212,7 @@ cont_restore_1(rb_context_t *cont)
|
|||||||
rb_thread_t *th = GET_THREAD(), *sth = &cont->saved_thread;
|
rb_thread_t *th = GET_THREAD(), *sth = &cont->saved_thread;
|
||||||
|
|
||||||
/* restore thread context */
|
/* restore thread context */
|
||||||
if (sth->stack) {
|
if (cont->type == CONTINUATION_CONTEXT) {
|
||||||
/* fiber */
|
|
||||||
th->stack = sth->stack;
|
|
||||||
th->stack_size = sth->stack_size;
|
|
||||||
th->local_storage = sth->local_storage;
|
|
||||||
th->fiber = cont->self;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* continuation */
|
/* continuation */
|
||||||
VALUE fib;
|
VALUE fib;
|
||||||
|
|
||||||
@ -227,6 +227,13 @@ cont_restore_1(rb_context_t *cont)
|
|||||||
}
|
}
|
||||||
MEMCPY(th->stack, cont->vm_stack, VALUE, sth->stack_size);
|
MEMCPY(th->stack, cont->vm_stack, VALUE, sth->stack_size);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* fiber */
|
||||||
|
th->stack = sth->stack;
|
||||||
|
th->stack_size = sth->stack_size;
|
||||||
|
th->local_storage = sth->local_storage;
|
||||||
|
th->fiber = cont->self;
|
||||||
|
}
|
||||||
|
|
||||||
th->cfp = sth->cfp;
|
th->cfp = sth->cfp;
|
||||||
th->safe_level = sth->safe_level;
|
th->safe_level = sth->safe_level;
|
||||||
@ -476,15 +483,25 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
|
|||||||
|
|
||||||
#define FIBER_VM_STACK_SIZE (4 * 1024)
|
#define FIBER_VM_STACK_SIZE (4 * 1024)
|
||||||
|
|
||||||
static VALUE
|
static rb_context_t *
|
||||||
fiber_alloc(VALUE klass, VALUE proc)
|
fiber_alloc(VALUE klass)
|
||||||
{
|
{
|
||||||
rb_context_t *cont = cont_new(klass);
|
rb_context_t *cont = cont_new(klass);
|
||||||
|
|
||||||
|
cont->type = FIBER_CONTEXT;
|
||||||
|
cont->prev = Qnil;
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
fiber_new(VALUE klass, VALUE proc)
|
||||||
|
{
|
||||||
|
rb_context_t *cont = fiber_alloc(klass);
|
||||||
VALUE contval = cont->self;
|
VALUE contval = cont->self;
|
||||||
rb_thread_t *th = &cont->saved_thread;
|
rb_thread_t *th = &cont->saved_thread;
|
||||||
|
|
||||||
/* initialize */
|
/* initialize */
|
||||||
cont->prev = Qnil;
|
|
||||||
cont->vm_stack = 0;
|
cont->vm_stack = 0;
|
||||||
|
|
||||||
th->stack = 0;
|
th->stack = 0;
|
||||||
@ -517,13 +534,13 @@ fiber_alloc(VALUE klass, VALUE proc)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj)
|
rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj)
|
||||||
{
|
{
|
||||||
return fiber_alloc(rb_cFiber, rb_proc_new(func, obj));
|
return fiber_new(rb_cFiber, rb_proc_new(func, obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_fiber_s_new(VALUE self)
|
rb_fiber_s_new(VALUE self)
|
||||||
{
|
{
|
||||||
return fiber_alloc(self, rb_block_proc());
|
return fiber_new(self, rb_block_proc());
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -604,15 +621,15 @@ rb_fiber_current()
|
|||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
if (th->fiber == 0) {
|
if (th->fiber == 0) {
|
||||||
/* save root */
|
/* save root */
|
||||||
rb_context_t *cont = cont_new(rb_cFiber);
|
rb_context_t *cont = fiber_alloc(rb_cFiber);
|
||||||
cont->prev = Qnil;
|
cont->type = ROOT_FIBER_CONTEXT;
|
||||||
th->root_fiber = th->fiber = cont->self;
|
th->root_fiber = th->fiber = cont->self;
|
||||||
}
|
}
|
||||||
return th->fiber;
|
return th->fiber;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
cont_store(rb_context_t *next_cont)
|
fiber_store(rb_context_t *next_cont)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
rb_context_t *cont;
|
rb_context_t *cont;
|
||||||
@ -623,8 +640,8 @@ cont_store(rb_context_t *next_cont)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* create current fiber */
|
/* create current fiber */
|
||||||
cont = cont_new(rb_cFiber); /* no need to allocate vm stack */
|
cont = fiber_alloc(rb_cFiber); /* no need to allocate vm stack */
|
||||||
cont->prev = Qnil;
|
cont->type = ROOT_FIBER_CONTEXT;
|
||||||
th->root_fiber = th->fiber = cont->self;
|
th->root_fiber = th->fiber = cont->self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,7 +682,7 @@ fiber_switch(VALUE fib, int argc, VALUE *argv, int is_resume)
|
|||||||
|
|
||||||
cont->value = make_passing_arg(argc, argv);
|
cont->value = make_passing_arg(argc, argv);
|
||||||
|
|
||||||
if ((value = cont_store(cont)) == Qundef) {
|
if ((value = fiber_store(cont)) == Qundef) {
|
||||||
cont_restore_0(cont, &value);
|
cont_restore_0(cont, &value);
|
||||||
rb_bug("rb_fiber_resume: unreachable");
|
rb_bug("rb_fiber_resume: unreachable");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user