Skip to content

Instantly share code, notes, and snippets.

@spacejam
Created January 2, 2018 15:11
Show Gist options
  • Save spacejam/5744a52778e0794001fdf7f7dd6d2e98 to your computer and use it in GitHub Desktop.
Save spacejam/5744a52778e0794001fdf7f7dd6d2e98 to your computer and use it in GitHub Desktop.
#![feature(asm)]
#![feature(i128_type)]
fn cas128(val: &mut u128, old: u128, new: u128) -> Result<u128, u128> {
// old
let rdx: u64 = (old >> 64) as u64;
let rax: u64 = old as u64;
// new
let rcx: u64 = (new >> 64) as u64;
let rbx: u64 = new as u64;
// output
let rdx_out: u64;
let rax_out: u64;
let success: u8;
unsafe {
asm!(
"lock; cmpxchg16b $3; sete $0"
: "=r" (success)
, "={rdx}" (rdx_out)
, "={rax}" (rax_out)
: "*m" (val)
, "{rdx}" (rdx)
, "{rax}" (rax)
, "{rcx}" (rcx)
, "{rbx}" (rbx)
: "memory"
: "alignstack"
)
};
let current = (rdx_out as u128) << 64 | rax_out as u128;
if success == 1 {
Ok(current)
} else {
Err(current)
}
}
fn main() {
let mut vals = vec![0u128; 2];
let mut val = &mut vals[1];
println!("align of val: {:?}", std::mem::align_of::<u128>());
cas128(&mut val, 0, 1 << 65).unwrap();
cas128(&mut val, 3, 2).unwrap_err();
cas128(&mut val, 1 << 65, 0).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment