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

yarv-diff:328

From: ko1 atdot.net
Date: 4 May 2006 18:35:00 -0000
Subject: [yarv-diff:328] r495 - in trunk: . lib yarvtest

Author: ko1
Date: 2006-05-05 03:35:00 +0900 (Fri, 05 May 2006)
New Revision: 495

Modified:
   trunk/
   trunk/ChangeLog
   trunk/common.mk
   trunk/disasm.c
   trunk/lib/monitor.rb
   trunk/lib/mutex_m.rb
   trunk/lib/singleton.rb
   trunk/lib/tempfile.rb
   trunk/lib/thread.rb
   trunk/lib/weakref.rb
   trunk/signal.c
   trunk/thread.c
   trunk/thread_pthread.h
   trunk/thread_win32.h
   trunk/yarvcore.c
   trunk/yarvcore.h
   trunk/yarvtest/test_thread.rb
Log:
 r765@lermite:  ko1 | 2006-05-05 03:32:40 +0900
 	* common.mk : vtune rule make run test.rb
 
 	* disasm.c : fix syntax errors (on VC)
 
 	* yarvcore.c : ditto
 
 	* lib/thread.rb : Mutex#synchronize is defined here
 
 	* lib/*.rb : ditto
 
 	* signal.c : separate pthread or not
 
 	* thread.c : support lightweight wakeup
 
 	* thread_pthread.h : ditto
 
 	* thread_win32.h : ditto
 
 	* yarvcore.h : ditto
 
 	* yarvtest/test_thread.rb : restore last change
 



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

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/ChangeLog	2006-05-04 18:35:00 UTC (rev 495)
@@ -4,6 +4,31 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2006-05-05(Fri) 03:03:22 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* common.mk : vtune rule make run test.rb
+
+	* disasm.c : fix syntax errors (on VC)
+
+	* yarvcore.c : ditto
+
+	* lib/thread.rb : Mutex#synchronize is defined here
+
+	* lib/*.rb : ditto
+
+	* signal.c : separate pthread or not
+
+	* thread.c : support lightweight wakeup
+
+	* thread_pthread.h : ditto
+
+	* thread_win32.h : ditto
+
+	* yarvcore.h : ditto
+
+	* yarvtest/test_thread.rb : restore last change
+
+
 2006-05-04(Thu) 18:11:43 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* eval_thread.c : remove rb_thread_interrupt

Modified: trunk/common.mk
===================================================================
--- trunk/common.mk	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/common.mk	2006-05-04 18:35:00 UTC (rev 495)
@@ -469,7 +469,7 @@
 # Intel VTune
 
 vtune: miniruby$(EXEEXT)
-	vtl activity -c sampling -app ".\miniruby$(EXEEXT)","-I$(srcdir)/lib $(srcdir)/benchmark/bmx_temp.rb" run
+	vtl activity -c sampling -app ".\miniruby$(EXEEXT)","-I$(srcdir)/lib $(srcdir)/test.rb" run
 	vtl view -hf -mn miniruby$(EXEEXT) -sum -sort -cd
 	vtl view -ha -mn miniruby$(EXEEXT) -sum -sort -cd | $(BASERUBY) $(srcdir)/rb/vtlh.rb > ha.lines
 

Modified: trunk/disasm.c
===================================================================
--- trunk/disasm.c	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/disasm.c	2006-05-04 18:35:00 UTC (rev 495)
@@ -570,7 +570,8 @@
 }
 
 #define DECL_SYMBOL(name) \
-  static VALUE sym_##name;
+  static VALUE sym_##name
+
 #define INIT_SYMBOL(name) \
   sym_##name = ID2SYM(rb_intern(#name))
 
@@ -616,6 +617,7 @@
     VALUE nbody;
     VALUE line = rb_ary_new();
     VALUE exception = rb_ary_new(); /* [[....]] */
+    
     static VALUE insn_syms[YARV_MAX_INSTRUCTION_SIZE];
     struct st_table *labels_table = st_init_numtable();
     
