Skip to content

Commit 9961e39

Browse files
straight-shootaSijaysbaddaden
authored
Enhance documentation for ExecutionContext (#15665)
Co-authored-by: Sijawusz Pur Rahnama <[email protected]> Co-authored-by: Julien Portalier <[email protected]>
1 parent 9f9eb40 commit 9961e39

File tree

5 files changed

+97
-11
lines changed

5 files changed

+97
-11
lines changed

src/concurrent.cr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ end
3939
{% begin %}
4040
# Spawns a new fiber.
4141
#
42+
# When using execution contexts, the fiber spawns into the current execution
43+
# context (`Fiber::ExecutionContext.current`).
44+
#
4245
# NOTE: The newly created fiber doesn't run as soon as spawned.
4346
#
4447
# Example:
@@ -85,6 +88,9 @@ end
8588
# Spawns a fiber by first creating a `Proc`, passing the *call*'s
8689
# expressions to it, and letting the `Proc` finally invoke the *call*.
8790
#
91+
# When using execution contexts, the fiber spawns into the current execution
92+
# context (`Fiber::ExecutionContext.current`).
93+
#
8894
# Compare this:
8995
#
9096
# ```

src/fiber/execution_context.cr

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,73 @@ require "./execution_context/*"
88
{% raise "ERROR: execution contexts require the `preview_mt` compilation flag" unless flag?(:preview_mt) || flag?(:docs) %}
99
{% raise "ERROR: execution contexts require the `execution_context` compilation flag" unless flag?(:execution_context) || flag?(:docs) %}
1010

11+
# An execution context creates and manages a dedicated pool of 1 or more threads
12+
# where fibers can be executed into. Each context manages the rules to run,
13+
# suspend and swap fibers internally.
14+
#
15+
# EXPERIMENTAL: Execution contexts are an experimental feature, implementing
16+
# [RFC 2](https://github.com/crystal-lang/rfcs/pull/2). It's opt-in and requires
17+
# the compiler flags `-Dpreview_mt -Dexecution_context`.
18+
#
19+
# Applications can create any number of execution contexts in parallel. These
20+
# contexts are isolated but they can communicate with the usual thread-safe
21+
# synchronization primitives (e.g. `Channel`, `Mutex`).
22+
#
23+
# An execution context groups fibers together. Instead of associating a fiber to
24+
# a specific thread, we associate a fiber to an execution context, abstracting
25+
# which thread(s) they actually run on.
26+
#
27+
# When spawning a fiber with `::spawn`, it spawns into the execution context of
28+
# the current fiber. Thus child fibers execute in the same context as their
29+
# parent (unless told otherwise).
30+
#
31+
# Once spawned, a fiber cannot _move_ to another execution context. It always
32+
# resumes in the same execution context.
33+
#
34+
# ## Context types
35+
#
36+
# The standard library provides a number of execution context implementations
37+
# for common use cases.
38+
#
39+
# * `ExecutionContext::SingleThreaded`: Fully concurrent with limited
40+
# parallelism. Fibers run concurrently in a single thread and never in parallel.
41+
# They can use simpler and faster synchronization primitives internally (no
42+
# atomics, no thread safety). Communication with fibers in other contexts
43+
# requires thread-safe primitives. A blocking fiber blocks the entire thread and
44+
# all other fibers in the context.
45+
# * `ExecutionContext::MultiThreaded`: Fully concurrent, fully parallel. Fibers
46+
# running in this context can be resumed by any thread in this context. They run
47+
# concurrently and in parallel to each other, in addition to running in parallel
48+
# to any fibers in other contexts. Schedulers steal work from each other. The
49+
# number of threads can grow and shrink dynamically.
50+
# * `ExecutionContext::Isolated`: Single fiber in a single thread without
51+
# concurrency. This is useful for tasks that can block thread execution for a
52+
# long time (e.g. a GUI main loop, a game loop, or CPU heavy computation). The
53+
# event-loop works normally (when the fiber sleeps, it pauses the thread).
54+
# Communication with fibers in other contexts requires thread-safe primitives.
55+
#
56+
# ## The default execution context
57+
#
58+
# The Crystal runtime starts with a single threaded execution context, available
59+
# in `Fiber::ExecutionContext.default`.
60+
#
61+
# ```
62+
# Fiber::ExecutionContext.default.class # => Fiber::ExecutionContext::SingleThreaded
63+
# ```
64+
#
65+
# NOTE: The single threaded default context is required for backwards
66+
# compatibility. It may change to a multi-threaded default context in the
67+
# future.
1168
@[Experimental]
1269
module Fiber::ExecutionContext
1370
@@default : ExecutionContext?
1471

1572
# Returns the default `ExecutionContext` for the process, automatically
1673
# started when the program started.
74+
#
75+
# NOTE: The default context is a `SingleThreaded` context for backwards
76+
# compatibility reasons. It may change to a multi-threaded default context in
77+
# the future.
1778
@[AlwaysInline]
1879
def self.default : ExecutionContext
1980
@@default.not_nil!("expected default execution context to have been setup")

src/fiber/execution_context/isolated.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ require "./scheduler"
22
require "../list"
33

44
module Fiber::ExecutionContext
5-
# ST scheduler. Owns a single thread running a single fiber.
5+
# Isolated execution context. Runs a single thread with a single fiber.
66
#
77
# Concurrency is disabled within the thread: the fiber owns the thread and the
88
# thread can only run this fiber. Keep in mind that the fiber will still run

src/fiber/execution_context/multi_threaded.cr

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,28 @@ require "./global_queue"
22
require "./multi_threaded/scheduler"
33

44
module Fiber::ExecutionContext
5-
# MT scheduler.
5+
# A multi-threaded execution context which owns one or more threads. It's
6+
# fully concurrent and fully parallel.
67
#
78
# Owns multiple threads and starts a scheduler in each one. The number of
89
# threads is dynamic. Setting the minimum and maximum to the same value will
910
# start a fixed number of threads.
1011
#
11-
# Fully concurrent, fully parallel: fibers running in this context can be
12-
# resumed by any thread in the context; fibers can run concurrently and in
13-
# parallel to each other, in addition to running in parallel to every other
14-
# fibers running in other contexts.
12+
# Fibers running in this context can be resumed by any thread in the context.
13+
# Fibers can run concurrently and in parallel to each other, in addition to
14+
# running in parallel to any other fiber running in other contexts.
15+
#
16+
# ```
17+
# mt_context = Fiber::ExecutionContext::MultiThreaded.new("worker-threads", 4)
18+
#
19+
# 10.times do
20+
# mt_context.spawn do
21+
# do_something
22+
# end
23+
# end
24+
#
25+
# sleep
26+
# ```
1527
class MultiThreaded
1628
include ExecutionContext
1729

src/fiber/execution_context/single_threaded.cr

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@ require "./runnables"
33
require "./scheduler"
44

55
module Fiber::ExecutionContext
6-
# ST scheduler. Owns a single thread.
6+
# A single-threaded execution context which owns a single thread. It's fully
7+
# concurrent with limited parallelism.
78
#
8-
# Fully concurrent with limited parallelism: concurrency is restricted to this
9-
# single thread. Fibers running in this context will never run in parallel to
10-
# each other but they may still run in parallel to fibers running in other
11-
# contexts (i.e. another thread).
9+
# Concurrency is restricted to a single thread. Fibers in the same context
10+
# will never run in parallel to each other but they may still run in parallel
11+
# to fibers running in other contexts (i.e. in another thread).
12+
#
13+
# Fibers can use simpler and faster synchronization primitives between
14+
# themselves (no atomics, no thread safety). Communication with fibers in
15+
# other contexts requires thread-safe primitives.
16+
#
17+
# A blocking fiber blocks the entire thread and all other fibers in the
18+
# context.
1219
class SingleThreaded
1320
include ExecutionContext
1421
include ExecutionContext::Scheduler

0 commit comments

Comments
 (0)