ruby-changes:8871
From: yugui <ko1@a...>
Date: Sun, 30 Nov 2008 18:24:03 +0900 (JST)
Subject: [ruby-changes:8871] Ruby:r20407 (ruby_1_9_1): * thread.c, thread_pthread.c, thread_win32.c: merges nobu's commits -
yugui 2008-11-30 18:22:31 +0900 (Sun, 30 Nov 2008) New Revision: 20407 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20407 Log: * thread.c, thread_pthread.c, thread_win32.c: merges nobu's commits - r20117, r20123, r20124, r20127, r20132-r20134, r20138, r20140, r20141 and r20160 - from trunk into ruby_1_9_1. * thread_pthread.c (thread_timer): checks working flags again. * thread_pthread.c (rb_thread_create_timer_thread): do not wait never coming signal if failed to create tiemr thread. * thread_pthread.c (native_cond_timedwait): returns error code. * thread_pthread.c (thread_timer, rb_thread_create_timer_thread): handshakes properly. * thread_pthread.c (thread_timer): initializes mutex each time. * thread_win32.c (thread_start_func_1): use already gotten stack info. * thread.c (thread_timer): pthread_cond_timedwait returns ETIMEDOUT when timed out. * thread_pthread.c (thread_timer): uses pthread_cond_timedwait always instead of pthread_kill. * thread.c (thread_timer): uses timedwait on cygwin. * thread.c (rb_thread_stop_timer_thread): terminates timer thread immediately. Modified files: branches/ruby_1_9_1/ChangeLog branches/ruby_1_9_1/thread.c branches/ruby_1_9_1/thread_pthread.c branches/ruby_1_9_1/thread_win32.c Index: ruby_1_9_1/thread_win32.c =================================================================== --- ruby_1_9_1/thread_win32.c (revision 20406) +++ ruby_1_9_1/thread_win32.c (revision 20407) @@ -455,7 +455,6 @@ thread_start_func_1(void *th_ptr) { rb_thread_t *th = th_ptr; - VALUE stack_start; volatile HANDLE thread_id = th->thread_id; native_thread_init_stack(th); @@ -464,8 +463,9 @@ /* run */ thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th, th->thread_id, th->native_thread_data.interrupt_event); - thread_start_func_2(th, &stack_start, 0); + thread_start_func_2(th, th->machine_stack_start, rb_ia64_bsp()); + w32_close_handle(thread_id); thread_debug("thread deleted (th: %p)\n", th); return 0; @@ -531,27 +531,42 @@ } static HANDLE timer_thread_id = 0; +static HANDLE timer_thread_lock; static unsigned long _stdcall timer_thread_func(void *dummy) { thread_debug("timer_thread\n"); - while (system_working) { - Sleep(WIN32_WAIT_TIMEOUT); + while (WaitForSingleObject(timer_thread_lock, WIN32_WAIT_TIMEOUT) == + WAIT_TIMEOUT) { timer_thread_function(dummy); } thread_debug("timer killed\n"); return 0; } -void +static void rb_thread_create_timer_thread(void) { if (timer_thread_id == 0) { + if (!timer_thread_lock) { + timer_thread_lock = CreateEvent(0, TRUE, FALSE, 0); + } timer_thread_id = w32_create_thread(1024 + (THREAD_DEBUG ? BUFSIZ : 0), - timer_thread_func, GET_VM()); + timer_thread_func, 0); w32_resume_thread(timer_thread_id); } } +static int +native_stop_timer_thread(void) +{ + int stopped = --system_working <= 0; + if (stopped) { + CloseHandle(timer_thread_lock); + timer_thread_lock = 0; + } + return stopped; +} + #endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */ Index: ruby_1_9_1/ChangeLog =================================================================== --- ruby_1_9_1/ChangeLog (revision 20406) +++ ruby_1_9_1/ChangeLog (revision 20407) @@ -1,3 +1,34 @@ +Sat Nov 29 00:27:33 2008 Yuki Sonoda (Yugui) <yugui@y...> + + * thread.c, thread_pthread.c, thread_win32.c: merges nobu's commits - + r20117, r20123, r20124, r20127, r20132-r20134, r20138, r20140, r20141 + and r20160 - from trunk into ruby_1_9_1. + + * thread_pthread.c (thread_timer): checks working flags again. + + * thread_pthread.c (rb_thread_create_timer_thread): do not wait never + coming signal if failed to create tiemr thread. + + * thread_pthread.c (native_cond_timedwait): returns error code. + + * thread_pthread.c (thread_timer, rb_thread_create_timer_thread): + handshakes properly. + + * thread_pthread.c (thread_timer): initializes mutex each time. + + * thread_win32.c (thread_start_func_1): use already gotten stack info. + + * thread.c (thread_timer): pthread_cond_timedwait returns ETIMEDOUT + when timed out. + + * thread_pthread.c (thread_timer): uses pthread_cond_timedwait always + instead of pthread_kill. + + * thread.c (thread_timer): uses timedwait on cygwin. + + * thread.c (rb_thread_stop_timer_thread): terminates timer thread + immediately. + Tue Nov 25 00:08:22 2008 Nobuyoshi Nakada <nobu@r...> * process.c (rb_fork): stops the timer thread during fork. Index: ruby_1_9_1/thread_pthread.c =================================================================== --- ruby_1_9_1/thread_pthread.c (revision 20406) +++ ruby_1_9_1/thread_pthread.c (revision 20407) @@ -116,7 +116,13 @@ pthread_cond_wait(cond, mutex); } +static int +native_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *ts) +{ + return pthread_cond_timedwait(cond, mutex, ts); +} + #define native_cleanup_push pthread_cleanup_push #define native_cleanup_pop pthread_cleanup_pop #ifdef HAVE_SCHED_YIELD @@ -503,6 +509,8 @@ #define ubf_select 0 #endif +#define PER_NANO 1000000000 + static void native_sleep(rb_thread_t *th, struct timeval *tv) { @@ -513,10 +521,10 @@ gettimeofday(&tvn, NULL); ts.tv_sec = tvn.tv_sec + tv->tv_sec; ts.tv_nsec = (tvn.tv_usec + tv->tv_usec) * 1000; - if (ts.tv_nsec >= 1000000000){ + if (ts.tv_nsec >= PER_NANO){ ts.tv_sec += 1; - ts.tv_nsec -= 1000000000; - } + ts.tv_nsec -= PER_NANO; + } } thread_debug("native_sleep %ld\n", tv ? tv->tv_sec : -1); @@ -535,7 +543,7 @@ int r; thread_debug("native_sleep: pthread_cond_wait start\n"); r = pthread_cond_wait(&th->native_thread_data.sleep_cond, - &th->interrupt_lock); + &th->interrupt_lock); if (r) rb_bug("pthread_cond_wait: %d", r); thread_debug("native_sleep: pthread_cond_wait end\n"); } @@ -647,22 +655,36 @@ } static pthread_t timer_thread_id; +static pthread_cond_t timer_thread_cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t timer_thread_lock = PTHREAD_MUTEX_INITIALIZER; +static struct timespec * +get_ts(struct timespec *ts, unsigned long nsec) +{ + struct timeval tv; + gettimeofday(&tv, 0); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000 + nsec; + if (ts->tv_nsec >= PER_NANO) { + ts->tv_sec++; + ts->tv_nsec -= PER_NANO; + } + return ts; +} + static void * thread_timer(void *dummy) { - while (system_working) { -#ifdef HAVE_NANOSLEEP - struct timespec req, rem; - req.tv_sec = 0; - req.tv_nsec = 10 * 1000 * 1000; /* 10 ms */ - nanosleep(&req, &rem); -#else - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 10000; /* 10 ms */ - select(0, NULL, NULL, NULL, &tv); -#endif + struct timespec ts; + int err; + + native_mutex_lock(&timer_thread_lock); + native_cond_broadcast(&timer_thread_cond); +#define WAIT_FOR_10MS() native_cond_timedwait(&timer_thread_cond, &timer_thread_lock, get_ts(&ts, PER_NANO/100)) + while (system_working > 0 && (err = WAIT_FOR_10MS()) != 0 && err != EINTR) { + if (err != ETIMEDOUT) { + rb_bug("thread_timer/timedwait: %d", err); + } #ifndef __CYGWIN__ if (signal_thread_list_anchor.next) { FGLOCK(&signal_thread_list_lock, { @@ -677,6 +699,7 @@ #endif timer_thread_function(dummy); } + native_mutex_unlock(&timer_thread_lock); return NULL; } @@ -694,12 +717,29 @@ pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + (THREAD_DEBUG ? BUFSIZ : 0)); #endif - err = pthread_create(&timer_thread_id, &attr, thread_timer, GET_VM()); + native_mutex_lock(&timer_thread_lock); + err = pthread_create(&timer_thread_id, &attr, thread_timer, 0); if (err != 0) { + native_mutex_unlock(&timer_thread_lock); rb_bug("rb_thread_create_timer_thread: return non-zero (%d)", err); } + native_cond_wait(&timer_thread_cond, &timer_thread_lock); + native_mutex_unlock(&timer_thread_lock); } rb_disable_interrupt(); /* only timer thread recieve signal */ } +static int +native_stop_timer_thread(void) +{ + int stopped; + native_mutex_lock(&timer_thread_lock); + stopped = --system_working <= 0; + if (stopped) { + native_cond_signal(&timer_thread_cond); + } + native_mutex_unlock(&timer_thread_lock); + return stopped; +} + #endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */ Index: ruby_1_9_1/thread.c =================================================================== --- ruby_1_9_1/thread.c (revision 20406) +++ ruby_1_9_1/thread.c (revision 20407) @@ -71,6 +71,7 @@ void rb_signal_exec(rb_thread_t *th, int sig); void rb_disable_interrupt(void); +void rb_thread_stop_timer_thread(void); static const VALUE eKillSignal = INT2FIX(0); static const VALUE eTerminateSignal = INT2FIX(1); @@ -318,7 +319,7 @@ } POP_TAG(); } - system_working = 0; + rb_thread_stop_timer_thread(); } static void @@ -2322,7 +2323,7 @@ static void timer_thread_function(void *arg) { - rb_vm_t *vm = arg; /* TODO: fix me for Multi-VM */ + rb_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */ int sig; /* for time slice */ @@ -2355,8 +2356,7 @@ void rb_thread_stop_timer_thread(void) { - if (timer_thread_id) { - system_working = 0; + if (timer_thread_id && native_stop_timer_thread()) { native_thread_join(timer_thread_id); timer_thread_id = 0; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/