@@ -784,8 +786,8 @@
 insn_make_insn_table(void)
 {
     struct st_table *table;
+    int i;
     table = st_init_numtable();
-    int i;
 
     for (i=0; i<YARV_MAX_INSTRUCTION_SIZE; i++) {
 	st_insert(table, ID2SYM(rb_intern(insn_name(i))), i);

Modified: trunk/lib/monitor.rb
===================================================================
--- trunk/lib/monitor.rb	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/monitor.rb	2006-05-04 18:35:00 UTC (rev 495)
@@ -41,8 +41,9 @@
 empty_cond.signal.
 
 =end
-  
 
+require 'thread'
+
 #
 # Adds monitor functionality to an arbitrary object by mixing the module with
 # +include+.  For example:

Modified: trunk/lib/mutex_m.rb
===================================================================
--- trunk/lib/mutex_m.rb	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/mutex_m.rb	2006-05-04 18:35:00 UTC (rev 495)
@@ -24,6 +24,8 @@
 #	this obj can be handled like Mutex
 #
 
+require 'thread'
+
 module Mutex_m
   def Mutex_m.define_aliases(cl)
     cl.module_eval %q{

Modified: trunk/lib/singleton.rb
===================================================================
--- trunk/lib/singleton.rb	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/singleton.rb	2006-05-04 18:35:00 UTC (rev 495)
@@ -60,6 +60,8 @@
 #    and _dump(depth) hooks allows the (partially) resurrections of
 #    a previous state of ``the instance''.
 
+require 'thread'
+
 module Singleton
   #  disable build-in copying methods
   def clone

Modified: trunk/lib/tempfile.rb
===================================================================
--- trunk/lib/tempfile.rb	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/tempfile.rb	2006-05-04 18:35:00 UTC (rev 495)
@@ -6,6 +6,7 @@
 
 require 'delegate'
 require 'tmpdir'
+require 'thread'
 
 # A class for managing temporary files.  This library is written to be
 # thread safe.

Modified: trunk/lib/thread.rb
===================================================================
--- trunk/lib/thread.rb	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/thread.rb	2006-05-04 18:35:00 UTC (rev 495)
@@ -21,6 +21,15 @@
   Thread.abort_on_exception = true
 end
 
+class Mutex
+  def synchronize
+    self.lock
+    yield
+  ensure
+    self.unlock
+  end
+end
+
 # 
 # ConditionVariable objects augment class Mutex. Using condition variables,
 # it is possible to suspend while in the middle of a critical section until a

Modified: trunk/lib/weakref.rb
===================================================================
--- trunk/lib/weakref.rb	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/weakref.rb	2006-05-04 18:35:00 UTC (rev 495)
@@ -10,6 +10,7 @@
 #   p foo.to_s			# should raise exception (recycled)
 
 require "delegate"
+require 'thread'
 
 class WeakRef < Delegator
 

Modified: trunk/signal.c
===================================================================
--- trunk/signal.c	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/signal.c	2006-05-04 18:35:00 UTC (rev 495)
@@ -403,20 +403,19 @@
 static int trap_last_mask;
 # endif
 
+
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#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
+    pthread_sigmask(SIG_SETMASK, &mask, NULL);
     trap_last_mask = mask;
 #endif
 }
@@ -424,7 +423,9 @@
 static void
 rb_enable_interrupt(void)
 {
-    rb_trap_restore_mask();
+#ifndef _WIN32
+    pthread_sigmask(SIG_SETMASK, &trap_last_mask, NULL);
+#endif
 }
 
 int

Modified: trunk/thread.c
===================================================================
--- trunk/thread.c	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/thread.c	2006-05-04 18:35:00 UTC (rev 495)
@@ -44,7 +44,7 @@
 #define THREAD_DEBUG 0
 
 static void sleep_for_polling();
-static int sleep_timeval(yarv_thread_t *th, struct timeval time);
+static void sleep_timeval(yarv_thread_t *th, struct timeval time);
 static void sleep_wait_for_interrupt(yarv_thread_t *th, double sleepsec);
 static void sleep_forever(yarv_thread_t *th);
 static double timeofday();
@@ -68,6 +68,27 @@
 
 #define THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
 
+static void native_thread_interrupt(yarv_thread_t *th);
+static void yarv_set_interrupt_function(yarv_thread_t *th, yarv_interrupt_function_t *func, int is_return);
+static void yarv_clear_interrupt_function(yarv_thread_t *th);
+
+#define GVL_UNLOCK_RANGE(exec) do { \
+    yarv_thread_t *__th = GET_THREAD(); \
+    int __prev_status = __th->status; \
+    yarv_set_interrupt_function(__th, native_thread_interrupt, 0); \
+    __th->status = THREAD_STOPPED; \
+    GVL_UNLOCK_BEGIN(); {\
+	    exec; \
+    } \
+    GVL_UNLOCK_END(); \
+    yarv_remove_signal_thread_list(__th); \
+    yarv_clear_interrupt_function(__th); \
+    if (__th->status == THREAD_STOPPED) { \
+	__th->status = __prev_status; \
+    } \
+    YARV_CHECK_INTS(); \
+} while(0)
+
 #if THREAD_DEBUG
 void thread_debug(const char *fmt, ...);
 #else
@@ -118,34 +139,48 @@
 #endif
 
 
-#define GVL_UNLOCK_RANGE(exec) do { \
-    yarv_thread_t *__th = GET_THREAD(); \
-    int __prev_status = __th->status; \
-    YARV_CHECK_INTS(); \
-    __th->status = THREAD_STOPPED; \
-    GVL_UNLOCK_BEGIN(); {\
-	exec; \
-    } \
-    GVL_UNLOCK_END(); \
-    yarv_remove_signal_thread_list(__th); \
-    if (__th->status == THREAD_STOPPED) { \
-	__th->status = __prev_status; \
-    } \
-    YARV_CHECK_INTS(); \
-} while(0)
+static void
+yarv_set_interrupt_function(yarv_thread_t *th, yarv_interrupt_function_t *func, int is_return)
+{
+  check_ints:
+    YARV_CHECK_INTS();
+    native_mutex_lock(&th->interrupt_lock);
+    if (th->interrupt_flag) {
+	native_mutex_unlock(&th->interrupt_lock);
+	if (is_return) {
+	    return;
+	}
+	else {
+	    goto check_ints;
+	}
+    }
+    else {
+	th->interrupt_function = func;
+    }
+    native_mutex_unlock(&th->interrupt_lock);
+}
 
