fixed test

This commit is contained in:
mamoniot 2022-12-26 23:05:59 -05:00
parent 4b6bf0a4ad
commit 2c07136b5e
2 changed files with 44 additions and 22 deletions

View file

@ -142,7 +142,6 @@ impl CounterWindow {
//atomic instructions are only ever atomic within themselves; //atomic instructions are only ever atomic within themselves;
//sequentially consistent atomics do not guarantee that the thread is not preempted between individual atomic instructions //sequentially consistent atomics do not guarantee that the thread is not preempted between individual atomic instructions
if let Some(history) = self.0.lock().unwrap().as_mut() { if let Some(history) = self.0.lock().unwrap().as_mut() {
const NONCE_MAX_DELTA: i64 = (2*COUNTER_MAX_ALLOWED_OOO as i64).wrapping_shl(32);
let mut is_in = false; let mut is_in = false;
let mut idx = 0; let mut idx = 0;
let mut smallest = fragment_nonce; let mut smallest = fragment_nonce;
@ -155,7 +154,7 @@ impl CounterWindow {
idx = i; idx = i;
} }
} }
if !is_in & (smallest != fragment_nonce) & ((fragment_nonce as i64).wrapping_sub(smallest as i64) < NONCE_MAX_DELTA) { if !is_in & (smallest != fragment_nonce) {
history[idx] = fragment_nonce; history[idx] = fragment_nonce;
return true return true
} }
@ -164,4 +163,28 @@ impl CounterWindow {
return true return true
} }
} }
#[inline(always)]
pub fn purge(&self, inauthentic_counter_value: u32, inauthentic_fragment_no: u8) {
let inauthentic_nonce = (inauthentic_counter_value as u64).wrapping_shl(32) | (inauthentic_fragment_no as u64);
//everything past this point must be atomic, i.e. these instructions must be run mutually exclusive to completion;
//atomic instructions are only ever atomic within themselves;
//sequentially consistent atomics do not guarantee that the thread is not preempted between individual atomic instructions
if let Some(history) = self.0.lock().unwrap().as_mut() {
let mut idx = 0;
let mut smallest = history[0];
for i in 0..history.len() {
let nonce = history[i];
if nonce == inauthentic_nonce {
idx = i;
} else {
let delta = (smallest as i64).wrapping_sub(nonce as i64);
if delta > 0 {
smallest = nonce;
}
}
}
history[idx] = smallest;
}
}
} }

View file

@ -228,42 +228,41 @@ mod tests {
} }
#[test] #[test]
fn counter_window() { fn counter_window() {
let sqrt_out_of_order_max = (COUNTER_MAX_ALLOWED_OOO as f32).sqrt() as u32; let mut rng = 415263;
let mut rng = 1027;//8234
let mut counter = u32::MAX - 16; let mut counter = u32::MAX - 16;
let mut fragment_no: u8 = 0; let mut fragment_no: u8 = 0;
let mut history = Vec::<(u32, u8)>::new(); let mut history = Vec::<(u32, u8)>::new();
let mut w = CounterWindow::new(counter.wrapping_sub(1)); let mut w = CounterWindow::new(counter.wrapping_sub(1));
for i in 1..1000000 { for i in 0..1000000 {
let p = xorshift64(&mut rng)%1000; let p = xorshift64(&mut rng) as f32/(u32::MAX as f32 + 1.0);
let c; let c;
let f; let f;
if p < 200 { if p < 0.5 {
let r = xorshift64(&mut rng); let r = xorshift64(&mut rng);
c = counter.wrapping_add(r%sqrt_out_of_order_max); c = counter.wrapping_add(r%(COUNTER_MAX_ALLOWED_OOO - 2) as u32 + 1);
f = fragment_no + 1 + ((r/sqrt_out_of_order_max)%sqrt_out_of_order_max) as u8; f = 0;
} else if p < 400 { } else if p < 0.7 {
fragment_no = u8::min(fragment_no + 1, 63);
c = counter;
f = fragment_no;
} else if p < 0.8 {
counter = counter.wrapping_add(1);
fragment_no = 0;
c = counter;
f = fragment_no;
} else if p < 0.9 {
if history.len() > 0 { if history.len() > 0 {
let idx = xorshift64(&mut rng) as usize%history.len(); let idx = xorshift64(&mut rng) as usize%history.len();
let (c, f) = history[idx]; let (c, f) = history[idx];
assert!(!w.message_received(c, f)); assert!(!w.message_received(c, f));
} }
continue; continue;
} else if p < 650 { } else if p < 0.9995 {
fragment_no = u8::min(fragment_no + 1, 63); c = counter.wrapping_add(xorshift64(&mut rng)%999);
c = counter;
f = fragment_no;
} else if p < 900 {
counter = counter.wrapping_add(1);
fragment_no = 0;
c = counter;
f = fragment_no;
} else if p < 999 {
c = xorshift64(&mut rng);
f = (xorshift64(&mut rng)%64) as u8; f = (xorshift64(&mut rng)%64) as u8;
if w.message_received(c, f) { if w.message_received(c, f) {
history.push((c, f)); w.purge(c, f);
} }
continue; continue;
} else { } else {