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

yarv-diff:112

From: ko1 atdot.net
Date: 30 Sep 2005 11:12:25 -0000
Subject: [yarv-diff:112] r268 - trunk

Author: ko1
Date: 2005-09-30 20:12:25 +0900 (Fri, 30 Sep 2005)
New Revision: 268

Modified:
   trunk/ChangeLog
   trunk/test.rb
   trunk/thread.c
   trunk/yarvcore.h
Log:
	* thread.c : support join with timeout

	* yarvcore.h : use GET_VM()



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-09-30 06:08:45 UTC (rev 267)
+++ trunk/ChangeLog	2005-09-30 11:12:25 UTC (rev 268)
@@ -4,6 +4,13 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-09-30(Fri) 20:11:19 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* thread.c : support join with timeout
+
+	* yarvcore.h : use GET_VM()
+
+
 2005-09-30(Fri) 14:59:29 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* thread.c, common.mk : add thread.c

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-09-30 06:08:45 UTC (rev 267)
+++ trunk/test.rb	2005-09-30 11:12:25 UTC (rev 268)
@@ -1,4 +1,11 @@
 
+Thread.new{
+  sleep
+}.join(10)
+
+p :finish
+exit
+__END__
 10.times{|e|
   Thread.new(e){|le|
     10000.times{|i|

Modified: trunk/thread.c
===================================================================
--- trunk/thread.c	2005-09-30 06:08:45 UTC (rev 267)
+++ trunk/thread.c	2005-09-30 11:12:25 UTC (rev 268)
@@ -48,6 +48,10 @@
 #define thead_debug if(0)printf
 #endif
 
+static void sleep_for_polling();
+static void sleep_timeval(struct timeval time);
+static double timeofday();
+struct timeval rb_time_interval(VALUE);
 
 /********************************************************************************/
 
@@ -157,15 +161,42 @@
   if(th->status == THREAD_KILLED){
     return self;
   }
-  
-  GIL_UNLOCK_BEGIN();
-  err = native_thread_join(th->thread_id, 0);
-  GIL_UNLOCK_END();
 
-  switch(err){
-  case EDEADLK:
-    rb_raise(rb_eThreadError, "can't join current thread (cause dead lock)");
+  if(argc == 0){
+    GIL_UNLOCK_BEGIN();
+    err = native_thread_join(th->thread_id, 0);
+    GIL_UNLOCK_END();
+
+    switch(err){
+    case EDEADLK:
+      rb_raise(rb_eThreadError, "can't join current thread (cause dead lock)");
+    }
   }
+  else if(argc == 1){
+    double limit = timeofday();
+    struct timeval interval;
+    
+    interval = rb_time_interval(argv[0]);
+    limit += interval.tv_sec;
+    limit += interval.tv_usec * 1e-6;
+    
+    while(1){
+      GIL_UNLOCK_BEGIN();
+      sleep_for_polling();
+      GIL_UNLOCK_END();
+      
+      if(th->status == THREAD_KILLED){
+        break;
+      }
+      if(timeofday() > limit){
+        /* timeout */
+        return Qnil;
+      }
+    }
+  }
+  else{
+    
+  }
   return self;
 }
 
@@ -237,6 +268,14 @@
   }
 }
 
+static void
+sleep_for_polling(){
+  struct timeval time;
+  time.tv_sec  = 0;
+  time.tv_usec = 100000; /* 0.1 sec */
+  sleep_timeval(time);
+}
+
 void
 rb_thread_wait_for(struct timeval time)
 {
@@ -249,6 +288,54 @@
   CSL_UNLOCK_END();
 }
 
+void
+yarv_thraed_schedule()
+{
+  if(GET_VM()->thread_critical == 0){
+    yarv_thread_t *th = GET_THREAD(); 
+    yarv_save_machine_context(th);
+    native_mutex_unlock(&GET_VM()->global_interpreter_lock);
+    native_mutex_lock(&GET_VM()->global_interpreter_lock);
+    yarv_set_current_running_thread(th);
+  }
+}
+
+#if HAVE_PTHREAD_H
+static pthread_t time_thread;
+
+static void*
+thread_timer(void *dummy)
+{
+  while(1){
+#ifdef HAVE_NANOSLEEP
+    struct timespec req, rem;
+
+    req.tv_sec = 0;
+    req.tv_nsec = 10000000;
+    nanosleep(&req, &rem);
+#else
+    struct timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = 10000;
+    select(0, NULL, NULL, NULL, &tv);
+#endif
+    GET_VM()->interrupt_flag = 1;
+  }
+}
+
+void make_timer_thread()
+{
+  if(!time_thread){
+    pthread_create(&time_thread, 0, thread_timer, 0);
+  }
+}
+
+#else
+#error "unsupported"
+#endif /* HAVE_PTHREAD_H */
+
+/********************************************************************/
+
 static VALUE
 yarv_thread_s_current(VALUE klass){
   return GET_THREAD()->self;
@@ -259,7 +346,6 @@
   return GET_VM()->main_thread;
 }
 
-
 VALUE
 rb_thread_local_aref(VALUE thread, ID id)
 {
@@ -279,7 +365,6 @@
   return Qnil;
 }
 
-
 /*
  *  call-seq:
  *      thr[sym]   => obj or nil
@@ -339,12 +424,11 @@
  */
 
 static VALUE
-rb_thread_aset(VALUE thread, ID id, VALUE val)
+rb_thread_aset(VALUE self, ID id, VALUE val)
 {
-  return rb_thread_local_aset(thread, rb_to_id(id), val);
+  return rb_thread_local_aset(self, rb_to_id(id), val);
 }
 
-
 /*
  *  call-seq:
  *     thr.key?(sym)   => true or false
@@ -359,10 +443,10 @@
  */
 
 static VALUE
-rb_thread_key_p(VALUE thread, ID id)
+rb_thread_key_p(VALUE self, ID id)
 {
   yarv_thread_t *th;
-  GetThreadVal(thread, th);
+  GetThreadVal(self, th);
   
   if(!th->local_storage){
     return Qfalse;
@@ -396,11 +480,10 @@
  */
 
 static VALUE
-rb_thread_keys(thread)
-    VALUE thread;
+rb_thread_keys(VALUE self)
 {
   yarv_thread_t *th;
-  GetThreadVal(thread, th);
+  GetThreadVal(self, th);
   VALUE ary = rb_ary_new();
 
   if(th->local_storage){
@@ -409,18 +492,6 @@
   return ary;
 }
 
-void
-yarv_thraed_schedule()
-{
-  if(GET_VM()->thread_critical == 0){
-    yarv_thread_t *th = GET_THREAD(); 
-    yarv_save_machine_context(th);
-    native_mutex_unlock(&GET_VM()->global_interpreter_lock);
-    native_mutex_lock(&GET_VM()->global_interpreter_lock);
-    yarv_set_current_running_thread(th);
-  }
-}
-
 static VALUE
 yarv_thread_s_pass(VALUE klass)
 {
@@ -442,28 +513,7 @@
   setjmp(th->machine_regs);
 }
 
-static pthread_t time_thread;
 
-static void*
-thread_timer(void *dummy)
-{
-  for (;;) {
-#ifdef HAVE_NANOSLEEP
-    struct timespec req, rem;
-
-    req.tv_sec = 0;
-    req.tv_nsec = 10000000;
-    nanosleep(&req, &rem);
-#else
-    struct timeval tv;
-    tv.tv_sec = 0;
-    tv.tv_usec = 10000;
-    select(0, NULL, NULL, NULL, &tv);
-#endif
-    theYarvVM->interrupt_flag = 1;
-  }
-}
-
 void
 Init_yarvthread(){
   rb_define_singleton_method(cYarvThread, "new", yarv_thread_s_new, -2);
@@ -480,9 +530,7 @@
   rb_define_method(cYarvThread, "key?", rb_thread_key_p, 1);
   rb_define_method(cYarvThread, "keys", rb_thread_keys, 0);
 
-  if(time_thread == 0){
-    pthread_create(&time_thread, 0, thread_timer, 0);
-  }
+  make_timer_thread();
 
   {
     /* main thread setting */

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-09-30 06:08:45 UTC (rev 267)
+++ trunk/yarvcore.h	2005-09-30 11:12:25 UTC (rev 268)
@@ -486,8 +486,8 @@
 void yarv_thraed_schedule();
 
 #define YARV_CHECK_INTS() do { \
-  if(theYarvVM->interrupt_flag){ \
-    theYarvVM->interrupt_flag = 0; \
+  if(GET_VM()->interrupt_flag){ \
+    GET_VM()->interrupt_flag = 0; \
     /* TODO: trap something event */ \
     yarv_thraed_schedule(); \
   } \


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

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