+static void
+yarv_clear_interrupt_function(yarv_thread_t *th)
+{
+    native_mutex_lock(&th->interrupt_lock);
+    th->interrupt_function = 0;
+    native_mutex_unlock(&th->interrupt_lock);
+}
 
 static void
 rb_thread_interrupt(yarv_thread_t *th)
 {
+    native_mutex_lock(&th->interrupt_lock);
     th->interrupt_flag = 1;
-    if (th->status == THREAD_STOPPED) {
-	// (*th->interrupt_function)(th);
-	native_thread_interrupt(th);
+
+    if (th->interrupt_function) {
+	(th->interrupt_function)(th);
     }
     else {
 	/* none */
     }
+    native_mutex_unlock(&th->interrupt_lock);
 }
 
 
@@ -158,8 +193,8 @@
 
     if (th != main_thread) {
 	thread_debug("terminate_i: %p\n", th);
-	th->throwed_errinfo = eTerminateSignal;
 	rb_thread_interrupt(th);
+	th->throwed_errinfo = eTerminateSignal;
 	th->status = THREAD_TO_KILL;
     }
     else {
@@ -174,7 +209,7 @@
     yarv_thread_t *th = GET_THREAD(); /* main thread */
     yarv_vm_t *vm = th->vm;
     if (vm->main_thread != th) {
-	rb_bug("rb_thread_terminate_all: called by child thread");
+	rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)", vm->main_thread, th);
     }
 
     thread_debug("rb_thread_terminate_all (main thread: %p)\n", th);
@@ -262,6 +297,8 @@
     th->first_args = args;
     th->first_proc = rb_block_proc();
 
+    native_mutex_initialize(&th->interrupt_lock);
+
     /* kick thread */
     native_thread_create(th);
     st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
@@ -403,16 +440,6 @@
  * Thread Scheduling
  */
 
-#if !defined(HAVE_PAUSE) || defined(__CYGWIN__)
-# if defined(_WIN32) || defined(__CYGWIN__)
-#  define pause(th) w32_sleep(th, INFINITE)
-# else
-#  define pause(th) sleep(0x7fffffff)
-# endif
-#else
-#define pause(th) pause()
-#endif
-
 static struct timeval
 double2timeval(double d)
 {
@@ -430,13 +457,20 @@
 static void
 sleep_forever(yarv_thread_t *th)
 {
-    thread_debug("rb_thread_sleep_forever\n");
-    GVL_UNLOCK_RANGE(pause(th));
+    native_sleep(th, 0);
+    YARV_CHECK_INTS();
 }
 
+static void
+sleep_timeval(yarv_thread_t *th, struct timeval tv)
+{
+    native_sleep(th, &tv);
+}
+
 void
 rb_thread_sleep_forever()
 {
+    thread_debug("rb_thread_sleep_forever\n");
     sleep_forever(GET_THREAD());
 }
 
@@ -448,29 +482,6 @@
     return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
 }
 
-static int
-sleep_timeval(yarv_thread_t *th, struct timeval time)
-{
-#if defined(_WIN32) || defined(__CYGWIN__)
-    DWORD limit = time.tv_sec * 1000 + time.tv_usec / 1000;
-    thread_debug("sleep_timeval - sleep start\n");
-    w32_sleep(th, limit);
-    thread_debug("sleep_timeval - sleep end\n");
-    return 0;
-#else
-    thread_debug("sleep_timeval\n");
-    {
-	int n = select(0, 0, 0, 0, &time);
-	if (n == 0) {
-	    return 0;
-	}
-	else {
-	    return errno;
-	}
-    }
-#endif
-}
-
 static void
 sleep_wait_for_interrupt(yarv_thread_t *th, double sleepsec)
 {
@@ -482,7 +493,7 @@
 {
     struct timeval time;
     time.tv_sec = 0;
-    time.tv_usec = 100000;	/* 0.1 sec */
+    time.tv_usec = 100 * 1000;	/* 0.1 sec */
     sleep_timeval(th, time);
 }
 
@@ -490,33 +501,7 @@
 rb_thread_wait_for(struct timeval time)
 {
     yarv_thread_t *th = GET_THREAD();
-    double d, limit;
-    limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6;
-    thread_debug("rb_thread_wait_for\n");
-
-    while (1) {
-	int ret;
-	GVL_UNLOCK_RANGE(ret = sleep_timeval(th, time));
-
-	switch (ret) {
-	  case 0:
-	    return;
-	  case EINTR:
-#ifdef ERESTART
-	  case ERESTART:
-#endif
-	    break;
-	  default:
-	    rb_sys_fail("rb_thread_wait_for");
-	}
-
-	/* prepare to restart */
-	d = limit - timeofday();
-	time = double2timeval(d);
-	if (time.tv_sec < 0) {
-	    return;
-	}
-    }
+    sleep_timeval(th, time);
 }
 
 void
@@ -524,7 +509,7 @@
 {
     if (!rb_thread_alone()) {
 	yarv_thread_t *th = GET_THREAD();
-	GVL_UNLOCK_RANGE(sleep_for_polling(th));
+	sleep_for_polling(th);
     }
 }
 
@@ -557,6 +542,7 @@
     }
 }
 
