Skip to content

Commit

Permalink
Use wrapping addition for JEC
Browse files Browse the repository at this point in the history
  • Loading branch information
cuviper committed Sep 15, 2020
1 parent 4a26ac4 commit e768237
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
18 changes: 18 additions & 0 deletions rayon-core/src/join/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,21 @@ fn join_context_second() {
assert!(!a_migrated);
assert!(b_migrated);
}

#[test]
fn join_counter_overflow() {
const MAX: u32 = 500_000;

let mut i = 0;
let mut j = 0;
let pool = ThreadPoolBuilder::new().num_threads(2).build().unwrap();

// Hammer on join a bunch of times -- used to hit overflow debug-assertions
// in JEC on 32-bit targets: https://github.com/rayon-rs/rayon/issues/797
for _ in 0..MAX {
pool.join(|| i += 1, || j += 1);
}

assert_eq!(i, MAX);
assert_eq!(j, MAX);
}
8 changes: 5 additions & 3 deletions rayon-core/src/sleep/counters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl AtomicCounters {
loop {
let old_value = self.load(Ordering::SeqCst);
if increment_when(old_value.jobs_counter()) {
let new_value = old_value.plus(ONE_JEC);
let new_value = old_value.increment_jobs_counter();
if self.try_exchange(old_value, new_value, Ordering::SeqCst) {
return new_value;
}
Expand Down Expand Up @@ -221,9 +221,11 @@ impl Counters {
}

#[inline]
fn plus(self, word: usize) -> Counters {
fn increment_jobs_counter(self) -> Counters {
// We can freely add to JEC because it occupies the most significant bits.
// Thus it doesn't overflow into the other counters, just wraps itself.
Counters {
word: self.word + word,
word: self.word.wrapping_add(ONE_JEC),
}
}

Expand Down

0 comments on commit e768237

Please sign in to comment.