ruby-changes:34325
From: nobu <ko1@a...>
Date: Wed, 11 Jun 2014 17:38:20 +0900 (JST)
Subject: [ruby-changes:34325] nobu:r46406 (trunk): thread.c: fix for non-scalar pthread_t
nobu 2014-06-11 17:38:09 +0900 (Wed, 11 Jun 2014) New Revision: 46406 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46406 Log: thread.c: fix for non-scalar pthread_t * configure.in (rb_cv_scalar_pthread_t): pthread_t is not required to be a scalar type. * thread.c (fill_thread_id_string, thread_id_str): dump pthread_t in hexadecimal form if it is not a scalar type, assume it can be represented in a pointer form otherwise. based on the patch by Rei Odaira at [ruby-core:62867]. [ruby-core:62857] [Bug #9884] * thread_pthread.c (Init_native_thread, thread_start_func_1), (native_thread_create): set thread_id_str if needed. * vm_core.h (rb_thread_t): add thread_id_string if needed. Modified files: trunk/ChangeLog trunk/configure.in trunk/thread.c trunk/thread_pthread.c trunk/vm.c trunk/vm_core.h Index: configure.in =================================================================== --- configure.in (revision 46405) +++ configure.in (revision 46406) @@ -2603,6 +2603,20 @@ if test x"$enable_pthread" = xyes; then https://github.com/ruby/ruby/blob/trunk/configure.in#L2603 else AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled") fi + AC_CACHE_CHECK([whether pthread_t is scalar type], [rb_cv_scalar_pthread_t], [ + AC_TRY_COMPILE([ + @%:@include <pthread.h> + ], [ + pthread_t thread_id; + thread_id = 0; + if (!thread_id) return 0; + ], [rb_cv_scalar_pthread_t=yes], [rb_cv_scalar_pthread_t=no]) + ]) + if test x"$rb_cv_scalar_pthread_t" = xyes; then + : # RUBY_CHECK_SIZEOF(pthread_t, [void* int long], [], [@%:@include <pthread.h>]) + else + AC_DEFINE(NON_SCALAR_THREAD_ID) + fi AC_CHECK_FUNCS(sched_yield pthread_attr_setinheritsched \ pthread_getattr_np pthread_attr_get_np pthread_attr_getstack\ pthread_get_stackaddr_np pthread_get_stacksize_np \ Index: ChangeLog =================================================================== --- ChangeLog (revision 46405) +++ ChangeLog (revision 46406) @@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Jun 11 17:37:48 2014 Nobuyoshi Nakada <nobu@r...> + + * configure.in (rb_cv_scalar_pthread_t): pthread_t is not required + to be a scalar type. + + * thread.c (fill_thread_id_string, thread_id_str): dump pthread_t + in hexadecimal form if it is not a scalar type, assume it can be + represented in a pointer form otherwise. based on the patch by + Rei Odaira at [ruby-core:62867]. [ruby-core:62857] [Bug #9884] + + * thread_pthread.c (Init_native_thread, thread_start_func_1), + (native_thread_create): set thread_id_str if needed. + + * vm_core.h (rb_thread_t): add thread_id_string if needed. + Wed Jun 11 01:53:22 2014 Koichi Sasada <ko1@a...> * gc.c: invoke GC before memory allocation (xmalloc/xrealloc) Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 46405) +++ thread_pthread.c (revision 46406) @@ -454,6 +454,7 @@ Init_native_thread(void) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L454 pthread_key_create(&ruby_native_thread_key, NULL); th->thread_id = pthread_self(); + fill_thread_id_str(th); native_thread_init(th); #ifdef USE_SIGNAL_THREAD_LIST native_mutex_initialize(&signal_thread_list_lock); @@ -798,6 +799,7 @@ thread_start_func_1(void *th_ptr) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L799 VALUE stack_start; #endif + fill_thread_id_str(th); #if defined USE_NATIVE_THREAD_INIT native_thread_init_stack(th); #endif @@ -958,6 +960,8 @@ native_thread_create(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L960 native_mutex_unlock(&th->interrupt_lock); #endif thread_debug("create: %p (%d)\n", (void *)th, err); + /* should be done in the created thread */ + fill_thread_id_str(th); #ifdef HAVE_PTHREAD_ATTR_INIT CHECK_ERR(pthread_attr_destroy(&attr)); #endif @@ -1157,7 +1161,7 @@ remove_signal_thread_list(rb_thread_t *t https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1161 static void ubf_select_each(rb_thread_t *th) { - thread_debug("ubf_select_each (%p)\n", (void *)th->thread_id); + thread_debug("ubf_select_each (%"PRI_THREAD_ID")\n", thread_id_str(th)); if (th) { pthread_kill(th->thread_id, SIGVTALRM); } Index: vm_core.h =================================================================== --- vm_core.h (revision 46405) +++ vm_core.h (revision 46406) @@ -507,6 +507,8 @@ typedef struct rb_ensure_list { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L507 struct rb_ensure_entry entry; } rb_ensure_list_t; +typedef char rb_thread_id_string_t[sizeof(rb_nativethread_id_t) * 2 + 3]; + typedef struct rb_thread_struct { struct list_node vmlt_node; VALUE self; @@ -546,6 +548,9 @@ typedef struct rb_thread_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L548 /* thread control */ rb_nativethread_id_t thread_id; +#ifdef NON_SCALAR_THREAD_ID + rb_thread_id_string_t thread_id_string; +#endif enum rb_thread_status status; int to_kill; int priority; Index: thread.c =================================================================== --- thread.c (revision 46405) +++ thread.c (revision 46406) @@ -173,6 +173,33 @@ void rb_thread_debug(const char *fmt, .. https://github.com/ruby/ruby/blob/trunk/thread.c#L173 #define POSITION_ARGS #endif +# ifdef NON_SCALAR_THREAD_ID +static const char * +fill_thread_id_string(rb_nativethread_id_t thid, rb_thread_id_string_t buf) +{ + extern const char ruby_digitmap[]; + size_t i; + + buf[0] = '0'; + buf[1] = 'x'; + for (i = 0; i < sizeof(thid); i++) { +# ifdef LITTLE_ENDIAN + size_t j = sizeof(thid) - i - 1; +# else + size_t j = i; +# endif + unsigned char c = (unsigned char)((char *)&thid)[j]; + buf[2 + i * 2] = ruby_digitmap[(c >> 4) & 0xf]; + buf[3 + i * 2] = ruby_digitmap[c & 0xf]; + } + buf[sizeof(rb_thread_id_string_t)-1] = '\0'; + return buf; +} +# define fill_thread_id_str(th) fill_thread_id_string((th)->thread_id, (th)->thread_id_string) +# define thread_id_str(th) ((th)->thread_id_string) +# define PRI_THREAD_ID "s" +# endif + # if THREAD_DEBUG < 0 static int rb_thread_debug_enabled; @@ -211,6 +238,13 @@ rb_thread_s_debug_set(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L238 #define thread_debug if(0)printf #endif +#ifndef fill_thread_id_str +# define fill_thread_id_string(thid, buf) (thid) +# define fill_thread_id_str(th) (void)0 +# define thread_id_str(th) ((void *)(th)->thread_id) +# define PRI_THREAD_ID "p" +#endif + #ifndef __ia64 #define thread_start_func_2(th, st, rst) thread_start_func_2(th, st) #endif @@ -232,7 +266,8 @@ static void timer_thread_function(void * https://github.com/ruby/ruby/blob/trunk/thread.c#L266 #define DEBUG_OUT() \ pthread_mutex_lock(&debug_mutex); \ - printf(POSITION_FORMAT"%#"PRIxVALUE" - %s" POSITION_ARGS, (VALUE)pthread_self(), buf); \ + printf(POSITION_FORMAT"%"PRI_THREAD_ID" - %s" POSITION_ARGS, \ + fill_thread_id_string(pthread_self(), thread_id_string), buf); \ fflush(stdout); \ pthread_mutex_unlock(&debug_mutex); @@ -253,6 +288,9 @@ rb_thread_debug( https://github.com/ruby/ruby/blob/trunk/thread.c#L288 { va_list args; char buf[BUFSIZ]; +#ifdef NON_SCALAR_THREAD_ID + rb_thread_id_string_t thread_id_string; +#endif if (!rb_thread_debug_enabled) return; @@ -792,14 +830,14 @@ thread_join_sleep(VALUE arg) https://github.com/ruby/ruby/blob/trunk/thread.c#L830 else { now = timeofday(); if (now > limit) { - thread_debug("thread_join: timeout (thid: %p)\n", - (void *)target_th->thread_id); + thread_debug("thread_join: timeout (thid: %"PRI_THREAD_ID")\n", + thread_id_str(target_th)); return Qfalse; } sleep_wait_for_interrupt(th, limit - now, 0); } - thread_debug("thread_join: interrupted (thid: %p)\n", - (void *)target_th->thread_id); + thread_debug("thread_join: interrupted (thid: %"PRI_THREAD_ID")\n", + thread_id_str(target_th)); } return Qtrue; } @@ -822,7 +860,7 @@ thread_join(rb_thread_t *target_th, doub https://github.com/ruby/ruby/blob/trunk/thread.c#L860 arg.limit = timeofday() + delay; arg.forever = delay == DELAY_INFTY; - thread_debug("thread_join (thid: %p)\n", (void *)target_th->thread_id); + thread_debug("thread_join (thid: %"PRI_THREAD_ID")\n", thread_id_str(target_th)); if (target_th->status != THREAD_KILLED) { rb_thread_list_t list; @@ -835,8 +873,8 @@ thread_join(rb_thread_t *target_th, doub https://github.com/ruby/ruby/blob/trunk/thread.c#L873 } } - thread_debug("thread_join: success (thid: %p)\n", - (void *)target_th->thread_id); + thread_debug("thread_join: success (thid: %"PRI_THREAD_ID")\n", + thread_id_str(target_th)); if (target_th->errinfo != Qnil) { VALUE err = target_th->errinfo; @@ -2145,7 +2183,7 @@ rb_thread_kill(VALUE thread) https://github.com/ruby/ruby/blob/trunk/thread.c#L2183 rb_exit(EXIT_SUCCESS); } - thread_debug("rb_thread_kill: %p (%p)\n", (void *)th, (void *)th->thread_id); + thread_debug("rb_thread_kill: %p (%"PRI_THREAD_ID")\n", (void *)th, thread_id_str(th)); if (th == GET_THREAD()) { /* kill myself immediately */ Index: vm.c =================================================================== --- vm.c (revision 46405) +++ vm.c (revision 46406) @@ -2131,6 +2131,9 @@ th_init(rb_thread_t *th, VALUE self) https://github.com/ruby/ruby/blob/trunk/vm.c#L2131 th->last_status = Qnil; th->waiting_fd = -1; th->root_svar = Qnil; +#ifdef NON_SCALAR_THREAD_ID + th->thread_id_string[0] = '\0'; +#endif #if OPT_CALL_THREADED_CODE th->retval = Qundef; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/