+
 static VALUE
 rb_thread_s_critical(VALUE self)
 {
@@ -606,7 +592,6 @@
     return Qnil;
 }
 
-
 /*
  *
  */
@@ -614,7 +599,6 @@
 void
 yarv_thread_execute_interrupts(yarv_thread_t *th)
 {
-
     while (th->interrupt_flag) {
 	int status = th->status;
 	th->status = THREAD_RUNNABLE;
@@ -622,8 +606,9 @@
 
 	/* signal handling */
 	if (th->exec_signal) {
-	    rb_signal_exec(th, th->exec_signal);
+	    int sig = th->exec_signal;
 	    th->exec_signal = 0;
+	    rb_signal_exec(th, sig);
 	}
 
 	/* exception from another thread */
@@ -631,7 +616,7 @@
 	    VALUE err = th->throwed_errinfo;
 	    th->throwed_errinfo = 0;
 	    thread_debug("yarv_thread_execute_interrupts: %p\n", err);
-	    
+
 	    if (err == eKillSignal) {
 		th->errinfo = INT2FIX(TAG_FATAL);
 		TH_JUMP_TAG(th, TAG_FATAL);
@@ -651,8 +636,8 @@
 		rb_exc_raise(err);
 	    }
 	}
-
 	th->status = status;
+
 	/* thread pass */
 	rb_thread_schedule();
     }
@@ -676,10 +661,7 @@
     exc = rb_make_exception(argc, argv);
     // TODO: need synchronization if run threads in parallel
     th->throwed_errinfo = exc;
-    th->interrupt_flag = 1;
-
     rb_thread_ready(th);
-
     return Qnil;
 }
 
@@ -842,7 +824,6 @@
     if (th->status == THREAD_KILLED) {
 	rb_raise(rb_eThreadError, "killed thread");
     }
-
     rb_thread_ready(th);
     return thread;
 }
@@ -905,11 +886,9 @@
 		 "stopping only thread\n\tnote: use sleep to stop forever");
     }
     rb_thread_sleep_forever();
-
     return Qnil;
 }
 
