yarv-diff:291
From: ko1 atdot.net
Date: 21 Feb 2006 04:09:30 -0000
Subject: [yarv-diff:291] r455 - in trunk: . yarvtest
Author: ko1
Date: 2006-02-21 13:09:30 +0900 (Tue, 21 Feb 2006)
New Revision: 455
Modified:
trunk/
trunk/ChangeLog
trunk/eval.c
trunk/eval_thread.c
trunk/test.rb
trunk/thread.c
trunk/thread_pthread.h
trunk/thread_win32.h
trunk/yarvcore.c
trunk/yarvcore.h
trunk/yarvtest/test_thread.rb
Log:
r696@lermite: ko1 | 2006-02-21 12:50:34 +0900
* eval_thread.c : remove unused function rb_thread_schedule()
* thread.c : rename yarv_thread_schedule to rb_thread_schedule()
* thread.c, eval.c : fix to terminate all thread and barrier at
eval.c#ruby_cleanup()
* thread_win32.h : remove native_thread_cleanup()
* thread_pthread.h : ditto
* yarvcore.c : ditto
* yarvtest/test_thread.rb : separete assersions to tests
Property changes on: trunk
___________________________________________________________________
Name: svk:merge
- 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:692
+ 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:696
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/ChangeLog 2006-02-21 04:09:30 UTC (rev 455)
@@ -4,6 +4,24 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-02-21(Tue) 12:42:44 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * eval_thread.c : remove unused function rb_thread_schedule()
+
+ * thread.c : rename yarv_thread_schedule to rb_thread_schedule()
+
+ * thread.c, eval.c : fix to terminate all thread and barrier at
+ eval.c#ruby_cleanup()
+
+ * thread_win32.h : remove native_thread_cleanup()
+
+ * thread_pthread.h : ditto
+
+ * yarvcore.c : ditto
+
+ * yarvtest/test_thread.rb : separete assersions to tests
+
+
2006-02-21(Tue) 02:13:33 +900 Yukihiro Matsumoto <matz ruby-lang.org>
* parse.y (f_arglist): should set command_start = Qtrue for
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/eval.c 2006-02-21 04:09:30 UTC (rev 455)
@@ -214,9 +214,11 @@
volatile VALUE err = GET_THREAD()->errinfo;
yarv_vm_t *vm = GET_VM();
+ rb_thread_terminate_all();
+
/* th->errinfo contains a NODE while break'ing */
if (RTEST(err) && (TYPE(err) != T_NODE) &&
- rb_obj_is_kind_of(err, rb_eSystemExit)) {
+ rb_obj_is_kind_of(err, rb_eSystemExit)) {
vm->exit_code = NUM2INT(rb_iv_get(err, "status"));
}
else {
Modified: trunk/eval_thread.c
===================================================================
--- trunk/eval_thread.c 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/eval_thread.c 2006-02-21 04:09:30 UTC (rev 455)
@@ -379,11 +379,6 @@
// TODO: fix me
}
-void
-rb_thread_schedule()
-{
-}
-
VALUE
rb_thread_current()
{
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/test.rb 2006-02-21 04:09:30 UTC (rev 455)
@@ -1,4 +1,7 @@
+
+__END__
+
class C
define_method(:foo){
return :bar
Modified: trunk/thread.c
===================================================================
--- trunk/thread.c 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/thread.c 2006-02-21 04:09:30 UTC (rev 455)
@@ -54,6 +54,11 @@
static void yarv_add_signal_thread_list(yarv_thread_t *th);
static void yarv_remove_signal_thread_list(yarv_thread_t *th);
+void rb_signal_exec(yarv_thread_t *th, int sig);
+static VALUE eKillSignal = INT2FIX(0);
+static VALUE eTerminateSignal = INT2FIX(1);
+static int system_working = 1;
+
inline static void
st_delete_wrap(st_table * table, VALUE key)
{
@@ -130,6 +135,49 @@
YARV_CHECK_INTS(); \
} while(0)
+static int
+terminate_i(st_data_t key, st_data_t val, yarv_thread_t *main_thread)
+{
+ VALUE thval = key;
+ yarv_thread_t *th;
+ GetThreadVal(thval, th);
+
+ if (th != main_thread) {
+ thread_debug("terminate_i: %p\n", th);
+ th->throwed_errinfo = eTerminateSignal;
+ th->interrupt_flag = 1;
+
+ if (th->status == THREAD_STOPPED) {
+ native_thread_interrupt(th);
+ }
+ th->status = THREAD_TO_KILL;
+ }
+ else {
+ thread_debug("terminate_i: main thread (%p)\n", th);
+ }
+ return ST_CONTINUE;
+}
+
+void
+rb_thread_terminate_all(void)
+{
+ yarv_thread_t *th = GET_THREAD(); /* main thread */
+ yarv_vm_t *vm = th->vm;
+ if (vm->main_thread != th) {
+ rb_bug("rb_thread_terminate_all: called by child thread");
+ }
+
+ thread_debug("rb_thread_terminate_all (main thread: %p)\n", th);
+ st_foreach(vm->living_threads, terminate_i, (st_data_t)th);
+
+ while (!rb_thread_alone()) {
+ rb_thread_schedule();
+ }
+ system_working = 0;
+}
+
+
+
VALUE th_eval_body(yarv_thread_t *th);
static void
@@ -478,13 +526,13 @@
}
void
-yarv_thread_schedule()
+rb_thread_schedule()
{
- thread_debug("yarv_thread_schedule\n");
+ thread_debug("rb_thread_schedule\n");
if (!rb_thread_alone()) {
yarv_thread_t *th = GET_THREAD();
- thread_debug("yarv_thread_schedule/switch start\n");
+ thread_debug("rb_thread_schedule/switch start\n");
yarv_save_machine_context(th);
native_mutex_unlock(&GET_VM()->global_interpreter_lock);
{
@@ -492,8 +540,9 @@
}
native_mutex_lock(&GET_VM()->global_interpreter_lock);
yarv_set_current_running_thread(th);
- thread_debug("yarv_thread_schedule/switch done (thid: %p)\n",
+ thread_debug("rb_thread_schedule/switch done (thid: %p)\n",
th->thread_id);
+ YARV_CHECK_INTS();
}
}
@@ -527,7 +576,7 @@
static VALUE
yarv_thread_s_pass(VALUE klass)
{
- yarv_thread_schedule();
+ rb_thread_schedule();
return Qnil;
}
@@ -536,10 +585,6 @@
*
*/
-void rb_signal_exec(yarv_thread_t *th, int sig);
-
-static VALUE eKillSignal = 1;
-
void
yarv_thread_execute_interrupts(yarv_thread_t *th)
{
@@ -562,10 +607,23 @@
if (th->throwed_errinfo) {
VALUE err = th->throwed_errinfo;
th->throwed_errinfo = 0;
+ thread_debug("yarv_thread_execute_interrupts: %p\n", err);
+
if (err == eKillSignal) {
th->errinfo = INT2FIX(TAG_FATAL);
TH_JUMP_TAG(th, TAG_FATAL);
}
+ else if (err == eTerminateSignal) {
+ struct yarv_tag *tag = th->tag;
+
+ /* rewind to toplevel stack */
+ while (th->tag->prev) {
+ th->tag = th->tag->prev;
+ }
+
+ th->errinfo = INT2FIX(TAG_FATAL);
+ TH_JUMP_TAG(th, TAG_FATAL);
+ }
else {
rb_exc_raise(err);
}
@@ -573,7 +631,7 @@
th->status = status;
/* thread pass */
- yarv_thread_schedule();
+ rb_thread_schedule();
}
}
@@ -675,7 +733,6 @@
rb_thread_kill(VALUE thread)
{
yarv_thread_t *th;
- int status;
GetThreadVal(thread, th);
@@ -689,14 +746,13 @@
rb_exit(EXIT_SUCCESS);
}
- status = th->status;
+ if (th->status == THREAD_STOPPED) {
+ native_thread_interrupt(th);
+ }
th->throwed_errinfo = eKillSignal;
+ th->interrupt_flag = 1;
th->status = THREAD_TO_KILL;
- th->interrupt_flag = 1;
-
- if (status == THREAD_STOPPED) {
- native_thread_interrupt(th);
- }
+
return thread;
}
@@ -1293,7 +1349,9 @@
int
rb_thread_alone()
{
- return GET_VM()->living_threads->num_entries == 1;
+ int num = GET_VM()->living_threads->num_entries;
+ thread_debug("rb_thread_alone: %d\n", num);
+ return num == 1;
}
/*
@@ -1904,6 +1962,7 @@
if (state) {
JUMP_TAG(state);
}
+ return self;
}
void
Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/thread_pthread.h 2006-02-21 04:09:30 UTC (rev 455)
@@ -42,14 +42,6 @@
posix_signal(SIGVTALRM, null_func);
}
-static int system_working = 1;
-
-void
-native_thread_cleanup(yarv_vm_t *vm)
-{
- system_working = 0;
-}
-
NOINLINE(static int
thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
void static thread_cleanup_func(void *th_ptr);
Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/thread_win32.h 2006-02-21 04:09:30 UTC (rev 455)
@@ -48,32 +48,6 @@
th->native_thread_data.interrupt_event);
}
-static int system_working = 1;
-
-static int
-kill_func(st_data_t key, st_data_t val, void *dummy)
-{
- HANDLE thid = (HANDLE) val;
- yarv_thread_t *th = (void *)key;
-
- thread_debug("kill_func\n");
- if (th == th->vm->main_thread) {
- thread_debug("kill_func: main thread - skip (%p)\n", thid);
- }
- else {
- thread_debug("kill_func: work thread - kill (%p)\n", thid);
- // TerminateThread(thid, 0);
- }
- return ST_CONTINUE;
-}
-
-void
-native_thread_cleanup(yarv_vm_t *vm)
-{
- system_working = 0;
- st_foreach(vm->living_threads, kill_func, 0);
-}
-
static void
w32_show_error_message()
{
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/yarvcore.c 2006-02-21 04:09:30 UTC (rev 455)
@@ -494,8 +494,6 @@
if (ptr) {
yarv_vm_t *vmobj = ptr;
- native_thread_cleanup(ptr);
-
st_free_table(vmobj->living_threads);
// TODO: MultiVM Instance
// VM object should not be cleaned by GC
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/yarvcore.h 2006-02-21 04:09:30 UTC (rev 455)
@@ -580,7 +580,6 @@
extern int rb_thread_pending;
-//void yarv_thread_schedule();
void yarv_thread_execute_interrupts(yarv_thread_t *);
#define YARV_CHECK_INTS_TH(th) do { \
Modified: trunk/yarvtest/test_thread.rb
===================================================================
--- trunk/yarvtest/test_thread.rb 2006-02-20 17:15:04 UTC (rev 454)
+++ trunk/yarvtest/test_thread.rb 2006-02-21 04:09:30 UTC (rev 455)
@@ -15,7 +15,7 @@
}
end
- def test_create_many_threads
+ def test_create_many_threads1
ae %q{
v = 0
(1..200).map{|i|
@@ -27,6 +27,9 @@
}
v
}
+ end
+
+ def test_create_many_threads2
ae %q{
10000.times{|e|
(1..2).map{
@@ -37,6 +40,9 @@
}
}
}
+ end
+
+ def test_create_many_threads3
ae %q{
5000.times{
t = Thread.new{}
@@ -47,6 +53,14 @@
}
end
+ def test_create_many_threads4
+ ae %q{
+ 100.times{
+ Thread.new{loop{Thread.pass}}
+ }
+ }
+ end
+
def test_raise
ae %q{
t = Thread.new{
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml