add (cas), (casXX), and (bfcas)

This commit is contained in:
2020-10-28 22:48:25 +01:00
parent 4e67ac291f
commit d0d4f1c15e
8 changed files with 130 additions and 0 deletions
+1
View File
@@ -45,6 +45,7 @@ pub enum BufOps {
Write { obj: RdObj, idx: Rd, value: Rd },
Insert { obj: RdObj, idx: Rd, value: Rd },
Remove { dst: Wr, obj: RdObj, idx: Rd },
CompareSwap { obj: RdObj, idx: Rd, expected: Rd, src: Rd },
// Whole buffer ops
Resize { obj: RdObj, len: Rd },
+31
View File
@@ -138,6 +138,33 @@ impl OpTrait for BufOps {
}
}
BufOps::CompareSwap { obj, idx, expected, src } => {
state.clear_status();
let handle = state.read_obj(obj)?;
let idx = state.read(idx)? as usize;
let expected = state.read(expected)?;
let store: &mut ExtData = state.ext_mut();
let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
if idx < buf.data.len() {
if buf.data[idx] == expected {
// This looks stupid and it is stupid - the dance is needed to satisfy the borrow checker.
let val = state.read(src)?;
let store: &mut ExtData = state.ext_mut();
let buf = store.buffers.get_mut(&handle).unwrap();
buf.data[idx] = val;
state.set_flag(Flag::Equal, true);
}
} else if idx == buf.data.len() && expected == 0 {
let val = state.read(src)?;
let store: &mut ExtData = state.ext_mut();
let buf = store.buffers.get_mut(&handle).unwrap();
buf.data.push_back(val);
state.set_flag(Flag::Equal, true);
} else {
state.set_flag(Flag::Overflow, true);
}
}
BufOps::Insert { obj, idx, value } => {
state.clear_status();
let handle = state.read_obj(obj)?;
@@ -255,6 +282,10 @@ impl OpTrait for BufOps {
sexp::list(&[A("bfwr"), A(obj), A(idx), A(value)])
}
BufOps::CompareSwap { obj, idx, expected , src } => {
sexp::list(&[A("bfcas"), A(obj), A(idx), A(expected), A(src)])
}
BufOps::Insert { obj, idx, value } => {
sexp::list(&[A("bfins"), A(obj), A(idx), A(value)])
}
+8
View File
@@ -75,6 +75,14 @@ pub(crate) fn parse<'a>(_pos: &SourcePosition, keyword: &str, mut args: TokenPar
BufOps::Write { obj, idx, value }
}
"bfcas" => {
let obj = args.next_rdobj()?;
let idx = args.next_rd()?;
let expected = args.next_rd()?;
let src = args.next_rd()?;
BufOps::CompareSwap { obj, idx, expected, src }
}
"bfsz" => {
let dst = args.next_wr()?;
let obj = args.next_rdobj()?;