add (cas), (casXX), and (bfcas)
This commit is contained in:
@@ -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 },
|
||||
|
||||
@@ -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)])
|
||||
}
|
||||
|
||||
@@ -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()?;
|
||||
|
||||
Reference in New Issue
Block a user