(
ctx: &mut VmCtx,
out_ptr: u32,
timeouts: &Vec<(u64, Timestamp)>,
min_timeout: &Option<Timestamp>,
)
| 157 | #[ensures(ctx_safe(ctx))] |
| 158 | #[ensures(trace_safe(trace, ctx))] |
| 159 | pub fn writeback_timeouts( |
| 160 | ctx: &mut VmCtx, |
| 161 | out_ptr: u32, |
| 162 | timeouts: &Vec<(u64, Timestamp)>, |
| 163 | min_timeout: &Option<Timestamp>, |
| 164 | ) -> RuntimeResult<u32> { |
| 165 | let mut num_events_written = 0; |
| 166 | let mut event_idx = 0; |
| 167 | while event_idx < timeouts.len() { |
| 168 | body_invariant!(ctx_safe(ctx)); |
| 169 | body_invariant!(trace_safe(trace, ctx)); |
| 170 | |
| 171 | let (userdata, timeout) = timeouts[event_idx]; |
| 172 | let event_offset = (num_events_written * Event::WASI_SIZE) as usize; |
| 173 | if !ctx.fits_in_lin_mem_usize(out_ptr as usize + event_offset, Event::WASI_SIZE as usize) { |
| 174 | return Err(Eoverflow); |
| 175 | } |
| 176 | // Technically we know there must be a min_timeout, but use if let to be safe |
| 177 | if let Some(m_timeout) = min_timeout { |
| 178 | if timeout == *m_timeout { |
| 179 | let event = Event { |
| 180 | userdata, |
| 181 | error: RuntimeError::Success, |
| 182 | typ: EventType::Clock, |
| 183 | fd_readwrite: None, |
| 184 | }; |
| 185 | event.write(ctx, out_ptr + event_offset as u32); |
| 186 | num_events_written += 1; |
| 187 | } |
| 188 | } |
| 189 | event_idx += 1; |
| 190 | } |
| 191 | |
| 192 | return Ok(num_events_written); |
| 193 | } |
| 194 | |
| 195 | #[with_ghost_var(trace: &mut Trace)] |
| 196 | #[requires(ctx_safe(ctx))] |
no test coverage detected