-
 static int
 thread_list_i(st_data_t key, st_data_t val, void *data)
 {
@@ -1590,7 +1569,8 @@
     
     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;
+	thread_debug("bufferd_signal_size: %d, sig: %d\n",
+		     vm->bufferd_signal_size, vm->main_thread->exec_signal);
 	rb_thread_interrupt(vm->main_thread);
     }
 }
@@ -1906,24 +1886,6 @@
     return self;
 }
 
-static VALUE
-mutex_synchronize(VALUE self)
-{
-    int state;
-    VALUE val;
-    
-    mutex_lock(self);
-    PUSH_TAG(PROTO_NONE);
-    if ((state = EXEC_TAG()) == 0) {
-	val = rb_yield(Qnil);
-    }
-    mutex_unlock(self);
-    POP_TAG();
-    if (state) {
-	JUMP_TAG(state);
-    }
-    return val;
-}
 
 void
 Init_yarvthread()
@@ -1993,7 +1955,6 @@
     rb_define_method(cMutex, "lock", mutex_lock, 0);
     rb_define_method(cMutex, "unlock", mutex_unlock, 0);
     rb_define_method(cMutex, "unlock_and_stop", mutex_unlock_and_stop, 0);
-    rb_define_method(cMutex, "synchronize", mutex_synchronize, 0);
 
     Init_native_thread();
     {
@@ -2003,6 +1964,7 @@
 	    yarv_thread_lock_t *lp = &GET_THREAD()->vm->global_interpreter_lock;
 	    native_mutex_initialize(lp);
 	    native_mutex_lock(lp);
+	    native_mutex_initialize(&GET_THREAD()->interrupt_lock);
 	}
     }
 

Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/thread_pthread.h	2006-05-04 18:35:00 UTC (rev 495)
@@ -12,6 +12,7 @@
 
 typedef struct native_thread_data_struct {
     void *signal_thread_list;
+    pthread_cond_t sleep_cond;
 } native_thread_data_t;
 
 #endif /* THREAD_PTHREAD_H_INCLUDED */
@@ -54,7 +55,7 @@
 
 static yarv_thread_t *register_cached_thread_and_wait(void);
 
-#define USE_THREAD_CACHE 1
+#define USE_THREAD_CACHE 0
 
 static void *
 thread_start_func_1(void *th_ptr)
@@ -107,11 +108,13 @@
     volatile yarv_thread_t *th_area = 0;
     struct cached_thread_entry *entry =
       (struct cached_thread_entry *)malloc(sizeof(struct cached_thread_entry));
+
+    struct timeval tv;
+    struct timespec ts;
+    gettimeofday(&tv, 0);
+    ts.tv_sec = tv.tv_sec + 60;
+    ts.tv_nsec = tv.tv_usec * 1000;
     
-    struct timespec tm = {
-	time(0) + 60 /* 60 seconds */, 0,
-    };
-    
     pthread_mutex_lock(&thread_cache_lock);
     {
 	entry->th_area = &th_area;
@@ -119,7 +122,7 @@
 	entry->next = cached_thread_root;
 	cached_thread_root = entry;
 
-	pthread_cond_timedwait(&cond, &thread_cache_lock, &tm);
+	pthread_cond_timedwait(&cond, &thread_cache_lock, &ts);
 
 	{
 	    struct cached_thread_entry *e = cached_thread_root;
@@ -139,6 +142,7 @@
 		e = e->next;
 	    }
 	}
+
 	free(entry);
 	pthread_cond_destroy(&cond);
     }
@@ -222,6 +226,13 @@
 }
 
 static void
+interrupt_using_pthread_cond_signal(yarv_thread_t *th)
+{
+    thread_debug("interrupt_using_pthread_cond_signal (%p)\n", th);
+    pthread_cond_signal(&th->native_thread_data.sleep_cond);
+}
+
+static void
 native_thread_send_interrupt_signal(yarv_thread_t *th)
 {
     thread_debug("native_thread_send_interrupt_signal (%p)\n", th->thread_id);
@@ -230,6 +241,51 @@
     }
 }
 
