[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]