diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | bootstraptest/test_thread.rb | 12 | ||||
-rw-r--r-- | cont.c | 2 | ||||
-rw-r--r-- | thread.c | 6 | ||||
-rw-r--r-- | thread_pthread.c | 16 | ||||
-rw-r--r-- | thread_win32.c | 15 | ||||
-rw-r--r-- | vm_core.h | 4 |
7 files changed, 50 insertions, 15 deletions
@@ -1,3 +1,13 @@ +Tue Dec 25 13:07:56 2007 Koichi Sasada <[email protected]> + + * 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 <[email protected]> * vm.c (Init_VM): remove unused code. diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb index 3c1cc5a1c1..b3592e9bd7 100644 --- a/bootstraptest/test_thread.rb +++ b/bootstraptest/test_thread.rb @@ -25,7 +25,17 @@ assert_equal %q{5000}, %q{ 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) } } } @@ -610,7 +610,7 @@ rb_fiber_start(void) 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); @@ -218,7 +218,7 @@ static void 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 @@ thread_join_m(int argc, VALUE *argv, VALUE self) if (!NIL_P(limit)) { delay = rb_num2dbl(limit); } + return thread_join(target_th, delay); } @@ -607,7 +608,6 @@ static void sleep_forever(rb_thread_t *th) { native_sleep(th, 0); - RUBY_VM_CHECK_INTS(); } static void @@ -1924,7 +1924,7 @@ timer_thread_function(void) 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) { diff --git a/thread_pthread.c b/thread_pthread.c index a511468949..5a3770520f 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -392,6 +392,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv) int prev_status = th->status; struct timespec ts; struct timeval tvn; + struct timeval tve; if (tv) { gettimeofday(&tvn, NULL); @@ -410,15 +411,14 @@ native_sleep(rb_thread_t *th, struct timeval *tv) 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 @@ native_sleep(rb_thread_t *th, struct timeval *tv) &th->interrupt_lock, &ts); thread_debug("native_sleep: pthread_cond_timedwait end (%d)\n", r); } - th->unblock_function = 0; - th->unblock_function_arg = 0; } - pthread_mutex_unlock(&th->interrupt_lock); + 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"); } diff --git a/thread_win32.c b/thread_win32.c index d8b33e23e0..a7326ebfc5 100644 --- a/thread_win32.c +++ b/thread_win32.c @@ -208,17 +208,26 @@ native_sleep(rb_thread_t *th, struct timeval *tv) { 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 @@ -634,6 +634,10 @@ extern rb_vm_t *ruby_current_vm; #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 { \ |