pub struct Task(/* private fields */);Expand description
A cancellable, concurrent-safe unit of work that tracks a start..end range.
Task is a reference-counted handle: each worker holds a strong Task
(an Arc<TaskInner>), giving every worker a distinct identity even when
two workers speculatively share the same progress cursor. This identity is
what set_threads’s liveness sweep keys off (via WeakTask), so a dead
worker is reclaimed regardless of how many twins still reference its cursor.
The range is stored as a single atomic u128 inside TaskInner, allowing
lock-free reads and fine-grained progress updates. Multiple workers can
safely steal sub-ranges from the same task via split_two.
Two Tasks are equal iff they point to the same underlying state (see the
PartialEq impl, which uses Arc::ptr_eq).
Implementations§
Source§impl Task
impl Task
Sourcepub fn get(&self) -> Range<u64> ⓘ
pub fn get(&self) -> Range<u64> ⓘ
Returns the current start..end range, loaded atomically with Acquire
ordering.
Sourcepub fn safe_add_start(
&self,
start: u64,
bias: u64,
) -> Result<Range<u64>, RangeError>
pub fn safe_add_start( &self, start: u64, bias: u64, ) -> Result<Range<u64>, RangeError>
Atomically advances start to min(start + bias, end), but only if that
makes forward progress; then returns the slice that was claimed.
start must be a cursor value the caller actually observed via
start or get; a start that runs ahead
of the task’s real cursor is rejected, because honouring it would skip
work no worker ever executed. A stale start is still accepted, but the
returned span then begins at the real cursor and is shorter than bias —
always consume the returned span, never assume start..start + bias.
§Errors
Returns RangeError when start + bias would not exceed the current
start (no progress, a non-positive bias), or when
start runs ahead of the task’s cursor.
Sourcepub fn end(&self) -> u64
pub fn end(&self) -> u64
Returns the current end of the work range (the low 64 bits of the atomic state).
Loads independently of start; see that method for the
torn-snapshot caveat when combining the two.
Sourcepub fn split_two(
&self,
min_chunk_size: u64,
) -> Result<Option<Range<u64>>, RangeError>
pub fn split_two( &self, min_chunk_size: u64, ) -> Result<Option<Range<u64>>, RangeError>
Splits the work range in half, handing mid..end back to the caller as a
new task and keeping start..mid in self.
The split only proceeds when both halves are at least min_chunk_size,
i.e. remain >= min_chunk_size * 2. That test runs inside the
compare-and-swap loop against the same atomic snapshot the commit
observes, so a concurrent cursor-sharer (share_state) advancing start
between the call and the commit cannot leak a half smaller than
min_chunk_size. When the range is too small to split under
min_chunk_size, returns Ok(None) without modifying self.
§Errors
- Returns
RangeErrorwhenstart > end - Returns
Nonewhenremain < min_chunk_size * 2without modifying itself
Sourcepub fn take(&self) -> Result<Option<Range<u64>>, RangeError>
pub fn take(&self) -> Result<Option<Range<u64>>, RangeError>
Atomically claims and returns the entire remaining range start..end,
emptying this task (sets start = end).
Shares its error contract with split_two: both
consume remaining work, so both report a violated range invariant instead
of normalising it away.
§Errors
- Returns
RangeErrorwhenstart > end - Returns
Ok(None)when the task is already empty, without modifying it
Sourcepub fn downgrade(&self) -> WeakTask
pub fn downgrade(&self) -> WeakTask
Creates a WeakTask that does not keep the task’s state alive.
Sourcepub fn strong_count(&self) -> usize
pub fn strong_count(&self) -> usize
Returns the number of strong Task references to this worker’s identity
(TaskInner).
Task and WeakTask are a paired strong/weak view of the same identity
allocation, so this equals WeakTask::strong_count on a matching
WeakTask — exactly like Arc/Weak. The (different) cursor-sharer count
that steal caps on is exposed separately as the crate-internal
sharer_count accessor.
Sourcepub fn weak_count(&self) -> usize
pub fn weak_count(&self) -> usize
Returns the number of weak WeakTask references to this worker’s identity
(TaskInner). Pairs with strong_count, and equals
WeakTask::weak_count on a matching WeakTask.