Skip to content

Commit b2af873

Browse files
committed
Merge remote-tracking branch 'luqmana/incoming'
2 parents f7c6f86 + ed447a7 commit b2af873

File tree

12 files changed

+104
-33
lines changed

12 files changed

+104
-33
lines changed

src/libcore/private.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#[doc(hidden)];
77

8-
use compare_and_swap = rustrt::rust_compare_and_swap_ptr;
98
use task::TaskBuilder;
109
use task::atomically;
1110

@@ -14,14 +13,6 @@ extern mod rustrt {
1413
fn rust_task_weaken(ch: rust_port_id);
1514
fn rust_task_unweaken(ch: rust_port_id);
1615

17-
#[rust_stack]
18-
fn rust_atomic_increment(p: &mut libc::intptr_t)
19-
-> libc::intptr_t;
20-
21-
#[rust_stack]
22-
fn rust_atomic_decrement(p: &mut libc::intptr_t)
23-
-> libc::intptr_t;
24-
2516
#[rust_stack]
2617
fn rust_compare_and_swap_ptr(address: &mut libc::uintptr_t,
2718
oldval: libc::uintptr_t,
@@ -33,11 +24,36 @@ extern mod rustrt {
3324
fn rust_unlock_little_lock(lock: rust_little_lock);
3425
}
3526

27+
#[abi = "rust-intrinsic"]
28+
extern mod rusti {
29+
30+
#[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)]
31+
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
32+
fn atomic_xadd(dst: &mut int, src: int) -> int;
33+
fn atomic_xsub(dst: &mut int, src: int) -> int;
34+
}
35+
3636
#[allow(non_camel_case_types)] // runtime type
3737
type rust_port_id = uint;
3838

3939
type GlobalPtr = *libc::uintptr_t;
4040

41+
// TODO: Remove once snapshots have atomic_cxchg
42+
#[cfg(stage0)]
43+
fn compare_and_swap(address: &mut libc::uintptr_t,
44+
oldval: libc::uintptr_t,
45+
newval: libc::uintptr_t) -> bool {
46+
rustrt::rust_compare_and_swap_ptr(address, oldval, newval)
47+
}
48+
49+
#[cfg(stage1)]
50+
#[cfg(stage2)]
51+
#[cfg(stage3)]
52+
fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
53+
let old = rusti::atomic_cxchg(address, oldval, newval);
54+
old == oldval
55+
}
56+
4157
/**
4258
* Atomically gets a channel from a pointer to a pointer-sized memory location
4359
* or, if no channel exists creates and installs a new channel and sets up a
@@ -85,7 +101,7 @@ pub unsafe fn chan_from_global_ptr<T: Send>(
85101
log(debug,~"BEFORE COMPARE AND SWAP");
86102
let swapped = compare_and_swap(
87103
cast::reinterpret_cast(&global),
88-
0u, cast::reinterpret_cast(&ch));
104+
0, cast::reinterpret_cast(&ch));
89105
log(debug,fmt!("AFTER .. swapped? %?", swapped));
90106

91107
if swapped {
@@ -305,7 +321,7 @@ struct ArcDestruct<T> {
305321
}
306322
do task::unkillable {
307323
let data: ~ArcData<T> = cast::reinterpret_cast(&self.data);
308-
let new_count = rustrt::rust_atomic_decrement(&mut data.count);
324+
let new_count = rusti::atomic_xsub(&mut data.count, 1) - 1;
309325
assert new_count >= 0;
310326
if new_count == 0 {
311327
// Were we really last, or should we hand off to an unwrapper?
@@ -373,8 +389,8 @@ pub unsafe fn unwrap_shared_mutable_state<T: Send>(rc: SharedMutableState<T>)
373389
// Got in. Step 0: Tell destructor not to run. We are now it.
374390
rc.data = ptr::null();
375391
// Step 1 - drop our own reference.
376-
let new_count = rustrt::rust_atomic_decrement(&mut ptr.count);
377-
// assert new_count >= 0;
392+
let new_count = rusti::atomic_xsub(&mut ptr.count, 1) - 1;
393+
//assert new_count >= 0;
378394
if new_count == 0 {
379395
// We were the last owner. Can unwrap immediately.
380396
// Also we have to free the server endpoints.
@@ -452,7 +468,7 @@ pub unsafe fn clone_shared_mutable_state<T: Send>(rc: &SharedMutableState<T>)
452468
-> SharedMutableState<T> {
453469
unsafe {
454470
let ptr: ~ArcData<T> = cast::reinterpret_cast(&(*rc).data);
455-
let new_count = rustrt::rust_atomic_increment(&mut ptr.count);
471+
let new_count = rusti::atomic_xadd(&mut ptr.count, 1) + 1;
456472
assert new_count >= 2;
457473
cast::forget(move ptr);
458474
}

src/rt/rust_builtin.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -830,16 +830,6 @@ rust_compare_and_swap_ptr(intptr_t *address,
830830
return sync::compare_and_swap(address, oldval, newval);
831831
}
832832

833-
extern "C" CDECL intptr_t
834-
rust_atomic_increment(intptr_t *address) {
835-
return sync::increment(address);
836-
}
837-
838-
extern "C" CDECL intptr_t
839-
rust_atomic_decrement(intptr_t *address) {
840-
return sync::decrement(address);
841-
}
842-
843833
extern "C" CDECL void
844834
rust_task_weaken(rust_port_id chan) {
845835
rust_task *task = rust_get_current_task();

src/rt/rustrt.def.in

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,6 @@ rust_dbg_do_nothing
178178
rust_dbg_breakpoint
179179
rust_osmain_sched_id
180180
rust_compare_and_swap_ptr
181-
rust_atomic_increment
182-
rust_atomic_decrement
183181
rust_global_env_chan_ptr
184182
rust_port_take
185183
rust_port_drop
@@ -207,4 +205,4 @@ rust_gc_metadata
207205
rust_uv_ip4_port
208206
rust_uv_ip6_port
209207
rust_uv_tcp_getpeername
210-
rust_uv_tcp_getpeername6
208+
rust_uv_tcp_getpeername6

src/rustc/lib/llvm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,9 @@ extern mod llvm {
843843
Name: *c_char) -> ValueRef;
844844

845845
/* Atomic Operations */
846+
fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
847+
CMP: ValueRef, RHS: ValueRef,
848+
++Order: AtomicOrdering) -> ValueRef;
846849
fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
847850
LHS: ValueRef, RHS: ValueRef,
848851
++Order: AtomicOrdering) -> ValueRef;

