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

ruby-changes:62923

From: Samuel <ko1@a...>
Date: Mon, 14 Sep 2020 13:44:36 +0900 (JST)
Subject: [ruby-changes:62923] 1a0cfe2839 (master): Improve handling of urgent notification pipe.

https://git.ruby-lang.org/ruby.git/commit/?id=1a0cfe2839

From 1a0cfe28390ce5d46f7b854eaad2b9b979c160de Mon Sep 17 00:00:00 2001
From: Samuel Williams <samuel.williams@o...>
Date: Sun, 6 Sep 2020 14:48:52 +1200
Subject: Improve handling of urgent notification pipe.


diff --git a/test/fiber/scheduler.rb b/test/fiber/scheduler.rb
index fa05daf..b03058a 100644
--- a/test/fiber/scheduler.rb
+++ b/test/fiber/scheduler.rb
@@ -15,11 +15,9 @@ class Scheduler https://github.com/ruby/ruby/blob/trunk/test/fiber/scheduler.rb#L15
     @writable = {}
     @waiting = {}
 
-    @urgent = nil
-
     @lock = Mutex.new
     @locking = 0
-    @ready = []
+    @ready = Array.new
   end
 
   attr :readable
@@ -51,11 +49,17 @@ class Scheduler https://github.com/ruby/ruby/blob/trunk/test/fiber/scheduler.rb#L49
       # puts "writable: #{writable}" if writable&.any?
 
       readable&.each do |io|
-        @readable[io]&.resume
+        if fiber = @readable.delete(io)
+          fiber.resume
+        elsif io == @urgent.first
+          @urgent.first.read_nonblock(1024)
+        end
       end
 
       writable&.each do |io|
-        @writable[io]&.resume
+        if fiber = @writable.delete(io)
+          fiber.resume
+        end
       end
 
       if @waiting.any?
@@ -73,9 +77,6 @@ class Scheduler https://github.com/ruby/ruby/blob/trunk/test/fiber/scheduler.rb#L77
       end
 
       if @ready.any?
-        # Clear out the urgent notification pipe.
-        @urgent.first.read_nonblock(1024)
-
         ready = nil
 
         @lock.synchronize do
@@ -114,9 +115,6 @@ class Scheduler https://github.com/ruby/ruby/blob/trunk/test/fiber/scheduler.rb#L115
 
     Fiber.yield
 
-    @readable.delete(io)
-    @writable.delete(io)
-
     return true
   end
 
@@ -130,10 +128,10 @@ class Scheduler https://github.com/ruby/ruby/blob/trunk/test/fiber/scheduler.rb#L128
   def mutex_unlock(mutex, fiber)
     @lock.synchronize do
       @ready << fiber
+    end
 
-      if @urgent
-        @urgent.last.write('.')
-      end
+    if io = @urgent&.last
+      @urgent.last.write_nonblock('.')
     end
   end
 
diff --git a/thread_sync.c b/thread_sync.c
index cfdd626..9dd3b32 100644
--- a/thread_sync.c
+++ b/thread_sync.c
@@ -264,12 +264,12 @@ do_mutex_lock(VALUE self, int interruptible_p) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L264
             .fiber = fiber
         };
 
-	if (mutex->fiber == fiber) {
-	    rb_raise(rb_eThreadError, "deadlock; recursive locking");
-	}
+        if (mutex->fiber == fiber) {
+            rb_raise(rb_eThreadError, "deadlock; recursive locking");
+        }
 
-        VALUE scheduler = rb_thread_current_scheduler();
-	while (mutex->fiber != fiber) {
+        while (mutex->fiber != fiber) {
+            VALUE scheduler = rb_thread_current_scheduler();
             if (scheduler != Qnil) {
                 list_add_tail(&mutex->waitq, &w.node);
 
@@ -279,52 +279,48 @@ do_mutex_lock(VALUE self, int interruptible_p) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L279
 
                 if (!mutex->fiber) {
                     mutex->fiber = fiber;
-                    break;
-                } else {
-                    // Try again...
-                    continue;
                 }
-            }
-            
-	    enum rb_thread_status prev_status = th->status;
-	    rb_hrtime_t *timeout = 0;
-	    rb_hrtime_t rel = rb_msec2hrtime(100);
-
-	    th->status = THREAD_STOPPED_FOREVER;
-	    th->locking_mutex = self;
-            rb_ractor_sleeper_threads_inc(th->ractor);
-	    /*
-	     * Carefully! while some contended threads are in native_sleep(),
-	     * ractor->sleeper is unstable value. we have to avoid both deadlock
-	     * and busy loop.
-	     */
-	    if ((rb_ractor_living_thread_num(th->ractor) == rb_ractor_sleeper_thread_num(th->ractor)) &&
-		!patrol_thread) {
-		timeout = &rel;
-		patrol_thread = th;
-	    }
+            } else {
+                enum rb_thread_status prev_status = th->status;
+                rb_hrtime_t *timeout = 0;
+                rb_hrtime_t rel = rb_msec2hrtime(100);
+
+                th->status = THREAD_STOPPED_FOREVER;
+                th->locking_mutex = self;
+                rb_ractor_sleeper_threads_inc(th->ractor);
+                /*
+                 * Carefully! while some contended threads are in native_sleep(),
+                 * ractor->sleeper is unstable value. we have to avoid both deadlock
+                 * and busy loop.
+                 */
+                if ((rb_ractor_living_thread_num(th->ractor) == rb_ractor_sleeper_thread_num(th->ractor)) &&
+                    !patrol_thread) {
+                    timeout = &rel;
+                    patrol_thread = th;
+                }
 
-	    list_add_tail(&mutex->waitq, &w.node);
+                list_add_tail(&mutex->waitq, &w.node);
 
-            native_sleep(th, timeout); /* release GVL */
+                native_sleep(th, timeout); /* release GVL */
 
-	    list_del(&w.node);
+                list_del(&w.node);
 
-	    if (!mutex->fiber) {
-		mutex->fiber = fiber;
-	    }
+                if (!mutex->fiber) {
+                    mutex->fiber = fiber;
+                }
 
-	    if (patrol_thread == th)
-		patrol_thread = NULL;
+                if (patrol_thread == th)
+                    patrol_thread = NULL;
 
-	    th->locking_mutex = Qfalse;
-	    if (mutex->fiber && timeout && !RUBY_VM_INTERRUPTED(th->ec)) {
-		rb_check_deadlock(th->ractor);
-	    }
-	    if (th->status == THREAD_STOPPED_FOREVER) {
-		th->status = prev_status;
-	    }
-            rb_ractor_sleeper_threads_dec(th->ractor);
+                th->locking_mutex = Qfalse;
+                if (mutex->fiber && timeout && !RUBY_VM_INTERRUPTED(th->ec)) {
+                    rb_check_deadlock(th->ractor);
+                }
+                if (th->status == THREAD_STOPPED_FOREVER) {
+                    th->status = prev_status;
+                }
+                rb_ractor_sleeper_threads_dec(th->ractor);
+            }
 
             if (interruptible_p) {
                 /* release mutex before checking for interrupts...as interrupt checking
@@ -335,7 +331,7 @@ do_mutex_lock(VALUE self, int interruptible_p) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L331
                     mutex->fiber = fiber;
                 }
             }
-	}
+        }
 
         if (mutex->fiber == fiber) mutex_locked(th, self);
     }
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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