From e2091ff93481c5e1c41da26ea202c911c1140a0c Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 15 Nov 2016 15:19:38 +0100 Subject: [PATCH] add more atomic intrinsics --- src/interpreter/terminator/intrinsics.rs | 48 ++++++++++++++++++++++++ tests/run-pass/sendable-class.rs | 34 +++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 tests/run-pass/sendable-class.rs diff --git a/src/interpreter/terminator/intrinsics.rs b/src/interpreter/terminator/intrinsics.rs index bc258574665..5cea0bc2d0c 100644 --- a/src/interpreter/terminator/intrinsics.rs +++ b/src/interpreter/terminator/intrinsics.rs @@ -57,6 +57,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { } "atomic_load" | + "atomic_load_acq" | "volatile_load" => { let ty = substs.type_at(0); let ptr = arg_vals[0].read_ptr(&self.memory)?; @@ -74,6 +75,53 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { // we are inherently singlethreaded and singlecored, this is a nop } + "atomic_xchg" => { + let ty = substs.type_at(0); + let ptr = arg_vals[0].read_ptr(&self.memory)?; + let change = self.value_to_primval(arg_vals[1], ty)?; + let old = self.read_value(ptr, ty)?; + let old = match old { + Value::ByVal(val) => val, + Value::ByRef(_) => bug!("just read the value, can't be byref"), + Value::ByValPair(..) => bug!("atomic_xchg doesn't work with nonprimitives"), + }; + self.write_primval(dest, old)?; + self.write_primval(Lvalue::from_ptr(ptr), change)?; + } + + "atomic_cxchg" => { + let ty = substs.type_at(0); + let ptr = arg_vals[0].read_ptr(&self.memory)?; + let expect_old = self.value_to_primval(arg_vals[1], ty)?; + let change = self.value_to_primval(arg_vals[2], ty)?; + let old = self.read_value(ptr, ty)?; + let old = match old { + Value::ByVal(val) => val, + Value::ByRef(_) => bug!("just read the value, can't be byref"), + Value::ByValPair(..) => bug!("atomic_cxchg doesn't work with nonprimitives"), + }; + let (val, _) = primval::binary_op(mir::BinOp::Eq, old, expect_old)?; + let dest = self.force_allocation(dest)?.to_ptr(); + self.write_pair_to_ptr(old, val, dest, dest_ty)?; + self.write_primval(Lvalue::from_ptr(ptr), change)?; + } + + "atomic_xadd_relaxed" => { + let ty = substs.type_at(0); + let ptr = arg_vals[0].read_ptr(&self.memory)?; + let change = self.value_to_primval(arg_vals[1], ty)?; + let old = self.read_value(ptr, ty)?; + let old = match old { + Value::ByVal(val) => val, + Value::ByRef(_) => bug!("just read the value, can't be byref"), + Value::ByValPair(..) => bug!("atomic_xadd_relaxed doesn't work with nonprimitives"), + }; + self.write_primval(dest, old)?; + // FIXME: what do atomics do on overflow? + let (val, _) = primval::binary_op(mir::BinOp::Add, old, change)?; + self.write_primval(Lvalue::from_ptr(ptr), val)?; + }, + "atomic_xsub_rel" => { let ty = substs.type_at(0); let ptr = arg_vals[0].read_ptr(&self.memory)?; diff --git a/tests/run-pass/sendable-class.rs b/tests/run-pass/sendable-class.rs new file mode 100644 index 00000000000..b3e07d00f01 --- /dev/null +++ b/tests/run-pass/sendable-class.rs @@ -0,0 +1,34 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that a class with only sendable fields can be sent + +// pretty-expanded FIXME #23616 + +use std::sync::mpsc::channel; + +#[allow(dead_code)] +struct Foo { + i: isize, + j: char, +} + +fn foo(i:isize, j: char) -> Foo { + Foo { + i: i, + j: j + } +} + +pub fn main() { + let (tx, rx) = channel(); + let _ = tx.send(foo(42, 'c')); + let _ = rx; +}