mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46406 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									e2b10b6d13
								
							
						
					
					
						commit
						dfd8c5d402
					
				
					 6 changed files with 89 additions and 10 deletions
				
			
		
							
								
								
									
										15
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,18 @@
 | 
			
		|||
Wed Jun 11 17:37:48 2014  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* 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@atdot.net>
 | 
			
		||||
 | 
			
		||||
	* gc.c: invoke GC before memory allocation (xmalloc/xrealloc)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								configure.in
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								configure.in
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2603,6 +2603,20 @@ if test x"$enable_pthread" = xyes; then
 | 
			
		|||
    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 \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										56
									
								
								thread.c
									
										
									
									
									
								
							
							
						
						
									
										56
									
								
								thread.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -173,6 +173,33 @@ void rb_thread_debug(const char *fmt, ...);
 | 
			
		|||
#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 val)
 | 
			
		|||
#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 *);
 | 
			
		|||
 | 
			
		||||
#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(
 | 
			
		|||
{
 | 
			
		||||
    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)
 | 
			
		|||
	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, double delay)
 | 
			
		|||
    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, double delay)
 | 
			
		|||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		|||
	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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -454,6 +454,7 @@ Init_native_thread(void)
 | 
			
		|||
 | 
			
		||||
    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)
 | 
			
		|||
	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)
 | 
			
		|||
	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 *th)
 | 
			
		|||
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);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								vm.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2131,6 +2131,9 @@ th_init(rb_thread_t *th, VALUE self)
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -507,6 +507,8 @@ typedef struct rb_ensure_list {
 | 
			
		|||
    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 {
 | 
			
		|||
 | 
			
		||||
    /* 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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue