From ef7d9573a3a8f20c9ed55c6d3f72953c566abed1 Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 26 Apr 2024 18:20:07 +0200 Subject: [PATCH 1/2] Set current fiber on Thread instead of Crystal::Scheduler --- src/crystal/scheduler.cr | 15 +++++---------- src/crystal/system/thread.cr | 7 +++++-- src/fiber.cr | 6 +++--- src/gc/boehm.cr | 3 +-- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/crystal/scheduler.cr b/src/crystal/scheduler.cr index 1728a9b7f335..c86d04309b14 100644 --- a/src/crystal/scheduler.cr +++ b/src/crystal/scheduler.cr @@ -24,10 +24,6 @@ class Crystal::Scheduler Thread.current.scheduler.@event_loop end - def self.current_fiber : Fiber - Thread.current.scheduler.@current - end - def self.enqueue(fiber : Fiber) : Nil thread = Thread.current scheduler = thread.scheduler @@ -98,10 +94,9 @@ class Crystal::Scheduler @sleeping = false # :nodoc: - def initialize(thread : Thread) + def initialize(@thread : Thread) @main = thread.main_fiber {% if flag?(:preview_mt) %} @main.set_current_thread(thread) {% end %} - @current = @main @runnables = Deque(Fiber).new end @@ -124,7 +119,7 @@ class Crystal::Scheduler GC.set_stackbottom(fiber.@stack_bottom) {% end %} - current, @current = @current, fiber + current, @thread.current_fiber = @thread.current_fiber, fiber Fiber.swapcontext(pointerof(current.@context), pointerof(fiber.@context)) {% if flag?(:preview_mt) %} @@ -151,7 +146,7 @@ class Crystal::Scheduler protected def reschedule : Nil loop do if runnable = @lock.sync { @runnables.shift? } - resume(runnable) unless runnable == @current + resume(runnable) unless runnable == @thread.current_fiber break else @event_loop.run_once @@ -160,12 +155,12 @@ class Crystal::Scheduler end protected def sleep(time : Time::Span) : Nil - @current.resume_event.add(time) + @thread.current_fiber.resume_event.add(time) reschedule end protected def yield(fiber : Fiber) : Nil - @current.resume_event.add(0.seconds) + @thread.current_fiber.resume_event.add(0.seconds) resume(fiber) end diff --git a/src/crystal/system/thread.cr b/src/crystal/system/thread.cr index dd93714487b9..e6627538112d 100644 --- a/src/crystal/system/thread.cr +++ b/src/crystal/system/thread.cr @@ -45,6 +45,9 @@ class Thread # Returns the Fiber representing the thread's main stack. getter! main_fiber : Fiber + # Returns the Fiber currently running on the thread. + property! current_fiber : Fiber + # :nodoc: property next : Thread? @@ -68,7 +71,7 @@ class Thread def initialize @func = ->(t : Thread) {} @system_handle = Crystal::System::Thread.current_handle - @main_fiber = Fiber.new(stack_address, self) + @current_fiber = @main_fiber = Fiber.new(stack_address, self) Thread.threads.push(self) end @@ -120,7 +123,7 @@ class Thread protected def start Thread.threads.push(self) Thread.current = self - @main_fiber = fiber = Fiber.new(stack_address, self) + @current_fiber = @main_fiber = fiber = Fiber.new(stack_address, self) if name = @name self.system_name = name diff --git a/src/fiber.cr b/src/fiber.cr index 049b7e9bb0c0..5f6e632b2445 100644 --- a/src/fiber.cr +++ b/src/fiber.cr @@ -173,7 +173,7 @@ class Fiber # Returns the current fiber. def self.current : Fiber - Crystal::Scheduler.current_fiber + Thread.current.current_fiber end # The fiber's proc is currently running or didn't fully save its context. The @@ -246,11 +246,11 @@ class Fiber # The current fiber will resume after a period of time. # The timeout can be cancelled with `cancel_timeout` def self.timeout(timeout : Time::Span?, select_action : Channel::TimeoutAction? = nil) : Nil - Crystal::Scheduler.current_fiber.timeout(timeout, select_action) + Fiber.current.timeout(timeout, select_action) end def self.cancel_timeout : Nil - Crystal::Scheduler.current_fiber.cancel_timeout + Fiber.current.cancel_timeout end # Yields to the scheduler and allows it to swap execution to other diff --git a/src/gc/boehm.cr b/src/gc/boehm.cr index 609f71189795..90fe2801bd7d 100644 --- a/src/gc/boehm.cr +++ b/src/gc/boehm.cr @@ -374,8 +374,7 @@ module GC {% if flag?(:preview_mt) %} Thread.unsafe_each do |thread| - if scheduler = thread.@scheduler - fiber = scheduler.@current + if fiber = thread.@current_fiber GC.set_stackbottom(thread.gc_thread_handler, fiber.@stack_bottom) end end From 7b3940955e0656ac4f6c013b08915c14b8c6151c Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Thu, 2 May 2024 19:43:01 +0200 Subject: [PATCH 2/2] Prefer nilable getter over direct ivar access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Johannes Müller --- src/gc/boehm.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gc/boehm.cr b/src/gc/boehm.cr index 90fe2801bd7d..29ae825adab1 100644 --- a/src/gc/boehm.cr +++ b/src/gc/boehm.cr @@ -374,7 +374,7 @@ module GC {% if flag?(:preview_mt) %} Thread.unsafe_each do |thread| - if fiber = thread.@current_fiber + if fiber = thread.current_fiber? GC.set_stackbottom(thread.gc_thread_handler, fiber.@stack_bottom) end end