src/rustc/middle/trans/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,11 @@ fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
813813
}
814814

815815
// Atomic Operations
816+
fn AtomicCmpXchg(cx: block, dst: ValueRef,
817+
cmp: ValueRef, src: ValueRef,
818+
order: AtomicOrdering) -> ValueRef {
819+
llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
820+
}
816821
fn AtomicRMW(cx: block, op: AtomicBinOp,
817822
dst: ValueRef, src: ValueRef,
818823
order: AtomicOrdering) -> ValueRef {

src/rustc/middle/trans/foreign.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,30 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
799799
Some(substs), Some(item.span));
800800
let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
801801
match ccx.sess.str_of(item.ident) {
802+
~"atomic_cxchg" => {
803+
let old = AtomicCmpXchg(bcx,
804+
get_param(decl, first_real_arg),
805+
get_param(decl, first_real_arg + 1u),
806+
get_param(decl, first_real_arg + 2u),
807+
SequentiallyConsistent);
808+
Store(bcx, old, fcx.llretptr);
809+
}
810+
~"atomic_cxchg_acq" => {
811+
let old = AtomicCmpXchg(bcx,
812+
get_param(decl, first_real_arg),
813+
get_param(decl, first_real_arg + 1u),
814+
get_param(decl, first_real_arg + 2u),
815+
Acquire);
816+
Store(bcx, old, fcx.llretptr);
817+
}
818+
~"atomic_cxchg_rel" => {
819+
let old = AtomicCmpXchg(bcx,
820+
get_param(decl, first_real_arg),
821+
get_param(decl, first_real_arg + 1u),
822+
get_param(decl, first_real_arg + 2u),
823+
Release);
824+
Store(bcx, old, fcx.llretptr);
825+
}
802826
~"atomic_xchg" => {
803827
let old = AtomicRMW(bcx, Xchg,
804828
get_param(decl, first_real_arg),

src/rustc/middle/trans/type_use.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,12 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
9898

9999
~"get_tydesc" | ~"needs_drop" => use_tydesc,
100100

101-
~"atomic_xchg" | ~"atomic_xadd" |
102-
~"atomic_xsub" | ~"atomic_xchg_acq" |
103-
~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
104-
~"atomic_xchg_rel" | ~"atomic_xadd_rel" |
105-
~"atomic_xsub_rel" => 0,
101+
~"atomic_cxchg" | ~"atomic_cxchg_acq"|
102+
~"atomic_cxchg_rel"| ~"atomic_xchg" |
103+
~"atomic_xadd" | ~"atomic_xsub" |
104+
~"atomic_xchg_acq" | ~"atomic_xadd_acq" |
105+
~"atomic_xsub_acq" | ~"atomic_xchg_rel" |
106+
~"atomic_xadd_rel" | ~"atomic_xsub_rel" => 0,
106107

107108
~"visit_tydesc" | ~"forget" | ~"addr_of" |
108109
~"frame_address" | ~"morestack_addr" => 0,

src/rustc/middle/typeck/check.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2638,7 +2638,15 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
26382638
}
26392639
~"needs_drop" => (1u, ~[], ty::mk_bool(tcx)),
26402640
2641-
~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" |
2641+
~"atomic_cxchg" | ~"atomic_cxchg_acq"| ~"atomic_cxchg_rel" => {
2642+
(0u, ~[arg(ast::by_copy,
2643+
ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
2644+
ty::mk_int(tcx))),
2645+
arg(ast::by_copy, ty::mk_int(tcx)),
2646+
arg(ast::by_copy, ty::mk_int(tcx))],
2647+
ty::mk_int(tcx))
2648+
}
2649+
~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" |
26422650
~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
26432651
~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => {
26442652
(0u, ~[arg(ast::by_copy,

src/rustllvm/RustWrapper.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,14 @@ extern "C" LLVMTypeRef LLVMMetadataType(void) {
482482
return LLVMMetadataTypeInContext(LLVMGetGlobalContext());
483483
}
484484

485+
extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
486+
LLVMValueRef target,
487+
LLVMValueRef old,
488+
LLVMValueRef source,
489+
AtomicOrdering order) {
490+
return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
491+
unwrap(source), order));
492+
}
485493
extern "C" LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,
486494
AtomicRMWInst::BinOp op,
487495
LLVMValueRef target,

src/rustllvm/rustllvm.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ LLVMArrayType
8484
LLVMBasicBlockAsValue
8585
LLVMBlockAddress
8686
LLVMBuildAShr
87+
LLVMBuildAtomicCmpXchg
8788
LLVMBuildAtomicRMW
8889
LLVMBuildAdd
8990
LLVMBuildAggregateRet

src/test/auxiliary/cci_intrinsic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
#[abi = "rust-intrinsic"]
33
extern mod rusti {
44
#[legacy_exports];
5+
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
6+
fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
7+
fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
8+
59
fn atomic_xchg(dst: &mut int, src: int) -> int;
610
fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
711
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;

src/test/run-pass/intrinsic-atomics.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#[abi = "rust-intrinsic"]
22
extern mod rusti {
33
#[legacy_exports];
4+
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
5+
fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
6+
fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
7+
48
fn atomic_xchg(dst: &mut int, src: int) -> int;
59
fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
610
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
@@ -17,6 +21,15 @@ extern mod rusti {
1721
fn main() {
1822
let x = ~mut 1;
1923

24+
assert rusti::atomic_cxchg(x, 1, 2) == 1;
25+
assert *x == 2;
26+
27+
assert rusti::atomic_cxchg_acq(x, 1, 3) == 2;
28+
assert *x == 2;
29+
30+
assert rusti::atomic_cxchg_rel(x, 2, 1) == 2;
31+
assert *x == 1;
32+
2033
assert rusti::atomic_xchg(x, 0) == 1;
2134
assert *x == 0;
2235

0 commit comments

Comments
 (0)