ruby-changes:3162
From: ko1@a...
Date: 25 Dec 2007 13:16:23 +0900
Subject: [ruby-changes:3162] ko1 - Ruby:r14654 (trunk): * vm_core.h, thread.c, cont.c: add RUBY_VM_SET_INTERRUPT(),
ko1 2007-12-25 13:16:06 +0900 (Tue, 25 Dec 2007) New Revision: 14654 Modified files: trunk/ChangeLog trunk/bootstraptest/test_thread.rb trunk/cont.c trunk/thread.c trunk/thread_pthread.c trunk/thread_win32.c trunk/vm_core.h Log: * vm_core.h, thread.c, cont.c: add RUBY_VM_SET_INTERRUPT(), RUBY_VM_SET_TIMER_INTERRUPT(), RUBY_VM_INTERRUPTED(). * thread.c, thread_pthread.c, thread_win32.c: fix to ignore time slice event until sleep. * bootstraptest/test_thread.rb: add a test for time limited join test. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/cont.c?r1=14654&r2=14653 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14654&r2=14653 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/thread_win32.c?r1=14654&r2=14653 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/thread.c?r1=14654&r2=14653 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_core.h?r1=14654&r2=14653 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_thread.rb?r1=14654&r2=14653 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/thread_pthread.c?r1=14654&r2=14653 Index: thread_win32.c =================================================================== --- thread_win32.c (revision 14653) +++ thread_win32.c (revision 14654) @@ -208,17 +208,26 @@ { DWORD ret; int status = th->status; + th->status = THREAD_STOPPED; th->unblock_function = ubf_handle; th->unblock_function_arg = th; - thread_debug("native_sleep start (%d)\n", (int)msec); - ret = w32_wait_events(0, 0, msec, th); - thread_debug("native_sleep done (%d)\n", ret); + + if (RUBY_VM_INTERRUPTED(th)) { + /* interrupted. return immediate */ + } + else { + thread_debug("native_sleep start (%d)\n", (int)msec); + ret = w32_wait_events(0, 0, msec, th); + thread_debug("native_sleep done (%d)\n", ret); + } + th->unblock_function = 0; th->unblock_function_arg = 0; th->status = status; } GVL_UNLOCK_END(); + RUBY_VM_CHECK_INTS(); } int Index: ChangeLog =================================================================== --- ChangeLog (revision 14653) +++ ChangeLog (revision 14654) @@ -1,3 +1,13 @@ +Tue Dec 25 13:07:56 2007 Koichi Sasada <ko1@a...> + + * vm_core.h, thread.c, cont.c: add RUBY_VM_SET_INTERRUPT(), + RUBY_VM_SET_TIMER_INTERRUPT(), RUBY_VM_INTERRUPTED(). + + * thread.c, thread_pthread.c, thread_win32.c: fix to ignore time slice + event until sleep. + + * bootstraptest/test_thread.rb: add a test for time limited join test. + Tue Dec 25 12:42:59 2007 Koichi Sasada <ko1@a...> * vm.c (Init_VM): remove unused code. Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 14653) +++ thread_pthread.c (revision 14654) @@ -392,6 +392,7 @@ int prev_status = th->status; struct timespec ts; struct timeval tvn; + struct timeval tve; if (tv) { gettimeofday(&tvn, NULL); @@ -410,15 +411,14 @@ GVL_UNLOCK_BEGIN(); { pthread_mutex_lock(&th->interrupt_lock); + th->unblock_function = ubf_pthread_cond_signal; + th->unblock_function_arg = th; - if (th->interrupt_flag) { + if (RUBY_VM_INTERRUPTED(th)) { /* interrupted. return immediate */ thread_debug("native_sleep: interrupted before sleep\n"); } else { - th->unblock_function = ubf_pthread_cond_signal; - th->unblock_function_arg = th; - if (tv == 0) { thread_debug("native_sleep: pthread_cond_wait start\n"); pthread_cond_wait(&th->native_thread_data.sleep_cond, @@ -433,14 +433,16 @@ &th->interrupt_lock, &ts); thread_debug("native_sleep: pthread_cond_timedwait end (%d)\n", r); } - th->unblock_function = 0; - th->unblock_function_arg = 0; } + th->unblock_function = 0; + th->unblock_function_arg = 0; + pthread_mutex_unlock(&th->interrupt_lock); - th->status = prev_status; } GVL_UNLOCK_END(); + RUBY_VM_CHECK_INTS(); + thread_debug("native_sleep done\n"); } Index: bootstraptest/test_thread.rb =================================================================== --- bootstraptest/test_thread.rb (revision 14653) +++ bootstraptest/test_thread.rb (revision 14654) @@ -25,11 +25,21 @@ Thread.new{ } }.each{|e| - e.join + e.join() } } } assert_equal %q{5000}, %q{ + 5000.times{|e| + (1..2).map{ + Thread.new{ + } + }.each{|e| + e.join(1000000000) + } + } +} +assert_equal %q{5000}, %q{ 5000.times{ t = Thread.new{} while t.alive? Index: vm_core.h =================================================================== --- vm_core.h (revision 14653) +++ vm_core.h (revision 14654) @@ -634,6 +634,10 @@ #error "unsupported thread model" #endif +#define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02) +#define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01) +#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02) + void rb_thread_execute_interrupts(rb_thread_t *); #define RUBY_VM_CHECK_INTS_TH(th) do { \ Index: thread.c =================================================================== --- thread.c (revision 14653) +++ thread.c (revision 14654) @@ -218,7 +218,7 @@ rb_thread_interrupt(rb_thread_t *th) { native_mutex_lock(&th->interrupt_lock); - th->interrupt_flag = 1; + RUBY_VM_SET_INTERRUPT(th); if (th->unblock_function) { (th->unblock_function)(th->unblock_function_arg); } @@ -562,6 +562,7 @@ if (!NIL_P(limit)) { delay = rb_num2dbl(limit); } + return thread_join(target_th, delay); } @@ -607,7 +608,6 @@ sleep_forever(rb_thread_t *th) { native_sleep(th, 0); - RUBY_VM_CHECK_INTS(); } static void @@ -1924,7 +1924,7 @@ rb_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */ /* for time slice */ - vm->running_thread->interrupt_flag = 1; + RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread); /* check signal */ if (vm->buffered_signal_size && vm->main_thread->exec_signal == 0) { Index: cont.c =================================================================== --- cont.c (revision 14653) +++ cont.c (revision 14654) @@ -610,7 +610,7 @@ th->thrown_errinfo = vm_make_jump_tag_but_local_jump(state, th->errinfo); } - th->interrupt_flag = 1; + RUBY_VM_SET_INTERRUPT(th); } rb_fiber_terminate(cont); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml