From 8e0ef954f5907acdd98334cf5b93bc603971c5cf Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 19 May 2013 23:01:41 +1200 Subject: [PATCH] Added relaxed atomics and used them in the global heap --- src/libcore/rt/global_heap.rs | 20 +++++++++++++++++--- src/libcore/unstable/intrinsics.rs | 6 ++++++ src/librustc/middle/trans/foreign.rs | 16 +++++++++++++++- src/librustc/middle/trans/type_use.rs | 1 + src/librustc/middle/typeck/check/mod.rs | 1 + 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/libcore/rt/global_heap.rs b/src/libcore/rt/global_heap.rs index ce7ff87b44580..0c850e6d42ec7 100644 --- a/src/libcore/rt/global_heap.rs +++ b/src/libcore/rt/global_heap.rs @@ -14,10 +14,24 @@ use c_malloc = libc::malloc; use c_free = libc::free; use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; -use unstable::intrinsics::{atomic_xadd,atomic_xsub}; use ptr::null; use intrinsic::TyDesc; +#[cfg(stage0)] +use unstable::intrinsics::{atomic_xadd,atomic_xsub}; +#[cfg(not(stage0))] +use unstable::intrinsics::{atomic_xadd_relaxed,atomic_xsub_relaxed}; + +#[cfg(stage0)] +unsafe fn atomic_xadd_relaxed(dst:&mut int, src:int) -> int { + atomic_xadd(dst, src) +} + +#[cfg(stage0)] +unsafe fn atomic_xsub_relaxed(dst:&mut int, src:int) -> int { + atomic_xsub(dst, src) +} + pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { assert!(td.is_not_null()); @@ -35,7 +49,7 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { box.header.next = null(); let exchange_count = &mut *exchange_count_ptr(); - atomic_xadd(exchange_count, 1); + atomic_xadd_relaxed(exchange_count, 1); return transmute(box); } @@ -53,7 +67,7 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void { pub unsafe fn free(ptr: *c_void) { let exchange_count = &mut *exchange_count_ptr(); - atomic_xsub(exchange_count, 1); + atomic_xsub_relaxed(exchange_count, 1); assert!(ptr.is_not_null()); c_free(ptr); diff --git a/src/libcore/unstable/intrinsics.rs b/src/libcore/unstable/intrinsics.rs index 1636abedf7a7d..5c8ea198f124c 100644 --- a/src/libcore/unstable/intrinsics.rs +++ b/src/libcore/unstable/intrinsics.rs @@ -69,6 +69,9 @@ pub extern "rust-intrinsic" { pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int; /// Atomic addition, release ordering. pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int; + /// Atomic addition, relaxed ordering + #[cfg(not(stage0))] + pub fn atomic_xadd_relaxed(dst: &mut int, src: int) -> int; /// Atomic subtraction, sequentially consistent. pub fn atomic_xsub(dst: &mut int, src: int) -> int; @@ -76,6 +79,9 @@ pub extern "rust-intrinsic" { pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int; /// Atomic subtraction, release ordering. pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int; + /// Atomic subtraction, relaxed ordering + #[cfg(not(stage0))] + pub fn atomic_xsub_relaxed(dst: &mut int, src: int) -> int; /// The size of a type in bytes. /// diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 13d8f854fb20f..97afd40850053 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -9,7 +9,7 @@ // except according to those terms. use back::{link, abi}; -use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; +use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg, Monotonic}; use lib::llvm::{TypeRef, ValueRef}; use lib; use middle::trans::base::*; @@ -657,6 +657,13 @@ pub fn trans_intrinsic(ccx: @CrateContext, Release); Store(bcx, old, fcx.llretptr.get()); } + ~"atomic_xadd_relaxed" => { + let old = AtomicRMW(bcx, lib::llvm::Add, + get_param(decl, first_real_arg), + get_param(decl, first_real_arg + 1u), + Monotonic); + Store(bcx, old, fcx.llretptr.get()); + } ~"atomic_xsub" => { let old = AtomicRMW(bcx, lib::llvm::Sub, get_param(decl, first_real_arg), @@ -678,6 +685,13 @@ pub fn trans_intrinsic(ccx: @CrateContext, Release); Store(bcx, old, fcx.llretptr.get()); } + ~"atomic_xsub_relaxed" => { + let old = AtomicRMW(bcx, lib::llvm::Sub, + get_param(decl, first_real_arg), + get_param(decl, first_real_arg + 1u), + Monotonic); + Store(bcx, old, fcx.llretptr.get()); + } ~"size_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 4a8adfba11c31..92d5ca93e235f 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -130,6 +130,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint) ~"atomic_xadd" | ~"atomic_xsub" | ~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" | ~"atomic_xchg_rel" | + ~"atomic_xadd_relaxed" | ~"atomic_xsub_relaxed" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => 0, ~"visit_tydesc" | ~"forget" | ~"frame_address" | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 6e272b9410f49..3106b50003ecb 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3498,6 +3498,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { ty::mk_nil()) } ~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" | + ~"atomic_xadd_relaxed" | ~"atomic_xsub_relaxed" | ~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" | ~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => { (0,