Drain all returned slab IDs (called by Data Plane on each tick). Returns an iterator of `SlabId`s to free. The caller should call `SlabPool::free()` for each.
(&self)
| 180 | /// Returns an iterator of `SlabId`s to free. The caller should call |
| 181 | /// `SlabPool::free()` for each. |
| 182 | pub fn drain(&self) -> Vec<SlabId> { |
| 183 | let write = self.write_pos.load(Ordering::Acquire); |
| 184 | let read = self.read_pos.load(Ordering::Relaxed); |
| 185 | |
| 186 | if write == read { |
| 187 | return Vec::new(); |
| 188 | } |
| 189 | |
| 190 | let count = write.wrapping_sub(read) as usize; |
| 191 | let mut ids = Vec::with_capacity(count.min(self.capacity as usize)); |
| 192 | |
| 193 | for i in 0..count { |
| 194 | let idx = ((read.wrapping_add(i as u32)) % self.capacity) as usize; |
| 195 | let packed = self.buffer[idx].load(Ordering::Acquire); |
| 196 | if packed == u32::MAX { |
| 197 | break; // Not yet written. |
| 198 | } |
| 199 | ids.push(SlabId { |
| 200 | core_id: (packed >> 16) as u16, |
| 201 | page_index: (packed & 0xFFFF) as u16, |
| 202 | len: 0, // Length not needed for free. |
| 203 | }); |
| 204 | self.buffer[idx].store(u32::MAX, Ordering::Release); |
| 205 | } |
| 206 | |
| 207 | self.read_pos |
| 208 | .store(read.wrapping_add(ids.len() as u32), Ordering::Release); |
| 209 | ids |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | #[cfg(test)] |