Skip to content

Commit 99414d8

Browse files
committed
preemption matters
also note the bounds and multi-core requirements of the cooperative handlers pattern
1 parent b86411f commit 99414d8

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

src/concurrency.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,15 +437,23 @@ context, though they can be implemented on top of interrupts. We'll broaden the
437437
definition of these two marker traits to include bare metal code:
438438

439439
- `Sync`: types for which it is safe to share references between *execution
440-
contexts*.
440+
contexts* that may preempt each other.
441441

442-
- `Send`: types that can be transferred between *execution contexts*.
442+
- `Send`: types that can be transferred between *execution contexts* that may
443+
preempt each other.
443444

444445
An interrupt handler is an execution context independent of the `main` function,
445446
which can be seen as the "bottom" execution context. An OS thread is also an
446447
execution context. Each execution context has its own (call) stack and operates
447448
independently of other execution contexts though they can share state.
448449

450+
Preemption between any two execution contexts may or may not be possible. For
451+
example, preemption can occur between two interrupt handlers if they have
452+
different priorities, but no preemption can occur between the two if they have
453+
the same priority. In the case of OS threads, it depends on the exact
454+
implementation; in the most common case, any two threads can preempt each other
455+
because the scheduler periodically context switches between them.
456+
449457
Broadening the definitions of these marker traits does not change the rules
450458
around `static` variables. They must still hold values that implement the `Sync`
451459
trait. Atomics implement `Sync` so they are valid to place in `static` variables
@@ -558,6 +566,12 @@ unsafe impl<T> Sync for Mutex<T> where T: Send {}
558566

559567
This constraint applies to all types of critical sections.
560568

569+
### Cooperative handlers
570+
571+
In the case of interrupt handlers that run at the same priority and access the
572+
same static variable (see `examples/coop.rs`) no bound is required as no
573+
preemption is possible.
574+
561575
### Runtime initialization
562576

563577
For the pattern of moving values from `main` to an interrupt handler this is
@@ -715,6 +729,11 @@ program has been configured to not share stateful interrupts between cores --
715729
that is cores should *not* execute the exact same handler when the corresponding
716730
signal arrives.
717731

732+
### Cooperative handlers
733+
734+
The cooperative handlers pattern remains sound if and only if the handlers that
735+
share state are serviced by a single core.
736+
718737
### Runtime initialization
719738

720739
As the runtime initialization pattern is used to initialize the "state" of

0 commit comments

Comments
 (0)