// diff_fast corpus program: the Sandbox race kit's wire pack (RaceKit::pack -> Race::to_wire().ser_bin(out), // micro_serde's derived SerBin: per-field to_le_bytes + extend_from_slice / push, Vec = u64 length then // items, [u32; 6] arrays, Option), into one reused buffer that is cleared per instance and compared // with the last sent bytes (HostSession::send_kit_instances). Relax O3 took a bus error in pack, writing // at a page boundary, in a hosted race session. // rustc --test -O and `makepad test` (all tiers) must print identical D lines. macro_rules! d { ($($a:tt)*) => { println!("D {}", format!($($a)*)) } } trait SerBin { fn ser_bin(&self, s: &mut Vec); } macro_rules! le { ($($t:ty),*) => { $(impl SerBin for $t { fn ser_bin(&self, s: &mut Vec) { s.extend_from_slice(&self.to_le_bytes()); } })* } } le!(f32, u64, u32, i32); impl SerBin for u8 { fn ser_bin(&self, s: &mut Vec) { s.push(*self); } } impl SerBin for bool { fn ser_bin(&self, s: &mut Vec) { s.push(if *self { 1 } else { 0 }); } } impl SerBin for Vec { fn ser_bin(&self, s: &mut Vec) { let len = self.len() as u64; len.ser_bin(s); for item in self { item.ser_bin(s); } } } impl SerBin for Option { fn ser_bin(&self, s: &mut Vec) { match self { None => s.push(0), Some(v) => { s.push(1); v.ser_bin(s); } } } } impl SerBin for [T] { fn ser_bin(&self, s: &mut Vec) { for item in self { item.ser_bin(s); } } } impl SerBin for [T; N] { fn ser_bin(&self, s: &mut Vec) { self.as_slice().ser_bin(s) } } macro_rules! wire { ($name:ident { $($f:ident: $t:ty),* $(,)? }) => { #[derive(Clone, Debug, PartialEq)] struct $name { $($f: $t),* } impl SerBin for $name { fn ser_bin(&self, s: &mut Vec) { $(self.$f.ser_bin(s);)* } } } } const MAX_SECTORS: usize = 6; #[derive(Clone, Copy, Debug, Default, PartialEq)] struct V3 { x: f32, y: f32, z: f32 } #[derive(Clone, Copy)] struct SpawnPoint { pos: V3, yaw: f32, owner: u64 } #[derive(Clone, Copy)] struct Checkpoint { pos: V3, half: V3, #[allow(dead_code)] index: u32, entity: u64 } #[derive(Clone, Copy, Default)] struct LapTiming { started: bool, lap_start: u32, sector_start: u32, sector: u8, sectors: [u32; MAX_SECTORS], last_sectors: [u32; MAX_SECTORS], best_sectors: [u32; MAX_SECTORS], last_lap: u32, best_lap: u32, laps_timed: u32, gate_ms: u32, delta: i32, has_delta: bool, total: u32, gap_ahead: u32, gap_behind: u32, progress_ms: u32, } #[derive(Clone, Copy)] struct Standing { entity: u64, lap: u32, checkpoint: u32, progress: u32, finished: bool, finish_tick: u64, score: i32, timing: LapTiming, waiting: bool, hold_end: u64 } struct Race { spawns: Vec, checkpoints: Vec, standings: Vec, laps: u32, running: bool, winner: u64, circuit: bool, sectors: u32, hold_ticks: Option, hold_end: u64, release_tick: u64, fastest: (u64, u32), } wire!(TimingWire { started: bool, lap_start: u32, sector_start: u32, sector: u8, sectors: [u32; MAX_SECTORS], last_sectors: [u32; MAX_SECTORS], best_sectors: [u32; MAX_SECTORS], last_lap: u32, best_lap: u32, laps_timed: u32, gate_ms: u32, delta: i32, has_delta: bool, total: u32, gap_ahead: u32, gap_behind: u32, progress_ms: u32 }); wire!(StandingWire { entity: u64, lap: u32, checkpoint: u32, progress: u32, finished: bool, finish_tick: u64, score: i32, waiting: bool, hold_end: u64, timing: TimingWire }); wire!(GateWire { pos: [f32; 3], half: [f32; 3], entity: u64 }); wire!(SlotWire { pos: [f32; 3], yaw: f32, owner: u64 }); wire!(RaceWire { gates: Vec, slots: Vec, hold_ticks: Option, laps: u32, running: bool, winner: u64, circuit: bool, sectors: u32, hold_end: u64, release_tick: u64, fastest_entity: u64, fastest_ms: u32, standings: Vec }); impl Race { fn to_wire(&self) -> RaceWire { RaceWire { gates: self.checkpoints.iter().map(|c| GateWire { pos: [c.pos.x, c.pos.y, c.pos.z], half: [c.half.x, c.half.y, c.half.z], entity: c.entity }).collect(), slots: self.spawns.iter().map(|s| SlotWire { pos: [s.pos.x, s.pos.y, s.pos.z], yaw: s.yaw, owner: s.owner }).collect(), hold_ticks: self.hold_ticks, laps: self.laps, running: self.running, winner: self.winner, circuit: self.circuit, sectors: self.sectors, hold_end: self.hold_end, release_tick: self.release_tick, fastest_entity: self.fastest.0, fastest_ms: self.fastest.1, standings: self.standings.iter().map(|s| StandingWire { entity: s.entity, lap: s.lap, checkpoint: s.checkpoint, progress: s.progress, finished: s.finished, finish_tick: s.finish_tick, score: s.score, waiting: s.waiting, hold_end: s.hold_end, timing: { let t = &s.timing; TimingWire { started: t.started, lap_start: t.lap_start, sector_start: t.sector_start, sector: t.sector, sectors: t.sectors, last_sectors: t.last_sectors, best_sectors: t.best_sectors, last_lap: t.last_lap, best_lap: t.best_lap, laps_timed: t.laps_timed, gate_ms: t.gate_ms, delta: t.delta, has_delta: t.has_delta, total: t.total, gap_ahead: t.gap_ahead, gap_behind: t.gap_behind, progress_ms: t.progress_ms } }, }).collect(), } } } struct Kit { instances: Vec, ids: Vec } impl Kit { fn get(&self, id: u32) -> Option<&Race> { self.ids.binary_search(&id).ok().map(|i| &self.instances[i]) } #[inline(never)] fn pack(&self, i: u32, out: &mut Vec) { if let Some(race) = self.get(i) { race.to_wire().ser_bin(out); } } } fn race(seed: u32, gates: usize, racers: usize) -> Race { let f = |k: u32| (seed.wrapping_mul(2654435761).wrapping_add(k.wrapping_mul(40503)) % 1000) as f32 * 0.25; Race { spawns: (0..racers.max(4)).map(|k| SpawnPoint { pos: V3 { x: f(k as u32), y: 1.0, z: -f(k as u32 + 7) }, yaw: f(k as u32 + 3), owner: if k < racers { 1000 + k as u64 } else { 0 } }).collect(), checkpoints: (0..gates).map(|k| Checkpoint { pos: V3 { x: f(k as u32), y: 0.5, z: f(k as u32 + 1) }, half: V3 { x: 4.0, y: 2.0, z: 0.5 }, index: k as u32, entity: 500 + k as u64 }).collect(), standings: (0..racers).map(|k| { let mut t = LapTiming::default(); t.started = k % 2 == 0; t.lap_start = seed * 16 + k as u32; t.sector = (k % MAX_SECTORS) as u8; for s in 0..MAX_SECTORS { t.sectors[s] = seed + s as u32; t.last_sectors[s] = seed * 2 + s as u32; t.best_sectors[s] = seed * 3 + k as u32; } t.delta = k as i32 - 3; t.has_delta = k % 3 == 0; t.gap_ahead = seed ^ k as u32; t.progress_ms = seed * 7; Standing { entity: 1000 + k as u64, lap: seed % 4, checkpoint: k as u32, progress: seed + k as u32, finished: k == 0 && seed % 5 == 0, finish_tick: seed as u64 * 3, score: -(k as i32), timing: t, waiting: seed % 2 == 1, hold_end: 180 + seed as u64 } }).collect(), laps: 3, running: seed % 7 != 0, winner: if seed % 5 == 0 { 1000 } else { 0 }, circuit: seed % 2 == 0, sectors: 3, hold_ticks: if seed % 3 == 0 { None } else { Some(seed % 200) }, hold_end: 180 + seed as u64, release_tick: seed as u64, fastest: (1000 + (seed % 4) as u64, seed * 11), } } struct Host { kit_buf: Vec, sent: Vec<(u32, Vec)> } impl Host { #[inline(never)] fn send(&mut self, kit: &Kit) -> (usize, u64) { let mut buf = std::mem::take(&mut self.kit_buf); let mut changed = 0; let mut sum = 0u64; let mut each = |i: u32| { buf.clear(); kit.pack(i, &mut buf); for (k, b) in buf.iter().enumerate() { sum = sum.wrapping_mul(31).wrapping_add(*b as u64 ^ k as u64); } match self.sent.iter_mut().find(|(id, _)| *id == i) { Some((_, s)) if *s == buf => {} Some((_, s)) => { *s = buf.clone(); changed += 1; } None => { self.sent.push((i, buf.clone())); changed += 1; } } }; for &i in &kit.ids { each(i); } self.kit_buf = buf; (changed, sum) } } fn work() { let mut host = Host { kit_buf: Vec::new(), sent: Vec::new() }; let mut total = 0u64; for tick in 0..400u32 { let n = 1 + (tick as usize / 50) % 3; let kit = Kit { instances: (0..n).map(|r| race(tick / 3 + r as u32, 8 + (r * 13 + tick as usize / 20) % 40, 1 + (tick as usize / 10 + r) % 12)).collect(), ids: (1..=n as u32).collect(), }; let (c, s) = host.send(&kit); total = total.wrapping_add(s ^ c as u64); if tick % 50 == 0 { d!("tick {} kits {} changed {} sum {:x} cap>=len {}", tick, n, c, s, host.kit_buf.capacity() >= host.kit_buf.len()); } } let lens: Vec = host.sent.iter().map(|(_, b)| b.len()).collect(); d!("total {:x} lens {:?}", total, lens); } fn rounds(f: fn()) { let ms: u64 = 4 * std::env::var("DIFF_SLEEP_MS").ok().and_then(|v| v.parse::().ok()).unwrap_or(0); for r in 0..4 { f(); if r < 3 && ms > 0 { std::thread::sleep(std::time::Duration::from_millis(ms)); } } } #[test] fn run() { rounds(work); }