зеркало из https://github.com/github/ruby.git
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
94c942ed34
Коммит
5f0b8afb97
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Tue Dec 25 13:07:56 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* 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@atdot.net>
|
||||
|
||||
* vm.c (Init_VM): remove unused code.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
cont.c
2
cont.c
|
@ -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);
|
||||
|
|
6
thread.c
6
thread.c
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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 { \
|
||||
|
|
Загрузка…
Ссылка в новой задаче