Skip to content

Commit c4e5d58

Browse files
authored
Merge pull request #37 from jonhoo/miri-ci
Add miri CI test
2 parents 9544337 + 12bcddc commit c4e5d58

File tree

3 files changed

+70
-5
lines changed

3 files changed

+70
-5
lines changed

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ azure-devops = { project = "jonhoo/jonhoo", pipeline = "flurry", build = "15" }
1919
codecov = { repository = "jonhoo/flurry", branch = "master", service = "github" }
2020
maintenance = { status = "experimental" }
2121

22+
[features]
23+
sanitize = ['crossbeam-epoch/sanitize']
24+
2225
[dependencies]
23-
crossbeam-epoch = "0.8"
26+
crossbeam-epoch = "0.9"
2427
parking_lot = "0.10"
2528
num_cpus = "1.12.0"
2629

2730
[dev-dependencies]
2831
rand = "0.7"
32+
33+
[patch.crates-io]
34+
crossbeam-epoch = { git = "https://github.com/cynecx/crossbeam.git", branch = "fix-unsoundness" }

azure-pipelines.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,57 @@ jobs:
2929
condition: ne(variables.CACHE_RESTORED, 'true')
3030
- script: cargo deny check
3131
displayName: cargo deny
32+
- job: miri
33+
displayName: "Run miri on test suite"
34+
dependsOn: deny
35+
continueOnError: true # since miri sometimes isn't on nightly
36+
pool:
37+
vmImage: ubuntu-16.04
38+
steps:
39+
- template: install-rust.yml@templates
40+
parameters:
41+
rust: nightly
42+
components:
43+
- miri
44+
# ignore leaks due to https://github.com/crossbeam-rs/crossbeam/issues/464
45+
- bash: yes | cargo miri -Zmiri-ignore-leaks test
46+
displayName: cargo miri test
47+
- job: asan
48+
dependsOn: deny
49+
displayName: "Run address sanitizer on test suite"
50+
pool:
51+
vmImage: ubuntu-16.04
52+
steps:
53+
- template: install-rust.yml@templates
54+
parameters:
55+
rust: nightly
56+
- bash: |
57+
sudo ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer
58+
sed -i '/\[features\]/i [profile.dev]' Cargo.toml
59+
sed -i '/profile.dev/a opt-level = 1' Cargo.toml
60+
cat Cargo.toml
61+
displayName: Enable debug symbols
62+
- script: |
63+
env ASAN_OPTIONS="detect_odr_violation=0" RUSTFLAGS="-Z sanitizer=address" cargo test --features sanitize --target x86_64-unknown-linux-gnu
64+
displayName: cargo -Z sanitizer=address test
65+
- job: lsan
66+
dependsOn: deny
67+
displayName: "Run leak sanitizer on test suite"
68+
pool:
69+
vmImage: ubuntu-16.04
70+
steps:
71+
- template: install-rust.yml@templates
72+
parameters:
73+
rust: nightly
74+
- bash: |
75+
sudo ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer
76+
sed -i '/\[features\]/i [profile.dev]' Cargo.toml
77+
sed -i '/profile.dev/a opt-level = 1' Cargo.toml
78+
cat Cargo.toml
79+
displayName: Enable debug symbols
80+
- script: |
81+
env RUSTFLAGS="-Z sanitizer=leak" cargo test --features sanitize --target x86_64-unknown-linux-gnu
82+
displayName: cargo -Z sanitizer=leak test
3283
3384
resources:
3485
repositories:

src/map.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,15 +1176,16 @@ where
11761176

11771177
// just remove the node if the value is the one we expected at method call
11781178
if observed_value.map(|ov| ov == ev).unwrap_or(true) {
1179+
// we remember the old value so that we can return it and mark it for deletion below
1180+
old_val = Some(ev);
1181+
11791182
// found the node but we have a new value to replace the old one
11801183
if let Some(nv) = new_value {
11811184
n.value.store(Owned::new(nv), Ordering::SeqCst);
11821185
// we are just replacing entry value and we do not want to remove the node
11831186
// so we stop iterating here
11841187
break;
11851188
}
1186-
// we remember the old value so that we can return it and mark it for deletion below
1187-
old_val = Some(ev);
11881189
// remove the BinEntry containing the removed key value pair from the bucket
11891190
if !pred.is_null() {
11901191
// either by changing the pointer of the previous BinEntry, if present
@@ -1512,6 +1513,7 @@ where
15121513
}
15131514
}
15141515

1516+
#[cfg(not(miri))]
15151517
#[inline]
15161518
/// Returns the number of physical CPUs in the machine (_O(1)_).
15171519
fn num_cpus() -> usize {
@@ -1520,6 +1522,12 @@ fn num_cpus() -> usize {
15201522
NCPU.load(Ordering::Relaxed)
15211523
}
15221524

1525+
#[cfg(miri)]
1526+
#[inline]
1527+
const fn num_cpus() -> usize {
1528+
1
1529+
}
1530+
15231531
#[test]
15241532
fn capacity() {
15251533
let map = HashMap::<usize, usize>::new();
@@ -1694,7 +1702,7 @@ fn replace_existing() {
16941702
let guard = epoch::pin();
16951703
map.insert(42, 42, &guard);
16961704
let old = map.replace_node(&42, Some(10), None, &guard);
1697-
assert!(old.is_none());
1705+
assert_eq!(old, Some(&42));
16981706
assert_eq!(*map.get(&42, &guard).unwrap(), 10);
16991707
}
17001708
}
@@ -1707,7 +1715,7 @@ fn replace_existing_observed_value_matching() {
17071715
map.insert(42, 42, &guard);
17081716
let observed_value = Shared::from(map.get(&42, &guard).unwrap() as *const _);
17091717
let old = map.replace_node(&42, Some(10), Some(observed_value), &guard);
1710-
assert!(old.is_none());
1718+
assert_eq!(old, Some(&42));
17111719
assert_eq!(*map.get(&42, &guard).unwrap(), 10);
17121720
}
17131721
}

0 commit comments

Comments
 (0)