[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:327

From: ko1 atdot.net
Date: 4 May 2006 18:34:08 -0000
Subject: [yarv-diff:327] r494 - in trunk: . yarvtest

Author: ko1
Date: 2006-05-05 03:34:07 +0900 (Fri, 05 May 2006)
New Revision: 494

Modified:
   trunk/
   trunk/ChangeLog
   trunk/eval_thread.c
   trunk/intern.h
   trunk/signal.c
   trunk/thread.c
   trunk/thread_pthread.h
   trunk/thread_win32.h
   trunk/yarv.h
   trunk/yarvcore.h
   trunk/yarvtest/test_thread.rb
Log:
 r764@lermite:  ko1 | 2006-05-04 18:14:47 +0900
 	* eval_thread.c : remove rb_thread_interrupt
 
 	* intern.h : ditto
 
 	* signal.c : change signal transfer route
 
 	* thread.c : ditto
 
 	* thread_pthread.h : ditto
 
 	* thread_win32.h : ditto
 
 	* yarv.h : support GET_VM()
 
 	* yarvcore.h : change yarv_thread_t/yarv_vm_t structure
 
 	* yarvtest/test_thread.rb : decrease threads to test
 



Property changes on: trunk
___________________________________________________________________
Name: svk:merge
   - 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:762
   + 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:764

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/ChangeLog	2006-05-04 18:34:07 UTC (rev 494)
@@ -4,6 +4,27 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2006-05-04(Thu) 18:11:43 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* eval_thread.c : remove rb_thread_interrupt
+
+	* intern.h : ditto
+
+	* signal.c : change signal transfer route
+
+	* thread.c : ditto
+
+	* thread_pthread.h : ditto
+
+	* thread_win32.h : ditto
+
+	* yarv.h : support GET_VM()
+
+	* yarvcore.h : change yarv_thread_t/yarv_vm_t structure
+
+	* yarvtest/test_thread.rb : decrease threads to test
+
+
 2006-05-04(Thu) 00:26:18 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* thread_pthread.h : experimental support of thread cache

Modified: trunk/eval_thread.c
===================================================================
--- trunk/eval_thread.c	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/eval_thread.c	2006-05-04 18:34:07 UTC (rev 494)
@@ -533,12 +533,6 @@
 /***/
 
 void
-rb_thread_interrupt()
-{
-    rb_interrupt();
-}
-
-void
 rb_thread_atfork(void)
 {
     // TODO

Modified: trunk/intern.h
===================================================================
--- trunk/intern.h	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/intern.h	2006-05-04 18:34:07 UTC (rev 494)
@@ -270,7 +270,6 @@
 VALUE rb_thread_run(VALUE);
 VALUE rb_thread_kill(VALUE);
 VALUE rb_thread_create(VALUE (*)(ANYARGS), void*);
-void rb_thread_interrupt(void);
 void rb_thread_trap_eval(VALUE, int, int);
 void rb_thread_signal_raise(void *, const char*); /* should pass literal */
 void rb_thread_signal_exit(void *);

Modified: trunk/signal.c
===================================================================
--- trunk/signal.c	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/signal.c	2006-05-04 18:34:07 UTC (rev 494)
@@ -392,24 +392,61 @@
 static RETSIGTYPE
 sighandler(int sig)
 {
-  yarv_thread_t *th = GET_THREAD()->vm->main_thread; // TODO: fix me
-  int next_head = (th->signal_queue.head + 1) % RUBY_SIGNAL_QUEUE_MAX;
-  
-  if(next_head == th->signal_queue.tail){
-    /* signal queue overflow */
-    fprintf(stderr, "Signal Queue overflow. This signal (%d) is ignored.\n", sig);
-  }
-  else{
-    th->signal_queue.buff[th->signal_queue.head] = sig;
-    th->signal_queue.head = next_head;
-  }
+    yarv_vm_t *vm = GET_VM(); /* fix me for Multi-VM */
+    ATOMIC_INC(vm->signal_buff[sig]);
+    ATOMIC_INC(vm->bufferd_signal_size);
+}
 
-  if(th->status == THREAD_STOPPED){
-    native_thread_interrupt(th);
-  }
-  th->interrupt_flag = 1;
+# ifdef HAVE_SIGPROCMASK
+static sigset_t trap_last_mask;
+# else
+static int trap_last_mask;
+# endif
+
+void
+rb_disable_interrupt(void)
+{
+#ifndef _WIN32
+#ifdef HAVE_SIGPROCMASK
+    sigset_t mask;
+    sigfillset(&mask);
+    sigdelset(&mask, SIGVTALRM);
+    sigprocmask(SIG_SETMASK, &mask, NULL);
+#else
+    int mask;
+    mask = sigblock((~0) ^ (1<<SIGVTALRM));
+    sigsetmask(mask);
+#endif
+    trap_last_mask = mask;
+#endif
 }
 
+static void
+rb_enable_interrupt(void)
+{
+    rb_trap_restore_mask();
+}
+
+int
+rb_get_next_signal(yarv_vm_t *vm)
+{
+    int i, sig = 0;
+
+    for (i=1; i<RUBY_NSIG; i++) {
+	if (vm->signal_buff[i] > 0) {
+	    rb_disable_interrupt();
+	    {
+		ATOMIC_DEC(vm->signal_buff[i]);
+		ATOMIC_DEC(vm->bufferd_signal_size);
+	    }
+	    rb_enable_interrupt();
+	    sig = i;
+	    break;
+	}
+    }
+    return sig;
+}
+
 #ifdef SIGBUS
 static RETSIGTYPE
 sigbus(int sig)
@@ -463,7 +500,7 @@
   if (cmd == 0) {
     switch (sig) {
     case SIGINT:
-      rb_thread_interrupt();
+      rb_interrupt();
       break;
 #ifdef SIGHUP
     case SIGHUP:
@@ -522,12 +559,6 @@
     VALUE sig, cmd;
 };
 
-# ifdef HAVE_SIGPROCMASK
-static sigset_t trap_last_mask;
-# else
-static int trap_last_mask;
-# endif
-
 static VALUE
 trap(struct trap_arg *arg)
 {
@@ -789,26 +820,7 @@
     }
 }
 
-#ifdef HAVE_NATIVETHREAD
 static void
-install_nativethread_sighandler(int signum, sighandler_t handler)
-{
-    sighandler_t old;
-    int old_st;
-
-    old_st = rb_trap_accept_nativethreads[signum];
-    old = ruby_nativethread_signal(signum, handler);
-    if (old != SIG_DFL) {
-        if (old_st) {
-            ruby_nativethread_signal(signum, old);
-        } else {
-            ruby_signal(signum, old);
-        }
-    }
-}
-#endif
-
-static void
 init_sigchld(int sig)
 {
     sighandler_t oldfunc;

Modified: trunk/thread.c
===================================================================
--- trunk/thread.c	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/thread.c	2006-05-04 18:34:07 UTC (rev 494)
@@ -52,6 +52,8 @@
 static int rb_thread_dead(yarv_thread_t *th);
 
 void rb_signal_exec(yarv_thread_t *th, int sig);
+void rb_disable_interrupt();
+
 static VALUE eKillSignal = INT2FIX(0);
 static VALUE eTerminateSignal = INT2FIX(1);
 static int system_working = 1;
@@ -132,6 +134,21 @@
     YARV_CHECK_INTS(); \
 } while(0)
 
+
+static void
+rb_thread_interrupt(yarv_thread_t *th)
+{
+    th->interrupt_flag = 1;
+    if (th->status == THREAD_STOPPED) {
+	// (*th->interrupt_function)(th);
+	native_thread_interrupt(th);
+    }
+    else {
+	/* none */
+    }
+}
+
+
 static int
 terminate_i(st_data_t key, st_data_t val, yarv_thread_t *main_thread)
 {
@@ -142,11 +159,7 @@
     if (th != main_thread) {
 	thread_debug("terminate_i: %p\n", th);
 	th->throwed_errinfo = eTerminateSignal;
-	th->interrupt_flag = 1;
-
-	if (th->status == THREAD_STOPPED) {
-	    native_thread_interrupt(th);
-	}
+	rb_thread_interrupt(th);
 	th->status = THREAD_TO_KILL;
     }
     else {
@@ -174,9 +187,9 @@
 }
 
 
-
 VALUE th_eval_body(yarv_thread_t *th);
 
+
 static void
 thread_cleanup_func(void *th_ptr)
 {
@@ -185,6 +198,7 @@
     th->machine_stack_start = th->machine_stack_end = 0;
 }
 
+
 static int
 thread_start_func_2(yarv_thread_t *th, VALUE *stack_start)
 {
@@ -224,7 +238,7 @@
 	/* wake up joinning threads */
 	join_th = th->join_list_head;
 	while (join_th) {
-	    native_thread_interrupt(join_th);
+	    rb_thread_interrupt(join_th);
 	    join_th = join_th->join_list_next;
 	}
 	st_delete_wrap(th->vm->living_threads, th->self);
@@ -233,6 +247,7 @@
     return 0;
 }
 
+
 static VALUE
 yarv_thread_s_new(VALUE klass, VALUE args)
 {
@@ -284,7 +299,6 @@
 	    }
 	    sleep_wait_for_interrupt(th, limit - now);
 	}
-	
 	thread_debug("yarv_thread_join: interrupted (thid: %p)\n",
 		     target_th->thread_id);
     }
@@ -607,12 +621,9 @@
 	th->interrupt_flag = 0;
 
 	/* signal handling */
-	while (th->signal_queue.head != th->signal_queue.tail) {
-	    int sig = th->signal_queue.buff[th->signal_queue.tail];
-	    // TODO: signal mask
-	    th->signal_queue.tail =
-		(th->signal_queue.tail + 1) % RUBY_SIGNAL_QUEUE_MAX;
-	    rb_signal_exec(th, sig);
+	if (th->exec_signal) {
+	    rb_signal_exec(th, th->exec_signal);
+	    th->exec_signal = 0;
 	}
 
 	/* exception from another thread */
@@ -650,9 +661,7 @@
 static void
 rb_thread_ready(yarv_thread_t *th)
 {
-    if (th->status == THREAD_STOPPED) {
-	native_thread_interrupt(th);
-    }
+    rb_thread_interrupt(th);
 }
 
 static VALUE
@@ -763,11 +772,8 @@
 
     thread_debug("rb_thread_kill: %p (%p)\n", th, th->thread_id);
 
-    if (th->status == THREAD_STOPPED) {
-	native_thread_interrupt(th);
-    }
+    rb_thread_interrupt(th);
     th->throwed_errinfo = eKillSignal;
-    th->interrupt_flag = 1;
     th->status = THREAD_TO_KILL;
 
     return thread;
@@ -1576,12 +1582,17 @@
  *
  */
 
-
 static void
 timer_function(void)
 {
-    // TODO: GET_VM() should not be used
-    GET_THREAD()->vm->running_thread->interrupt_flag = 1;
+    yarv_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */
+    vm->running_thread->interrupt_flag = 1;
+    
+    if (vm->bufferd_signal_size && vm->main_thread->exec_signal == 0) {
+	vm->main_thread->exec_signal = rb_get_next_signal(vm);
+	vm->main_thread->interrupt_flag = 1;
+	rb_thread_interrupt(vm->main_thread);
+    }
 }
 
 /*
@@ -1994,5 +2005,8 @@
 	    native_mutex_lock(lp);
 	}
     }
+
+    make_timer_thread();
+    rb_disable_interrupt(); /* only timer thread recieve signal */
 }
 

Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/thread_pthread.h	2006-05-04 18:34:07 UTC (rev 494)
@@ -52,9 +52,9 @@
 	 thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
 void static thread_cleanup_func(void *th_ptr);
 
-static void register_cached_thread_and_wait(volatile yarv_thread_t **th);
+static yarv_thread_t *register_cached_thread_and_wait(void);
 
-#define USE_THREAD_CACHE 0
+#define USE_THREAD_CACHE 1
 
 static void *
 thread_start_func_1(void *th_ptr)
@@ -77,11 +77,10 @@
 #if USE_THREAD_CACHE
     if (1) {
 	/* cache thread */
-	volatile yarv_thread_t * th = 0;
-	register_cached_thread_and_wait(&th);
-	if (th != 0) {
-	    pritnf("!\n");
+	yarv_thread_t *th;
+	if ((th = register_cached_thread_and_wait()) != 0) {
 	    th_ptr = (void *)th;
+	    th->thread_id = pthread_self();
 	    goto thread_start;
 	}
     }
@@ -101,33 +100,31 @@
 
 struct cached_thread_entry *cached_thread_root;
 
-static void
-register_cached_thread_and_wait(volatile yarv_thread_t **th_area)
+static yarv_thread_t *
+register_cached_thread_and_wait(void)
 {
     pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-    
+    volatile yarv_thread_t *th_area = 0;
     struct cached_thread_entry *entry =
       (struct cached_thread_entry *)malloc(sizeof(struct cached_thread_entry));
     
     struct timespec tm = {
-	time(0) + 60, 0,
+	time(0) + 60 /* 60 seconds */, 0,
     };
     
     pthread_mutex_lock(&thread_cache_lock);
     {
-	entry->th_area = th_area;
+	entry->th_area = &th_area;
 	entry->cond = &cond;
 	entry->next = cached_thread_root;
 	cached_thread_root = entry;
-    }
-    
-    pthread_cond_timedwait(&cond, &thread_cache_lock, &tm);
-    
-    {
-	struct cached_thread_entry *e = cached_thread_root;
-	struct cached_thread_entry *prev = cached_thread_root;
 
-	if (*th_area == 0) {
+	pthread_cond_timedwait(&cond, &thread_cache_lock, &tm);
+
+	{
+	    struct cached_thread_entry *e = cached_thread_root;
+	    struct cached_thread_entry *prev = cached_thread_root;
+
 	    while (e) {
 		if (e == entry) {
 		    if (prev == cached_thread_root) {
@@ -142,12 +139,14 @@
 		e = e->next;
 	    }
 	}
+	free(entry);
+	pthread_cond_destroy(&cond);
     }
-    free(entry);
     pthread_mutex_unlock(&thread_cache_lock);
+
+    return (yarv_thread_t *)th_area;
 }
 
-
 static int
 use_cached_thread(yarv_thread_t *th)
 {
@@ -177,24 +176,19 @@
     int err = 0;
 
     if (use_cached_thread(th)) {
+	thread_debug("create (use cahced thread): %p\n", th);
     }
     else {
 	pthread_attr_t attr;
 	size_t stack_size = 4 * 1024 - sizeof(int);	/* 4KB */
-	static int init = 0;
 
-	if (!init) {
-	    make_timer_thread();
-	}
-
 	thread_debug("create: %p, stack size: %ld\n", th, stack_size);
 
 	pthread_attr_init(&attr);
 	pthread_attr_setstacksize(&attr, stack_size);
-	pthread_attr_setdetachstate(&attr, 1);
+	pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
-	//
-
 	err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
 
 	if (err != 0) {
@@ -327,7 +321,7 @@
 #ifdef HAVE_NANOSLEEP
 	struct timespec req, rem;
 	req.tv_sec = 0;
-	req.tv_nsec = 10 * 1000;	/* 10 ms */
+	req.tv_nsec = 10 * 1000 * 1000;	/* 10 ms */
 	nanosleep(&req, &rem);
 #else
 	struct timeval tv;

Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/thread_win32.h	2006-05-04 18:34:07 UTC (rev 494)
@@ -221,12 +221,7 @@
 native_thread_create(yarv_thread_t *th)
 {
     size_t stack_size = 4 * 1024 - sizeof(int);	/* 4KB */
-    static int init = 0;
 
-    if (!init) {
-	make_timer_thread();
-    }
-
     if ((th->thread_id =
 	 w32_create_thread(stack_size, thread_start_func_1, th))
 	== 0) {

Modified: trunk/yarv.h
===================================================================
--- trunk/yarv.h	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/yarv.h	2006-05-04 18:34:07 UTC (rev 494)
@@ -39,6 +39,7 @@
     return yarvCurrentThread;
 }
 
+#define GET_VM()     theYarvVM
 #define GET_THREAD() yarvCurrentThread
 
 static inline void

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/yarvcore.h	2006-05-04 18:34:07 UTC (rev 494)
@@ -28,6 +28,18 @@
 #error "unsupported thread type"
 #endif
 
+#include <signal.h>
+
+#ifndef NSIG
+# ifdef DJGPP
+#  define NSIG SIGMAX
+# else
+#  define NSIG (_SIGMAX + 1)      /* For QNX */
+# endif
+#endif
+
+#define RUBY_NSIG NSIG
+
 /*****************/
 /* configuration */
 /*****************/
@@ -285,7 +297,7 @@
 
 struct yarv_thread_struct;
 
-typedef struct {
+typedef struct yarv_vm_struct {
     VALUE self;
 
     yarv_thread_lock_t global_interpreter_lock;
@@ -301,10 +313,11 @@
     int exit_code;
     unsigned long trace_flag;
 
-
     /* object management */
     VALUE mark_object_ary;
-    
+
+    int signal_buff[RUBY_NSIG];
+    int bufferd_signal_size;
 } yarv_vm_t;
 
 typedef struct {
@@ -360,8 +373,6 @@
     struct yarv_tag *prev;
 };
 
-#define RUBY_SIGNAL_QUEUE_MAX 16
-
 typedef struct yarv_thread_struct {
     VALUE self;
     yarv_vm_t *vm;
@@ -400,18 +411,13 @@
     VALUE errinfo;
     VALUE throwed_errinfo;
     int interrupt_flag;
+    int exec_signal;
     struct yarv_tag *tag;
 
     int parse_in_eval;
 
     st_table *local_storage;	/* thread local storage */
 
-    struct {
-	int buff[RUBY_SIGNAL_QUEUE_MAX];
-	int head;
-	int tail;
-    } signal_queue;
-
     struct yarv_thread_struct *join_list_next;
     struct yarv_thread_struct *join_list_head;
     

Modified: trunk/yarvtest/test_thread.rb
===================================================================
--- trunk/yarvtest/test_thread.rb	2006-05-03 15:34:08 UTC (rev 493)
+++ trunk/yarvtest/test_thread.rb	2006-05-04 18:34:07 UTC (rev 494)
@@ -31,7 +31,7 @@
 
   def test_create_many_threads2
     ae %q{
-      10000.times{|e|
+      2000.times{|e|
         (1..2).map{
           Thread.new{
           }


-- 
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]