Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread owns its current fiber (instead of Crystal::Scheduler) #14554

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions src/crystal/scheduler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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) %}
Expand All @@ -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
Expand All @@ -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

Expand Down
7 changes: 5 additions & 2 deletions src/crystal/system/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
ysbaddaden marked this conversation as resolved.
Show resolved Hide resolved

# :nodoc:
property next : Thread?

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/fiber.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions src/gc/boehm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading