1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//! The shard handoff: a worker blocked in one poll (a blocking call, a long
//! loop) hands its shard to another thread, so the shard's other tasks,
//! timers and IO run on.
//!
//! The shard stays the same object with the same `Shared`, so every task,
//! waker, registration and handle keeps pointing at the right place; only
//! the thread under it changes. The runtime's [`Monitor`] sees a worker past
//! the threshold in one poll, takes its shard through the worker's
//! [`Slot`](slot::Slot), and hands it to a spare thread. The blocked thread
//! finishes its poll later, finds the shard gone, and carries on as a thread
//! with no shard: a `block_on` frame on its stack moves its future to the
//! thread's own shard, and its bound tasks (`spawn_local`, whose futures may
//! not move) wait in its [`Home`](home::Home) and run there too; then it
//! waits as a spare.
//!
//! What the worker pays: two plain stores and a load per poll, and per call
//! into the runtime from a task's code (every path of the runtime that
//! touches the shard, the owner's own among them, takes one: a bracket) a
//! load and a store of its word and a load of its claim, and a store as the
//! call ends (the compiler's fence between, where the process has a heavy
//! fence, see [`fence`]; a full fence elsewhere). A thread on a shard nobody
//! watches looks at one word per call. proofs/tla/handoff checks the
//! protocol, with the store buffers of x86 and every mutation of it that
//! must fail.
pub
pub
pub
pub
pub
pub
pub use ;
/// Whether a runtime may watch its workers here: not under loom (whose
/// threads are its own), not where there are no threads.
pub const SUPPORTED: bool = cfg!;