Skip to content

Commit

Permalink
std: Make atomics immutable. rust-lang#11583
Browse files Browse the repository at this point in the history
In Rust, the strongest guarantee that `&mut` provides is that the memory
pointed to is *not aliased*, whereas `&`'s guarantees are much weaker:
that the value can be aliased, and may be mutated under proper precautions
(interior mutability).

Our atomics though use `&mut` for mutation even while creating multiple
aliases, so this changes them to use 'interior mutability', mutating
through immutable references.
  • Loading branch information
brson authored and alexcrichton committed Mar 20, 2014
1 parent c01e2f0 commit f3fef9a
Show file tree
Hide file tree
Showing 7 changed files with 1,093 additions and 71 deletions.
6 changes: 3 additions & 3 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4012,7 +4012,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {

//We only care about the operation here
match *split.get(1) {
"cxchg" => (1, vec!(ty::mk_mut_rptr(tcx,
"cxchg" => (1, vec!(ty::mk_imm_rptr(tcx,
ty::ReLateBound(it.id, ty::BrAnon(0)),
param(ccx, 0)),
param(ccx, 0),
Expand All @@ -4025,15 +4025,15 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
param(ccx, 0)),
"store" => (1,
vec!(
ty::mk_mut_rptr(tcx, ty::ReLateBound(it.id, ty::BrAnon(0)),
ty::mk_imm_rptr(tcx, ty::ReLateBound(it.id, ty::BrAnon(0)),
param(ccx, 0)),
param(ccx, 0)
),
ty::mk_nil()),

"xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" |
"min" | "umax" | "umin" => {
(1, vec!(ty::mk_mut_rptr(tcx,
(1, vec!(ty::mk_imm_rptr(tcx,
ty::ReLateBound(it.id, ty::BrAnon(0)),
param(ccx, 0)), param(ccx, 0) ),
param(ccx, 0))
Expand Down
88 changes: 88 additions & 0 deletions src/libstd/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ pub trait TyVisitor {
fn visit_self(&mut self) -> bool;
}

#[cfg(stage0)]
extern "rust-intrinsic" {
pub fn atomic_cxchg<T>(dst: &mut T, old: T, src: T) -> T;
pub fn atomic_cxchg_acq<T>(dst: &mut T, old: T, src: T) -> T;
Expand Down Expand Up @@ -244,6 +245,93 @@ extern "rust-intrinsic" {
pub fn atomic_umax_rel<T>(dst: &mut T, src: T) -> T;
pub fn atomic_umax_acqrel<T>(dst: &mut T, src: T) -> T;
pub fn atomic_umax_relaxed<T>(dst: &mut T, src: T) -> T;
}

#[cfg(not(stage0))]
extern "rust-intrinsic" {

pub fn atomic_cxchg<T>(dst: &T, old: T, src: T) -> T;
pub fn atomic_cxchg_acq<T>(dst: &T, old: T, src: T) -> T;
pub fn atomic_cxchg_rel<T>(dst: &T, old: T, src: T) -> T;
pub fn atomic_cxchg_acqrel<T>(dst: &T, old: T, src: T) -> T;
pub fn atomic_cxchg_relaxed<T>(dst: &T, old: T, src: T) -> T;

pub fn atomic_load<T>(src: &T) -> T;
pub fn atomic_load_acq<T>(src: &T) -> T;
pub fn atomic_load_relaxed<T>(src: &T) -> T;

pub fn atomic_store<T>(dst: &T, val: T);
pub fn atomic_store_rel<T>(dst: &T, val: T);
pub fn atomic_store_relaxed<T>(dst: &T, val: T);

pub fn atomic_xchg<T>(dst: &T, src: T) -> T;
pub fn atomic_xchg_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_xchg_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_xchg_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_xchg_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_xadd<T>(dst: &T, src: T) -> T;
pub fn atomic_xadd_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_xadd_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_xadd_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_xadd_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_xsub<T>(dst: &T, src: T) -> T;
pub fn atomic_xsub_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_xsub_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_xsub_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_xsub_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_and<T>(dst: &T, src: T) -> T;
pub fn atomic_and_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_and_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_and_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_and_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_nand<T>(dst: &T, src: T) -> T;
pub fn atomic_nand_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_nand_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_nand_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_nand_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_or<T>(dst: &T, src: T) -> T;
pub fn atomic_or_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_or_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_or_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_or_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_xor<T>(dst: &T, src: T) -> T;
pub fn atomic_xor_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_xor_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_xor_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_xor_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_max<T>(dst: &T, src: T) -> T;
pub fn atomic_max_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_max_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_max_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_max_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_min<T>(dst: &T, src: T) -> T;
pub fn atomic_min_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_min_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_min_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_min_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_umin<T>(dst: &T, src: T) -> T;
pub fn atomic_umin_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_umin_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_umin_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_umin_relaxed<T>(dst: &T, src: T) -> T;

pub fn atomic_umax<T>(dst: &T, src: T) -> T;
pub fn atomic_umax_acq<T>(dst: &T, src: T) -> T;
pub fn atomic_umax_rel<T>(dst: &T, src: T) -> T;
pub fn atomic_umax_acqrel<T>(dst: &T, src: T) -> T;
pub fn atomic_umax_relaxed<T>(dst: &T, src: T) -> T;
}

extern "rust-intrinsic" {

pub fn atomic_fence();
pub fn atomic_fence_acq();
Expand Down
Loading

0 comments on commit f3fef9a

Please sign in to comment.