pub struct IoTransferWindow<'session, 'board> { /* private fields */ }Expand description
A rolling VeriComm pipeline that keeps up to capacity transfers in flight.
All transfers in one window have the same word length chosen up front.
Submit frames with Self::submit and retire them in order with
Self::receive_into. Dropping the window cancels any remaining transfers
and recycles their buffers back into the parent IoSession.
Implementations§
Source§impl<'session, 'board> IoTransferWindow<'session, 'board>
impl<'session, 'board> IoTransferWindow<'session, 'board>
pub fn words(&self) -> usize
pub fn capacity(&self) -> usize
pub fn pending(&self) -> usize
pub fn available(&self) -> usize
pub fn is_empty(&self) -> bool
pub fn is_full(&self) -> bool
Sourcepub fn submit(&mut self, tx: &[u16]) -> Result<()>
pub fn submit(&mut self, tx: &[u16]) -> Result<()>
Queues one transfer into the rolling window.
Examples found in repository?
examples/bench_transfer.rs (line 185)
147fn run_device_bench(options: &Options) -> Result<(), Box<dyn Error>> {
148 let mut board = Board::open_with_transport(options.transport)?;
149 let max_cycles_per_transfer = usize::from(board.config().fifo_size_words()) / WORDS_PER_CYCLE;
150 let mut io = board.configure_io(&IoConfig {
151 clock_high_delay: options.clock_high_delay,
152 clock_low_delay: options.clock_low_delay,
153 ..IoConfig::default()
154 })?;
155
156 if options.window == 0 {
157 return Err("window must be at least 1".into());
158 }
159
160 let template = vec![0x1234u16; options.words];
161 let mut rx = vec![0u16; options.words];
162 let mut outputs = vec![vec![0u16; options.words]; options.window];
163 let mut stage_profile = TransferStageProfile::default();
164
165 let started = Instant::now();
166 if options.window == 1 {
167 if options.profile_stages {
168 for _ in 0..options.iterations {
169 let profile = io.transfer_profiled_into(&template, &mut rx)?;
170 stage_profile.merge(&profile);
171 }
172 } else {
173 for _ in 0..options.iterations {
174 io.transfer(&template, &mut rx)?;
175 }
176 }
177 } else {
178 let mut window = io.transfer_window(options.words, options.window)?;
179 let initial = options.iterations.min(options.window);
180 for _ in 0..initial {
181 if options.profile_stages {
182 let profile = window.submit_profiled(&template)?;
183 stage_profile.merge(&profile);
184 } else {
185 window.submit(&template)?;
186 }
187 }
188
189 let mut submitted = initial;
190 let mut completed = 0usize;
191 while completed < options.iterations {
192 let output = outputs[completed % options.window].as_mut_slice();
193 if options.profile_stages {
194 let profile = window.receive_into_profiled(output)?;
195 stage_profile.merge(&profile);
196 } else {
197 window.receive_into(output)?;
198 }
199 completed += 1;
200
201 if submitted < options.iterations {
202 if options.profile_stages {
203 let profile = window.submit_profiled(&template)?;
204 stage_profile.merge(&profile);
205 } else {
206 window.submit(&template)?;
207 }
208 submitted += 1;
209 }
210 }
211 }
212 let elapsed = started.elapsed();
213 io.finish()?;
214
215 print_summary(
216 "device",
217 options.words,
218 options.iterations,
219 elapsed,
220 Some(max_cycles_per_transfer),
221 );
222 if options.profile_stages {
223 print_stage_profile(&stage_profile, elapsed);
224 }
225 Ok(())
226}More examples
examples/stress_abort.rs (line 74)
12fn real_main() -> Result<(), Box<dyn Error>> {
13 let mut iterations = 10usize;
14 let mut words = 512usize;
15 let mut window = 4usize;
16 let mut clock_high = 4u16;
17 let mut clock_low = 4u16;
18 let mut settle_ms = 0u64;
19
20 let mut args = env::args().skip(1);
21 while let Some(flag) = args.next() {
22 match flag.as_str() {
23 "--iterations" => {
24 iterations = args
25 .next()
26 .ok_or("missing value for --iterations")?
27 .parse()?
28 }
29 "--words" => words = args.next().ok_or("missing value for --words")?.parse()?,
30 "--window" => window = args.next().ok_or("missing value for --window")?.parse()?,
31 "--clock-high" => {
32 clock_high = args
33 .next()
34 .ok_or("missing value for --clock-high")?
35 .parse()?
36 }
37 "--clock-low" => {
38 clock_low = args
39 .next()
40 .ok_or("missing value for --clock-low")?
41 .parse()?
42 }
43 "--settle-ms" => {
44 settle_ms = args
45 .next()
46 .ok_or("missing value for --settle-ms")?
47 .parse()?
48 }
49 other => return Err(format!("unknown flag `{other}`").into()),
50 }
51 }
52
53 let tx = vec![0x1234u16; words];
54
55 for iteration in 0..iterations {
56 println!("iter={iteration} phase=open");
57 let mut board = Board::open()?;
58 println!(
59 "iter={iteration} config programmed={} fifo_words={} version=0x{:04x}",
60 board.config().is_programmed(),
61 board.config().fifo_size_words(),
62 board.config().smims_version_raw()
63 );
64
65 let mut io = board.configure_io(&IoConfig {
66 clock_high_delay: clock_high,
67 clock_low_delay: clock_low,
68 ..IoConfig::default()
69 })?;
70
71 {
72 let mut rolling = io.transfer_window(words, window)?;
73 for submit_index in 0..window {
74 rolling.submit(&tx)?;
75 println!("iter={iteration} submit={submit_index}");
76 }
77 if settle_ms > 0 {
78 thread::sleep(Duration::from_millis(settle_ms));
79 }
80 }
81
82 io.finish()?;
83 board.close()?;
84
85 println!("iter={iteration} phase=reopen");
86 let reopened = Board::open()?;
87 println!(
88 "iter={iteration} reopened programmed={} fifo_words={} version=0x{:04x}",
89 reopened.config().is_programmed(),
90 reopened.config().fifo_size_words(),
91 reopened.config().smims_version_raw()
92 );
93 reopened.close()?;
94 }
95
96 Ok(())
97}Sourcepub fn submit_profiled(&mut self, tx: &[u16]) -> Result<TransferStageProfile>
pub fn submit_profiled(&mut self, tx: &[u16]) -> Result<TransferStageProfile>
Queues one transfer and returns a stage profile for that submission.
Examples found in repository?
examples/bench_transfer.rs (line 182)
147fn run_device_bench(options: &Options) -> Result<(), Box<dyn Error>> {
148 let mut board = Board::open_with_transport(options.transport)?;
149 let max_cycles_per_transfer = usize::from(board.config().fifo_size_words()) / WORDS_PER_CYCLE;
150 let mut io = board.configure_io(&IoConfig {
151 clock_high_delay: options.clock_high_delay,
152 clock_low_delay: options.clock_low_delay,
153 ..IoConfig::default()
154 })?;
155
156 if options.window == 0 {
157 return Err("window must be at least 1".into());
158 }
159
160 let template = vec![0x1234u16; options.words];
161 let mut rx = vec![0u16; options.words];
162 let mut outputs = vec![vec![0u16; options.words]; options.window];
163 let mut stage_profile = TransferStageProfile::default();
164
165 let started = Instant::now();
166 if options.window == 1 {
167 if options.profile_stages {
168 for _ in 0..options.iterations {
169 let profile = io.transfer_profiled_into(&template, &mut rx)?;
170 stage_profile.merge(&profile);
171 }
172 } else {
173 for _ in 0..options.iterations {
174 io.transfer(&template, &mut rx)?;
175 }
176 }
177 } else {
178 let mut window = io.transfer_window(options.words, options.window)?;
179 let initial = options.iterations.min(options.window);
180 for _ in 0..initial {
181 if options.profile_stages {
182 let profile = window.submit_profiled(&template)?;
183 stage_profile.merge(&profile);
184 } else {
185 window.submit(&template)?;
186 }
187 }
188
189 let mut submitted = initial;
190 let mut completed = 0usize;
191 while completed < options.iterations {
192 let output = outputs[completed % options.window].as_mut_slice();
193 if options.profile_stages {
194 let profile = window.receive_into_profiled(output)?;
195 stage_profile.merge(&profile);
196 } else {
197 window.receive_into(output)?;
198 }
199 completed += 1;
200
201 if submitted < options.iterations {
202 if options.profile_stages {
203 let profile = window.submit_profiled(&template)?;
204 stage_profile.merge(&profile);
205 } else {
206 window.submit(&template)?;
207 }
208 submitted += 1;
209 }
210 }
211 }
212 let elapsed = started.elapsed();
213 io.finish()?;
214
215 print_summary(
216 "device",
217 options.words,
218 options.iterations,
219 elapsed,
220 Some(max_cycles_per_transfer),
221 );
222 if options.profile_stages {
223 print_stage_profile(&stage_profile, elapsed);
224 }
225 Ok(())
226}Sourcepub fn receive_into(&mut self, output: &mut [u16]) -> Result<()>
pub fn receive_into(&mut self, output: &mut [u16]) -> Result<()>
Retires the oldest in-flight transfer into output.
Examples found in repository?
examples/bench_transfer.rs (line 197)
147fn run_device_bench(options: &Options) -> Result<(), Box<dyn Error>> {
148 let mut board = Board::open_with_transport(options.transport)?;
149 let max_cycles_per_transfer = usize::from(board.config().fifo_size_words()) / WORDS_PER_CYCLE;
150 let mut io = board.configure_io(&IoConfig {
151 clock_high_delay: options.clock_high_delay,
152 clock_low_delay: options.clock_low_delay,
153 ..IoConfig::default()
154 })?;
155
156 if options.window == 0 {
157 return Err("window must be at least 1".into());
158 }
159
160 let template = vec![0x1234u16; options.words];
161 let mut rx = vec![0u16; options.words];
162 let mut outputs = vec![vec![0u16; options.words]; options.window];
163 let mut stage_profile = TransferStageProfile::default();
164
165 let started = Instant::now();
166 if options.window == 1 {
167 if options.profile_stages {
168 for _ in 0..options.iterations {
169 let profile = io.transfer_profiled_into(&template, &mut rx)?;
170 stage_profile.merge(&profile);
171 }
172 } else {
173 for _ in 0..options.iterations {
174 io.transfer(&template, &mut rx)?;
175 }
176 }
177 } else {
178 let mut window = io.transfer_window(options.words, options.window)?;
179 let initial = options.iterations.min(options.window);
180 for _ in 0..initial {
181 if options.profile_stages {
182 let profile = window.submit_profiled(&template)?;
183 stage_profile.merge(&profile);
184 } else {
185 window.submit(&template)?;
186 }
187 }
188
189 let mut submitted = initial;
190 let mut completed = 0usize;
191 while completed < options.iterations {
192 let output = outputs[completed % options.window].as_mut_slice();
193 if options.profile_stages {
194 let profile = window.receive_into_profiled(output)?;
195 stage_profile.merge(&profile);
196 } else {
197 window.receive_into(output)?;
198 }
199 completed += 1;
200
201 if submitted < options.iterations {
202 if options.profile_stages {
203 let profile = window.submit_profiled(&template)?;
204 stage_profile.merge(&profile);
205 } else {
206 window.submit(&template)?;
207 }
208 submitted += 1;
209 }
210 }
211 }
212 let elapsed = started.elapsed();
213 io.finish()?;
214
215 print_summary(
216 "device",
217 options.words,
218 options.iterations,
219 elapsed,
220 Some(max_cycles_per_transfer),
221 );
222 if options.profile_stages {
223 print_stage_profile(&stage_profile, elapsed);
224 }
225 Ok(())
226}Sourcepub fn receive_into_profiled(
&mut self,
output: &mut [u16],
) -> Result<TransferStageProfile>
pub fn receive_into_profiled( &mut self, output: &mut [u16], ) -> Result<TransferStageProfile>
Retires the oldest in-flight transfer and returns its stage profile.
Examples found in repository?
examples/bench_transfer.rs (line 194)
147fn run_device_bench(options: &Options) -> Result<(), Box<dyn Error>> {
148 let mut board = Board::open_with_transport(options.transport)?;
149 let max_cycles_per_transfer = usize::from(board.config().fifo_size_words()) / WORDS_PER_CYCLE;
150 let mut io = board.configure_io(&IoConfig {
151 clock_high_delay: options.clock_high_delay,
152 clock_low_delay: options.clock_low_delay,
153 ..IoConfig::default()
154 })?;
155
156 if options.window == 0 {
157 return Err("window must be at least 1".into());
158 }
159
160 let template = vec![0x1234u16; options.words];
161 let mut rx = vec![0u16; options.words];
162 let mut outputs = vec![vec![0u16; options.words]; options.window];
163 let mut stage_profile = TransferStageProfile::default();
164
165 let started = Instant::now();
166 if options.window == 1 {
167 if options.profile_stages {
168 for _ in 0..options.iterations {
169 let profile = io.transfer_profiled_into(&template, &mut rx)?;
170 stage_profile.merge(&profile);
171 }
172 } else {
173 for _ in 0..options.iterations {
174 io.transfer(&template, &mut rx)?;
175 }
176 }
177 } else {
178 let mut window = io.transfer_window(options.words, options.window)?;
179 let initial = options.iterations.min(options.window);
180 for _ in 0..initial {
181 if options.profile_stages {
182 let profile = window.submit_profiled(&template)?;
183 stage_profile.merge(&profile);
184 } else {
185 window.submit(&template)?;
186 }
187 }
188
189 let mut submitted = initial;
190 let mut completed = 0usize;
191 while completed < options.iterations {
192 let output = outputs[completed % options.window].as_mut_slice();
193 if options.profile_stages {
194 let profile = window.receive_into_profiled(output)?;
195 stage_profile.merge(&profile);
196 } else {
197 window.receive_into(output)?;
198 }
199 completed += 1;
200
201 if submitted < options.iterations {
202 if options.profile_stages {
203 let profile = window.submit_profiled(&template)?;
204 stage_profile.merge(&profile);
205 } else {
206 window.submit(&template)?;
207 }
208 submitted += 1;
209 }
210 }
211 }
212 let elapsed = started.elapsed();
213 io.finish()?;
214
215 print_summary(
216 "device",
217 options.words,
218 options.iterations,
219 elapsed,
220 Some(max_cycles_per_transfer),
221 );
222 if options.profile_stages {
223 print_stage_profile(&stage_profile, elapsed);
224 }
225 Ok(())
226}Trait Implementations§
Auto Trait Implementations§
impl<'session, 'board> Freeze for IoTransferWindow<'session, 'board>
impl<'session, 'board> !RefUnwindSafe for IoTransferWindow<'session, 'board>
impl<'session, 'board> Send for IoTransferWindow<'session, 'board>
impl<'session, 'board> Sync for IoTransferWindow<'session, 'board>
impl<'session, 'board> Unpin for IoTransferWindow<'session, 'board>
impl<'session, 'board> UnsafeUnpin for IoTransferWindow<'session, 'board>
impl<'session, 'board> !UnwindSafe for IoTransferWindow<'session, 'board>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more