init: solve_blocking, chunksize to POWSolver

This commit is contained in:
b1ek 2023-08-02 21:47:55 +10:00
parent 9af5bc0269
commit 4e1e14d418
Signed by: blek
GPG Key ID: 14546221E3595D0C
1 changed files with 66 additions and 1 deletions

View File

@ -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 {
challenge: POWChallenge,
result: Option<u128>
@ -60,6 +63,68 @@ impl POWSolver {
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 {
POWSolver { challenge, result: None }
}