Modification and Iteration
Relevant source files
This page documents the CpuMask
methods and traits for modifying mask state after construction and for iterating over set CPU indices. For mask construction methods, see Construction and Conversion Methods. For read-only query operations, see Query and Inspection Operations. For bitwise operations and operator overloads, see Bitwise Operations and Traits.
Modification Operations
The CpuMask
provides two primary methods for modifying the state of a mask after construction: individual bit manipulation via set
and bulk inversion via invert
.
Bit Manipulation
The set
method allows modification of individual CPU bits within the mask. It takes an index and a boolean value, sets the bit at that position, and returns the previous value of that bit.
flowchart TD A["CpuMask::set(index, value)"] B["debug_assert!(index < SIZE)"] C["self.value.set(index, value)"] D["Returns previous bit value"] E["Input: index: usize"] F["Input: value: bool"] A --> B B --> C C --> D E --> A F --> A
Sources: src/lib.rs(L177 - L180)
The method includes a debug assertion to ensure the index is within the valid range (less than SIZE
). The actual bit manipulation is delegated to the underlying Bitmap::set
method from the bitmaps crate.
Bulk Inversion
The invert
method provides a way to flip all bits in the mask simultaneously, converting true
bits to false
and vice versa.
flowchart TD A["CpuMask::invert()"] B["self.value.invert()"] C["All bits flipped"] D["Before: 101010"] E["After: 010101"] A --> B B --> C D --> A E --> C
Sources: src/lib.rs(L232 - L234)
This operation is useful for computing the complement of a CPU set, such as finding all CPUs that are not currently assigned to a particular task.
Iteration Interface
The CpuMask
implements comprehensive iteration support through the IntoIterator
trait and a custom Iter
struct that provides both forward and backward iteration over set CPU indices.
Iterator Implementation Architecture
flowchart TD A["&CpuMask"] B["IntoIterator trait"] C["Iter<'a, SIZE>"] D["Iterator trait"] E["DoubleEndedIterator trait"] F["next() -> Option"] G["next_back() -> Option"] H["head: Option"] I["tail: Option"] J["data: &'a CpuMask"] A --> B B --> C C --> D C --> E D --> F E --> G H --> C I --> C J --> C
Sources: src/lib.rs(L237 - L251) src/lib.rs(L429 - L436) src/lib.rs(L438 - L480) src/lib.rs(L482 - L518)
Iterator State Management
The Iter
struct maintains iteration state using two optional indices:
Field | Type | Purpose |
---|---|---|
head | Option | Tracks forward iteration position |
tail | Option | Tracks backward iteration position |
data | &'a CpuMask | Reference to the mask being iterated |
The iterator is initialized with head
set to None
and tail
set to Some(SIZE + 1)
, indicating that iteration can proceed in both directions from the extremes.
Forward Iteration Logic
flowchart TD A["next() called"] B["head == None?"] C["result = data.first_index()"] D["index >= SIZE?"] E["result = None"] F["result = data.next_index(index)"] G["result found?"] H["Check tail boundary"] I["head = SIZE + 1"] J["tail < index?"] K["Stop iteration"] L["head = index"] M["Return None"] N["Return Some(index)"] A --> B B --> C B --> D C --> G D --> E D --> F E --> G F --> G G --> H G --> I H --> J I --> M J --> K J --> L K --> M L --> N
Sources: src/lib.rs(L444 - L479)
Backward Iteration Logic
The DoubleEndedIterator
implementation provides next_back
functionality with similar boundary checking but in reverse:
flowchart TD A["next_back() called"] B["tail == None?"] C["result = None"] D["index >= SIZE?"] E["result = data.last_index()"] F["result = data.prev_index(index)"] G["result found?"] H["Check head boundary"] I["tail = None"] J["head > index?"] K["Stop iteration"] L["tail = index"] M["Return None"] N["Return Some(index)"] A --> B B --> C B --> D C --> G D --> E D --> F E --> G F --> G G --> H G --> I H --> J I --> M J --> K J --> L K --> M L --> N
Sources: src/lib.rs(L486 - L517)
Usage Patterns
Modification Examples
The modification operations enable dynamic CPU mask management:
Operation | Purpose | Method Call |
---|---|---|
Enable CPU | Add CPU to active set | mask.set(cpu_id, true) |
Disable CPU | Remove CPU from active set | mask.set(cpu_id, false) |
Toggle all CPUs | Invert entire mask | mask.invert() |
Iteration Examples
The iterator yields usize
indices representing CPU numbers that are set to true
in the mask:
// Iterate through all active CPUs
for cpu_id in &mask {
// cpu_id is usize, represents an active CPU
}
// Collect to vector for further processing
let active_cpus: Vec<usize> = mask.into_iter().collect();
// Reverse iteration for priority-based processing
for cpu_id in mask.into_iter().rev() {
// Process from highest to lowest CPU index
}
The implementation ensures that only indices with true
bits are yielded, making it efficient for sparse CPU masks where only a few CPUs are active.