yarv-diff:118
From: ko1 atdot.net
Date: 5 Oct 2005 00:11:36 -0000
Subject: [yarv-diff:118] r274 - in trunk: . benchmark
Author: ko1
Date: 2005-10-05 09:11:35 +0900 (Wed, 05 Oct 2005)
New Revision: 274
Modified:
trunk/ChangeLog
trunk/benchmark/bmx_temp.rb
trunk/eval.c
trunk/eval_intern.h
trunk/eval_jump.h
trunk/eval_thread.c
trunk/inits.c
trunk/test.rb
trunk/thread.c
trunk/vm.c
trunk/yarvcore.c
trunk/yarvcore.h
Log:
* eval.c, eval_intern.h, vm.c, eval_jump.h, yarvcore.h :
re-define PUSH/POP/EXEC/JUMP_TAG to use thread local tag
* inits.c, yarvcore.c : fix boostrap
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/ChangeLog 2005-10-05 00:11:35 UTC (rev 274)
@@ -5,6 +5,14 @@
#
+2005-10-05(Wed) 09:08:11 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * eval.c, eval_intern.h, vm.c, eval_jump.h, yarvcore.h :
+ re-define PUSH/POP/EXEC/JUMP_TAG to use thread local tag
+
+ * inits.c, yarvcore.c : fix boostrap
+
+
2005-10-03(Mon) 22:28:24 +0900 Koichi Sasada <ko1 atdot.net>
* compile.c : fix NODE_COLON2 bugs
Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/benchmark/bmx_temp.rb 2005-10-05 00:11:35 UTC (rev 274)
@@ -1,14 +1,7 @@
-i = 0
-def m
-end
-class C
- def m
-
- end
-end
+Array.new(100000000).each{}
+__END__
-o = C.new
-while i < 1000000
- i+=1
- o.m
-end
+10000000.times{
+}
+
+
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/eval.c 2005-10-05 00:11:35 UTC (rev 274)
@@ -19,7 +19,6 @@
struct RVarmap *ruby_dyna_vars = 0;
struct FRAME *ruby_frame = 0;
-struct tag *ruby_prot_tag;
VALUE rb_cProc;
VALUE rb_cBinding;
@@ -125,46 +124,48 @@
void
ruby_init()
{
- static int initialized = 0;
- static struct FRAME frame;
- int state;
+ static int initialized = 0;
+ int state;
- if (initialized)
- return;
- initialized = 1;
+ if (initialized)
+ return;
+ initialized = 1;
#ifdef HAVE_NATIVETHREAD
- ruby_thid = NATIVETHREAD_CURRENT();
+ ruby_thid = NATIVETHREAD_CURRENT();
#endif
#ifdef __MACOS__
- rb_origenviron = 0;
+ rb_origenviron = 0;
#else
- rb_origenviron = environ;
+ rb_origenviron = environ;
#endif
+
+ Init_yarv();
+ Init_stack((void*)&state);
+ Init_heap();
- Init_stack((void*)&state);
- Init_heap();
-
/* default visibility is private at toplevel */
- SCOPE_SET(SCOPE_PRIVATE);
+ SCOPE_SET(SCOPE_PRIVATE);
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- rb_call_inits();
+ PUSH_TAG(PROT_NONE);
+ if ((state = EXEC_TAG()) == 0) {
+ rb_call_inits();
+
#ifdef __MACOS__
- _macruby_init();
+ _macruby_init();
#elif defined(__VMS)
- _vmsruby_init();
+ _vmsruby_init();
#endif
- ruby_prog_init();
- ALLOW_INTS;
- }
- POP_TAG();
- if (state) {
- error_print();
- exit(EXIT_FAILURE);
- }
- ruby_running = 1;
+
+ ruby_prog_init();
+ ALLOW_INTS;
+ }
+ POP_TAG();
+ if (state) {
+ error_print();
+ exit(EXIT_FAILURE);
+ }
+ ruby_running = 1;
}
int ruby_in_eval;
@@ -931,9 +932,6 @@
if (tag != TAG_FATAL) {
// EXEC_EVENT_HOOK(RUBY_EVENT_RAISE ...)
}
- if (!prot_tag) {
- error_print();
- }
thread_reset_raised();
JUMP_TAG(tag);
}
@@ -1243,13 +1241,13 @@
int state;
volatile VALUE retval = Qnil;
NODE *node = NEW_IFUNC(bl_proc, data2);
+ yarv_thread_t *th = GET_THREAD();
- PUSH_TAG(PROT_LOOP);
- state = EXEC_TAG();
+ TH_PUSH_TAG(th);
+ state = TH_EXEC_TAG();
if (state == 0) {
iter_retry:
{
- yarv_thread_t *th = GET_THREAD();
yarv_block_t *blockptr = GET_BLOCK_PTR_IN_CFP(th->cfp);
blockptr->iseq = (void *)node;
blockptr->proc = 0;
@@ -1258,20 +1256,20 @@
retval = (*it_proc)(data1);
}
else if (state == TAG_BREAK /* TODO: more check */ ) {
- retval = prot_tag->retval;
+ // TODO: Fix me
state = 0;
}
else if (state == TAG_RETRY) {
state = 0;
goto iter_retry;
}
- POP_TAG();
+ TH_POP_TAG();
switch (state) {
case 0:
break;
default:
- JUMP_TAG(state);
+ TH_JUMP_TAG(th, state);
}
return retval;
}
@@ -1392,7 +1390,8 @@
result = (*b_proc)(data1);
}
POP_TAG();
- retval = prot_tag ? prot_tag->retval : Qnil; /* save retval */
+ // TODO: fix me
+ // retval = prot_tag ? prot_tag->retval : Qnil; /* save retval */
(*e_proc)(data2);
if (state) JUMP_TAG(state);
return result;
Modified: trunk/eval_intern.h
===================================================================
--- trunk/eval_intern.h 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/eval_intern.h 2005-10-05 00:11:35 UTC (rev 274)
@@ -32,10 +32,6 @@
#endif
#include <stdio.h>
-#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
-#include <ucontext.h>
-#define USE_CONTEXT
-#endif
#include <setjmp.h>
#include "st.h"
@@ -95,20 +91,14 @@
#endif
#ifdef USE_CONTEXT
-typedef struct {
- ucontext_t context;
- volatile int status;
-} rb_jmpbuf_t[1];
NORETURN(static void rb_jump_context(rb_jmpbuf_t, int));
static inline void
-rb_jump_context(env, val)
- rb_jmpbuf_t env;
- int val;
+rb_jump_context(rb_jmpbuf_t env, int val)
{
- env->status = val;
- setcontext(&env->context);
- abort(); /* ensure noreturn */
+ env->status = val;
+ setcontext(&env->context);
+ abort(); /* ensure noreturn */
}
/*
* FUNCTION_CALL_MAY_RETURN_TWICE is a magic for getcontext, gcc,
@@ -160,7 +150,6 @@
getcontext(&(j)->context), \
(j)->status)
#else
-typedef jmp_buf rb_jmpbuf_t;
#if !defined(setjmp) && defined(HAVE__SETJMP)
#define ruby_setjmp(env) _setjmp(env)
#define ruby_longjmp(env,val) _longjmp(env,val)
@@ -198,22 +187,21 @@
#include <sys/stat.h>
+#define TH_PUSH_TAG(th) do { \
+ struct yarv_tag _tag; \
+ yarv_thread_t * const _th = th; \
+ _tag.prev = _th->tag; \
+ _th->tag = &_tag;
-struct tag {
- rb_jmpbuf_t buf;
- VALUE tag;
- VALUE retval;
- struct tag *prev;
-};
+#define TH_POP_TAG() \
+ _th->tag = _tag.prev; \
+} while (0)
-extern struct tag *ruby_prot_tag;
-#define prot_tag ruby_prot_tag
+#define TH_POP_TAG2() \
+ _th->tag = _tag.prev
-#define PUSH_TAG(ptag) do { \
- struct tag _tag; \
- _tag.prev = prot_tag; \
- _tag.tag = ptag; \
- prot_tag = &_tag
+#define PUSH_TAG(ptag) TH_PUSH_TAG(GET_THREAD())
+#define POP_TAG() TH_POP_TAG()
#define PUSH_THREAD_TAG() \
PUSH_TAG(PROT_THREAD)
@@ -229,16 +217,18 @@
#define PROT_YIELD INT2FIX(3) /* 7 */
#define PROT_TOP INT2FIX(4) /* 9 */
-#define EXEC_TAG() (FLUSH_REGISTER_WINDOWS, ruby_setjmp(prot_tag->buf))
+#define TH_EXEC_TAG() \
+ (FLUSH_REGISTER_WINDOWS, ruby_setjmp(_th->tag->buf))
-#define JUMP_TAG(st) do { \
- ruby_longjmp(prot_tag->buf,(st)); \
-} while (0)
+#define EXEC_TAG() \
+ TH_EXEC_TAG()
-#define POP_TAG() \
- prot_tag = _tag.prev; \
+#define TH_JUMP_TAG(th, st) do { \
+ ruby_longjmp(th->tag->buf,(st)); \
} while (0)
+#define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), st)
+
#define TAG_RETURN 0x1
#define TAG_BREAK 0x2
#define TAG_NEXT 0x3
Modified: trunk/eval_jump.h
===================================================================
--- trunk/eval_jump.h 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/eval_jump.h 2005-10-05 00:11:35 UTC (rev 274)
@@ -24,7 +24,7 @@
VALUE *argv;
{
VALUE tag, value;
- struct tag *tt = prot_tag;
+ struct yarv_tag *tt = GET_THREAD()->tag;
rb_scan_args(argc, argv, "11", &tag, &value);
tag = ID2SYM(rb_to_id(tag));
@@ -107,7 +107,7 @@
val = rb_yield_0(tag, 0, 0, 0, Qfalse);
}
else if (state == TAG_THROW /* TODO: fix me (more check) */) {
- val = prot_tag->retval;
+ val = GET_THREAD()->tag->retval;
state = 0;
}
POP_TAG();
@@ -152,14 +152,13 @@
void
-rb_exit(status)
- int status;
+rb_exit(int status)
{
- if (prot_tag) {
- terminate_process(status, "exit", 4);
- }
- ruby_finalize();
- exit(status);
+ if (GET_THREAD()->tag) {
+ terminate_process(status, "exit", 4);
+ }
+ ruby_finalize();
+ exit(status);
}
/*
@@ -437,7 +436,7 @@
void
jump_tag_but_local_jump(int state, VALUE val)
{
- if (val == Qundef) val = prot_tag->retval;
+ if (val == Qundef) val = GET_THREAD()->tag->retval;
switch (state) {
case 0:
break;
Modified: trunk/eval_thread.c
===================================================================
--- trunk/eval_thread.c 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/eval_thread.c 2005-10-05 00:11:35 UTC (rev 274)
@@ -219,63 +219,64 @@
/* typedef struct thread * rb_thread_t; */
struct thread {
- struct thread *next, *prev;
- rb_jmpbuf_t context;
+ /* obsolete */
+ struct thread *next, *prev;
+ rb_jmpbuf_t context;
#ifdef SAVE_WIN32_EXCEPTION_LIST
- DWORD win32_exception_list;
+ DWORD win32_exception_list;
#endif
- VALUE result;
+ VALUE result;
- long stk_len;
- long stk_max;
- VALUE *stk_ptr;
- VALUE *stk_pos;
+ long stk_len;
+ long stk_max;
+ VALUE *stk_ptr;
+ VALUE *stk_pos;
#ifdef __ia64__
- VALUE *bstr_ptr;
- long bstr_len;
+ VALUE *bstr_ptr;
+ long bstr_len;
#endif
- struct FRAME *frame;
- struct SCOPE *scope;
- struct RVarmap *dyna_vars;
- struct BLOCK *block;
- struct iter *iter;
- struct tag *tag;
- VALUE klass;
- VALUE wrapper;
- NODE *cref;
- struct ruby_env *anchor;
+ struct FRAME *frame;
+ struct SCOPE *scope;
+ struct RVarmap *dyna_vars;
+ struct BLOCK *block;
+ struct iter *iter;
+ struct tag *tag;
+ VALUE klass;
+ VALUE wrapper;
+ NODE *cref;
+ struct ruby_env *anchor;
- int flags; /* misc. states (vmode/rb_trap_immediate/raised) */
+ int flags; /* misc. states (vmode/rb_trap_immediate/raised) */
- NODE *node;
+ NODE *node;
- int tracing;
- VALUE errinfo;
- VALUE last_status;
- VALUE last_line;
- VALUE last_match;
+ int tracing;
+ VALUE errinfo;
+ VALUE last_status;
+ VALUE last_line;
+ VALUE last_match;
- int safe;
+ int safe;
- enum yarv_thread_status status;
- int wait_for;
- int fd;
- rb_fdset_t readfds;
- rb_fdset_t writefds;
- rb_fdset_t exceptfds;
- int select_value;
- double delay;
- rb_thread_t join;
+ enum yarv_thread_status status;
+ int wait_for;
+ int fd;
+ rb_fdset_t readfds;
+ rb_fdset_t writefds;
+ rb_fdset_t exceptfds;
+ int select_value;
+ double delay;
+ rb_thread_t join;
- int abort;
- int priority;
- VALUE thgroup;
+ int abort;
+ int priority;
+ VALUE thgroup;
- st_table *locals;
+ st_table *locals;
- VALUE thread;
+ VALUE thread;
};
#define THREAD_RAISED 0x200 /* temporary flag */
@@ -479,7 +480,7 @@
#endif
th->flags &= THREAD_FLAGS_MASK;
- th->tag = prot_tag;
+ //th->tag = prot_tag;
// th->tracing = tracing;
th->errinfo = ruby_errinfo;
th->last_status = rb_last_status;
@@ -548,7 +549,7 @@
#endif
rb_trap_immediate = 0; /* inhibit interrupts from here */
- prot_tag = th->tag;
+ // prot_tag = th->tag;
// tracing = th->tracing;
ruby_errinfo = th->errinfo;
rb_last_status = th->last_status;
@@ -1460,22 +1461,6 @@
static VALUE rb_thread_yield _((VALUE, rb_thread_t));
static void
-push_thread_anchor(ip)
- struct ruby_env *ip;
-{
- ip->tag = prot_tag;
- ip->prev = curr_thread->anchor;
- curr_thread->anchor = ip;
-}
-
-static void
-pop_thread_anchor(ip)
- struct ruby_env *ip;
-{
- curr_thread->anchor = ip->prev;
-}
-
-static void
thread_insert(th)
rb_thread_t th;
{
Modified: trunk/inits.c
===================================================================
--- trunk/inits.c 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/inits.c 2005-10-05 00:11:35 UTC (rev 274)
@@ -47,14 +47,12 @@
void Init_var_tables _((void));
void Init_version _((void));
void Init_yarvcore _((void));
-void Init_vm _((void));
void Init_jump _((void));
void
rb_call_inits()
{
- Init_vm();
Init_sym();
Init_var_tables();
Init_Object();
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/test.rb 2005-10-05 00:11:35 UTC (rev 274)
@@ -1,300 +1,10 @@
-class NP
-def initialize a=@p=[], b=@b=[]; end
-def +@;@b<<1;b2c end;def-@;@b<<0;b2c end
-def b2c;if @b.size==8;c=0; b.each{|b|c<<=1;c|=b};send(
- 'lave'.reverse,( p.join))if c==0; p<<c.chr; b=[] end
- self end end ; begin _ = NP.new end
-
-# The Programming Language `NegaPosi'
-+-+--++----+--+-+++--+-------+--++--+++---+-+++-+-+-+++-----+++-_
-+--++++--+---++-+-+-+++--+--+-+------+--++++-++---++-++---++-++-_
-+++--++-+-+--++--+++--+------+----+--++--+++-++-+----++------+--_
--+-+----+++--+--+----+--+--+-++-++--+++-++++-++-----+-+-+----++-_
----------+-+---- _
-__END__
-
-1.times{
- a = 1
- class A
- B = 1
- end
- 2.times{
- a+=1
- }
- a
-}
-
-
-__END__
-1.times{
- a = 0
- class A
- B = 1
- end
- 2.times{
- p 1
- a+=1#(a += 1; A)::B
- p 2
- }
- a
-}
-
-__END__
-
-1.times{
- a = 0
- class A
- B = 1
- end
- 2.times{
- (a += 1; A)
- }
- p a
-}
-__END__
-A = :A
- class B
- C = :C
- end
- class D
- E = :E
- end
- a = []
-p a << ((a << (a << A; B)::C); D)::E
-
-__END__
-
-def fact(n)
- if(n > 1)
- n * fact(n-1)
- else
- 1
- end
- end
- p fact(300)
-__END__
-
-def proc(&pr)
- pr
-end
-
-def m
- a = 1
- m2{
- a
- }
-end
-
-def m2
- b = 2
- proc{
- [yield, b]
- }
- 10000.times{|x|
- "#{x}"
- }
- yield
-end
-m
-__END__
-
-(1..10)
-__END__
-[('a'..'b'), ('a'...'b')]
-__END__
-
-2.times{
- p((''..'').object_id)
-}
-
-__END__
-[C, ::C, C::D]
-__END__
-
-C = 1
- C = 2
-
-__END__
-{1 => "a", 2 => "b", 3 => "c"}
-__END__
-@@a = 1
- a = @@a
-
-__END__
-a=0
-[a, 2, 3]
-
-__END__
i=0
-Thread.new{
- loop{
- sleep 0.1
- p i+=1 % 10
- }
-}
-
-Thread.new{
- p raw_gets
-}.join
-
-__END__
-Thread.new{
- 100.times{|i|
- sleep 1
- p [i]
- }
-}
-
-40.times{|i|
- p i
- sleep 0.1
-}
-#p gets while true
-
-
-__END__
-10000.times{|e|
- begin
- p e
- Thread.new{
- sleep
- }
- rescue Exception => ex
- p ex
- p e
- break
- end
-}
-
-__END__
-
-max = 100000000
def m
end
-t1 = Thread.new{
- max.times{
- m
- p 1
- }
-}
-t2 = Thread.new{
- max.times{
- m
- p '------------------------------------------------------------------'
- }
-}
-t1.join
-t2.join
-__END__
-
-Thread.new{
- sleep 1
-}.join
-p :fin
-
-__END__
-
-(1..10).map{|e|
- Thread.new(e){|le|
- p "Start #{le}"
- 10000.times{|i|
- p [le, i]
- }
- p "Finish #{le}"
- }
-}.each{|t|
- t.join
-}
-
-p :finish
-
-__END__
-
-def test100
- ths = (0..100).map{|e|
- Thread.new(e){|le|
- p le
- }
- }
- ths.each{|e| e.join}
+while i<10000000
+ m
+ i+=1
end
-test100
-t1 = Thread.new{
- p 1
-}
-t2 = Thread.new{
- p 2
-}
-t1.join
-t2.join
-__END__
-def jointest
- Thread.new{
- sleep
- }.join(10)
-
- p :finish
-end
-
-10.times{|e|
- Thread.new(e){|le|
- p "Start #{le}"
- 10000.times{|i|
- [le, i]
- }
- p "Finish #{le}"
- }
-}
-sleep 20
-p :finish
-__END__
-
-require 'test_req'
-
-# test_req.rb
-p TOPLEVEL_BINDING.__id__
-eval('p a', TOPLEVEL_BINDING)
-
-
-__END__
-i=0
-1.times{|j|
- 1.times{|k|
- p local_variables
- }
-}
-
-__END__
-
-require 'shellwords'
-
-class C
-end
-
-C.module_eval{
- Const = 1
- p self
-}
-p Const
-
-__END__
-def m
- a = 1
- proc
-end
-a = 2
-eval 'p a', m{}
-
-__END__
-def m a
- binding
-end
-
-bind = m(1)
-3.times{
- eval('p a+=1', bind)
-}
-
Modified: trunk/thread.c
===================================================================
--- trunk/thread.c 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/thread.c 2005-10-05 00:11:35 UTC (rev 274)
@@ -30,9 +30,9 @@
------------------------------------------------------------------------
model 3:
- Every threads run concurrent and to access shared object exclusive
- access control is needed. For example, to access String object or
- Array object, fine grain lock must be locked every time.
+ Every threads run concurrent or parallel and to access shared object
+ exclusive access control is needed. For example, to access String
+ object or Array object, fine grain lock must be locked every time.
*/
@@ -83,6 +83,7 @@
static int
thread_start_func_2(yarv_thread_t *th, VALUE *stack_start)
{
+ int state;
VALUE args = th->first_args;
yarv_proc_t *proc;
GetProcVal(th->first_proc, proc);
@@ -95,7 +96,15 @@
{
yarv_set_current_running_thread(th);
thread_debug("get_lock, start: %p\n", th);
- th->value = th_invoke_proc(th, proc, RARRAY(args)->len, RARRAY(args)->ptr);
+
+ TH_PUSH_TAG(th);
+ if((state = EXEC_TAG()) == 0){
+ th->value = th_invoke_proc(th, proc, RARRAY(args)->len, RARRAY(args)->ptr);
+ }
+ else{
+
+ }
+ TH_POP_TAG();
th->status = THREAD_KILLED;
thread_debug("end: %p\n", th);
st_delete_wrap(GET_VM()->living_threads, th->self);
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/vm.c 2005-10-05 00:11:35 UTC (rev 274)
@@ -853,89 +853,8 @@
/*********************************************************/
/* import from ruby1.9/eval.c */
-#include <stdio.h>
-#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
-#include <ucontext.h>
-#define USE_CONTEXT
-#else
-#include <setjmp.h>
-#endif
+#include "eval_intern.h"
-#ifdef USE_CONTEXT
-typedef struct {
- ucontext_t context;
- volatile int status;
-} rb_jmpbuf_t[1];
-
-#undef longjmp
-#undef setjmp
-NORETURN(static void rb_jump_context(rb_jmpbuf_t, int));
-static inline void
-rb_jump_context(env, val)
- rb_jmpbuf_t env;
- int val;
-{
- env->status = val;
- setcontext(&env->context);
- abort(); /* ensure noreturn */
-}
-#define longjmp(env, val) rb_jump_context(env, val)
-#define setjmp(j) ((j)->status = 0, getcontext(&(j)->context), (j)->status)
-#else
-typedef jmp_buf rb_jmpbuf_t;
-#ifndef setjmp
-#ifdef HAVE__SETJMP
-#define setjmp(env) _setjmp(env)
-#define longjmp(env,val) _longjmp(env,val)
-#endif
-#endif
-#endif
-
-struct tag {
- rb_jmpbuf_t buf;
- VALUE tag;
- VALUE retval;
- struct tag *prev;
-};
-
-#if YARVEXT
-RUBY_EXTERN struct tag *ruby_prot_tag;
-#else
-RUBY_EXTERN struct tag *ruby_prot_tag;
-#endif
-
-#define PUSH_TAG(ptag) do { \
- struct tag _tag; \
- _tag.prev = ruby_prot_tag; \
- _tag.tag = ptag; \
- ruby_prot_tag = &_tag
-
-#define POP_TAG() \
- ruby_prot_tag = _tag.prev; \
-} while (0)
-
-#define POP_TAG2() \
- ruby_prot_tag = _tag.prev; \
-
-
-
-#define EXEC_TAG() \
- (FLUSH_REGISTER_WINDOWS, setjmp(ruby_prot_tag->buf))
-
-#define JUMP_TAG(st) do { \
- longjmp(ruby_prot_tag->buf,(st)); \
-} while (0)
-
-#define TAG_RETURN 0x1
-#define TAG_BREAK 0x2
-#define TAG_NEXT 0x3
-#define TAG_RETRY 0x4
-#define TAG_REDO 0x5
-#define TAG_RAISE 0x6
-#define TAG_THROW 0x7
-#define TAG_FATAL 0x8
-#define TAG_MASK 0xf
-
/*********************************************************/
/*********************************************************/
@@ -1083,12 +1002,12 @@
VALUE
th_eval_body(yarv_thread_t *th)
{
- struct tag _tag;
+ struct yarv_tag _tag;
int state;
VALUE result, err;
VALUE initial = 0;
- PUSH_TAG(0);
+ TH_PUSH_TAG(th);
if((state = EXEC_TAG()) == 0){
vm_loop_start:
result = th_eval(th, initial);
@@ -1278,12 +1197,12 @@
else{
th->cfp++;
ruby_errinfo = err;
- POP_TAG2();
+ TH_POP_TAG2();
JUMP_TAG(state);
}
}
}
- POP_TAG();
+ TH_POP_TAG();
return result;
}
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/yarvcore.c 2005-10-05 00:11:35 UTC (rev 274)
@@ -631,20 +631,18 @@
obj = Data_Make_Struct(klass, yarv_thread_t,
thread_mark, thread_free, th);
+ MEMZERO(th, yarv_thread_t, 1);
return obj;
}
static void
-th_init(yarv_thread_t *th)
-{
+th_init2(yarv_thread_t *th){
/* allocate thread stack */
th->stack = ALLOC_N(VALUE, YARV_THREAD_STACK_SIZE);
th->stack_size = YARV_THREAD_STACK_SIZE;
th->cfp = (void *)(th->stack + th->stack_size);
th->cfp--;
- th->klass_nest_stack = rb_ary_push(rb_ary_new(), rb_cObject);
-
th->cfp->pc = 0;
th->cfp->sp = th->stack;
th->cfp->bp = 0;
@@ -654,9 +652,13 @@
th->cfp->magic = 0;
th->status = THREAD_RUNNABLE;
- th->local_storage = 0;
- th->top_local_tbl = 0;
}
+static void
+th_init(yarv_thread_t *th)
+{
+ th_init2(th);
+ th->klass_nest_stack = rb_ary_push(rb_ary_new(), rb_cObject);
+}
static VALUE
thread_init(VALUE self)
@@ -998,11 +1000,11 @@
}
void
-Init_vm()
+Init_yarv()
{
/* initialize main thread */
yarv_thread_t *th = ALLOC(yarv_thread_t);
- th_init(th);
+ th_init2(th);
yarv_set_current_running_thread(th);
}
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2005-10-03 13:34:11 UTC (rev 273)
+++ trunk/yarvcore.h 2005-10-05 00:11:35 UTC (rev 274)
@@ -10,9 +10,15 @@
#include <setjmp.h>
+#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
+#include <ucontext.h>
+#define USE_CONTEXT
+#endif
+#include "ruby.h"
+#include "st.h"
+
#include "debug.h"
#include "vm_opts.h"
-#include "st.h"
#if defined(HAVE_PTHREAD_H)
#include "thread_pthread.h"
@@ -306,7 +312,23 @@
THREAD_KILLED,
};
-typedef struct{
+#ifdef USE_CONTEXT
+typedef struct {
+ ucontext_t context;
+ volatile int status;
+} rb_jmpbuf_t[1];
+#else
+typedef jmp_buf rb_jmpbuf_t;
+#endif
+
+struct yarv_tag{
+ rb_jmpbuf_t buf;
+ VALUE tag;
+ VALUE retval;
+ struct yarv_tag *prev;
+};
+
+typedef struct yarv_thread{
VALUE self;
VALUE vm_value;
yarv_vm_t *vm;
@@ -335,9 +357,13 @@
/* thread control */
yarv_thread_id_t thread_id;
+ enum yarv_thread_status status;
+ struct yarv_tag *tag;
VALUE value;
- enum yarv_thread_status status;
+ VALUE exception;
+ struct yarv_thread *join_thread;
+
VALUE first_proc;
VALUE first_args;
@@ -349,7 +375,6 @@
/* other information */
st_table *local_storage; /* thread local storage */
VALUE stat_insn_usage;
-
} yarv_thread_t;
/** node -> yarv instruction sequence object */
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml