@@ -6,14 +6,12 @@ use crate::util::md5::*;
66use crate :: util:: thread:: * ;
77use std:: collections:: { BTreeMap , BTreeSet } ;
88use std:: sync:: Mutex ;
9- use std:: sync:: atomic:: { AtomicBool , AtomicI32 , Ordering } ;
109
1110/// Atomics can be safely shared between threads.
1211struct Shared < ' a > {
1312 input : & ' a str ,
1413 part_two : bool ,
15- done : AtomicBool ,
16- counter : AtomicI32 ,
14+ iter : AtomicIter ,
1715 mutex : Mutex < Exclusive > ,
1816}
1917
@@ -40,15 +38,12 @@ pub fn part2(input: &str) -> i32 {
4038
4139/// Find the first 64 keys that satisfy the rules.
4240fn generate_pad ( input : & str , part_two : bool ) -> i32 {
41+ let step = if cfg ! ( feature = "simd" ) { 32 } else { 1 } ;
42+
4343 let exclusive =
4444 Exclusive { threes : BTreeMap :: new ( ) , fives : BTreeMap :: new ( ) , found : BTreeSet :: new ( ) } ;
45- let shared = Shared {
46- input,
47- part_two,
48- done : AtomicBool :: new ( false ) ,
49- counter : AtomicI32 :: new ( 0 ) ,
50- mutex : Mutex :: new ( exclusive) ,
51- } ;
45+ let shared =
46+ Shared { input, part_two, iter : AtomicIter :: new ( 0 , step) , mutex : Mutex :: new ( exclusive) } ;
5247
5348 // Use as many cores as possible to parallelize the search.
5449 spawn ( || worker ( & shared) ) ;
@@ -59,9 +54,9 @@ fn generate_pad(input: &str, part_two: bool) -> i32 {
5954
6055#[ cfg( not( feature = "simd" ) ) ]
6156fn worker ( shared : & Shared < ' _ > ) {
62- while ! shared. done . load ( Ordering :: Relaxed ) {
57+ while let Some ( n ) = shared. iter . next ( ) {
6358 // Get the next key to check.
64- let n = shared . counter . fetch_add ( 1 , Ordering :: Relaxed ) ;
59+ let n = n as i32 ;
6560
6661 // Calculate the hash.
6762 let ( mut buffer, size) = format_string ( shared. input , n) ;
@@ -88,9 +83,9 @@ fn worker(shared: &Shared<'_>) {
8883 let mut result = ( [ 0 ; 32 ] , [ 0 ; 32 ] , [ 0 ; 32 ] , [ 0 ; 32 ] ) ;
8984 let mut buffers = [ [ 0 ; 64 ] ; 32 ] ;
9085
91- while ! shared. done . load ( Ordering :: Relaxed ) {
86+ while let Some ( start ) = shared. iter . next ( ) {
9287 // Get the next key to check.
93- let start = shared . counter . fetch_add ( 32 , Ordering :: Relaxed ) ;
88+ let start = start as i32 ;
9489
9590 // Calculate the hash.
9691 for i in 0 ..32 {
@@ -183,7 +178,7 @@ fn check(shared: &Shared<'_>, n: i32, hash: (u32, u32, u32, u32)) {
183178 exclusive. found . extend ( candidates) ;
184179
185180 if exclusive. found . len ( ) >= 64 {
186- shared. done . store ( true , Ordering :: Relaxed ) ;
181+ shared. iter . stop ( ) ;
187182 }
188183 }
189184}
0 commit comments