+static void
+native_sleep(yarv_thread_t *th, struct timeval *tv)
+{
+    int prev_status = th->status;
+    struct timespec ts;
+    struct timeval tvn;
+
+    if (tv) {
+	gettimeofday(&tvn, NULL);
+	ts.tv_sec = tvn.tv_sec + tv->tv_sec;
+	ts.tv_nsec = (tvn.tv_usec + tv->tv_usec) * 1000;
+    }
+    
+    th->status = THREAD_STOPPED;
+    pthread_cond_init(&th->native_thread_data.sleep_cond, 0);
+
+    GVL_UNLOCK_BEGIN();
+    {
+	pthread_mutex_lock(&th->interrupt_lock);
+	
+	if (th->interrupt_flag) {
+	    /* interrupted.  return immediate */
+	}
+	else {
+	    th->interrupt_function = interrupt_using_pthread_cond_signal;
+	    if (tv == 0) {
+		thread_debug("native_sleep: pthread_cond_wait start\n");
+		pthread_cond_wait(&th->native_thread_data.sleep_cond, &th->interrupt_lock);
+		thread_debug("native_sleep: pthread_cond_wait end\n");
+	    }
+	    else {
+		int r;
+		thread_debug("native_sleep: pthread_cond_timedwait start (%d, %d)\n", ts.tv_sec, ts.tv_nsec);
+		r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond, &th->interrupt_lock, &ts);
+		thread_debug("native_sleep: pthread_cond_timedwait end (%d)\n", r);
+	    }
+	    th->interrupt_function = 0;
+	}
+	pthread_mutex_unlock(&th->interrupt_lock);
+
+	th->status = prev_status;
+    }
+    GVL_UNLOCK_END();
+}
+
 void
 native_thread_interrupt(yarv_thread_t *th)
 {
@@ -340,7 +396,6 @@
 		}
 	    });
 	}
-
 	timer_function();
     }
     return NULL;

Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/thread_win32.h	2006-05-04 18:35:00 UTC (rev 495)
@@ -79,6 +79,7 @@
 
     if (th) {
 	HANDLE intr = th->native_thread_data.interrupt_event;
+	ResetEvent(intr);
 	
 	if (th->interrupt_flag) {
 	    SetEvent(intr);
@@ -106,12 +107,22 @@
 }
 
 static void
-w32_sleep(yarv_thread_t *th, DWORD msec)
+native_sleep(yarv_thread_t *th, struct timeval *tv)
 {
-    DWORD ret;
-    thread_debug("w32_sleep start\n");
-    ret = w32_wait_event(0, msec, th);
-    thread_debug("w32_sleep done (%d)\n", ret);
+    DWORD msec;
+    if (tv) {
+	msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+    }
+    else {
+	msec = INFINITE;
+    }
+
+    GVL_UNLOCK_RANGE({
+	DWORD ret;
+	thread_debug("native_sleep start (%d)\n", (int)msec);
+	ret = w32_wait_event(0, msec, th);
+	thread_debug("native_sleep done (%d)\n", ret);
+    });
 }
 
 int
@@ -253,7 +264,7 @@
     SetThreadPriority(th->thread_id, priority);
 }
 
-void
+static void
 native_thread_interrupt(yarv_thread_t *th)
 {
     thread_debug("native_thread_interrupt: %p\n", th);

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/yarvcore.c	2006-05-04 18:35:00 UTC (rev 495)
@@ -475,6 +475,7 @@
 
     VALUE iseq_type;
     struct st_table *type_map = 0;
+    yarv_iseq_t *iseq;
 
     /* [magic, major_version, minor_version, format_type, misc,
      *  name, filename, line,
@@ -499,7 +500,6 @@
     exception = rb_ary_entry(data, 11);
     body = rb_ary_entry(data, 12);
 
-    yarv_iseq_t *iseq;
     GetISeqVal(iseqval, iseq);
     iseq->self = iseqval;
 

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/yarvcore.h	2006-05-04 18:35:00 UTC (rev 495)
@@ -373,7 +373,10 @@
     struct yarv_tag *prev;
 };
 
-typedef struct yarv_thread_struct {
+typedef void yarv_interrupt_function_t(struct yarv_thread_struct *);
+
+typedef struct yarv_thread_struct
+{
     VALUE self;
     yarv_vm_t *vm;
 
@@ -410,8 +413,12 @@
 
     VALUE errinfo;
     VALUE throwed_errinfo;
+    int exec_signal;
+
     int interrupt_flag;
-    int exec_signal;
+    yarv_interrupt_function_t *interrupt_function;
+    yarv_thread_lock_t interrupt_lock;
+
     struct yarv_tag *tag;
 
     int parse_in_eval;
@@ -420,7 +427,7 @@
 
     struct yarv_thread_struct *join_list_next;
     struct yarv_thread_struct *join_list_head;
-    
+
     VALUE first_proc;
     VALUE first_args;
 

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


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

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