Compare commits
2 Commits
9af5bc0269
...
8f631cb6b5
Author | SHA1 | Date |
---|---|---|
b1ek | 8f631cb6b5 | |
b1ek | 4e1e14d418 |
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
use powlib::{gen::{POWRange, POWChallenge}, solver::POWSolver};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let challenge = POWChallenge::make(POWRange::new(0, 20480));
|
||||||
|
let mut solver = POWSolver::new(challenge);
|
||||||
|
println!("Found {} with 8 threads", solver.solve_blocking(8, Some(|x| println!("{x}"))));
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
use crate::gen::POWChallenge;
|
use std::{sync::{mpsc::{self, Receiver, SyncSender}, Arc, atomic::{AtomicBool, Ordering}}, thread::{self, JoinHandle}};
|
||||||
|
|
||||||
|
use crate::{gen::POWChallenge, num::Num};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct POWSolver {
|
pub struct POWSolver {
|
||||||
challenge: POWChallenge,
|
challenge: POWChallenge,
|
||||||
result: Option<u128>
|
result: Option<u128>
|
||||||
|
@ -60,6 +63,68 @@ impl POWSolver {
|
||||||
return self.chunk_solve(self.challenge.range.min, self.challenge.range.max);
|
return self.chunk_solve(self.challenge.range.min, self.challenge.range.max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn chunksize(self: &POWSolver, threads: u8) -> u128 {
|
||||||
|
let range = self.challenge.range.max - self.challenge.range.min;
|
||||||
|
range / threads as u128
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn solve_blocking(self: &mut POWSolver, threads: u8, callback: Option<fn(u128)>) -> u128 {
|
||||||
|
let (send, recv) = mpsc::sync_channel::<u128>(1);
|
||||||
|
let mut thread_start: u128 = self.challenge.range.min;
|
||||||
|
|
||||||
|
let size = self.chunksize(threads);
|
||||||
|
let mut handles: Vec<JoinHandle<()>> = vec![];
|
||||||
|
let stop = Arc::new(AtomicBool::new(false));
|
||||||
|
let range = self.challenge.range.max - self.challenge.range.min;
|
||||||
|
|
||||||
|
for i in 0..threads {
|
||||||
|
let solver = self.clone();
|
||||||
|
let send = send.clone();
|
||||||
|
let stop = stop.clone();
|
||||||
|
|
||||||
|
let mut end = thread_start + size;
|
||||||
|
if end > range {
|
||||||
|
end -= end % range;
|
||||||
|
}
|
||||||
|
|
||||||
|
handles.push(
|
||||||
|
thread::spawn(move || {
|
||||||
|
for j in thread_start..end {
|
||||||
|
if stop.load(Ordering::Relaxed) { break }
|
||||||
|
if callback.is_some() {
|
||||||
|
callback.unwrap()(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if solver.challenge.check(Num::from(j as u128)) {
|
||||||
|
stop.store(true, Ordering::Relaxed);
|
||||||
|
send.send(j as u128).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
thread_start = thread_start + size + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = recv.recv().unwrap();
|
||||||
|
stop.load(Ordering::Relaxed);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut all_finished = true;
|
||||||
|
for handle in handles.iter() {
|
||||||
|
if !handle.is_finished() {
|
||||||
|
all_finished = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if all_finished { break }
|
||||||
|
}
|
||||||
|
|
||||||
|
self.result = Some(result);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(challenge: POWChallenge) -> POWSolver {
|
pub fn new(challenge: POWChallenge) -> POWSolver {
|
||||||
POWSolver { challenge, result: None }
|
POWSolver { challenge, result: None }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue