Add concurrent kernel executor
Signed-off-by: Trivernis <trivernis@protonmail.com>pull/1/head
parent
7ee06b1d35
commit
16e3e4a1bc
@ -0,0 +1,84 @@
|
||||
use crate::kernel_controller::primes::PrimeCalculationResult;
|
||||
use crate::kernel_controller::KernelController;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::Arc;
|
||||
use std::thread::Builder as ThreadBuilder;
|
||||
|
||||
pub struct ConcurrentKernelExecutor {
|
||||
kernel_controller: KernelController,
|
||||
}
|
||||
|
||||
impl ConcurrentKernelExecutor {
|
||||
pub fn new(kernel_controller: KernelController) -> Self {
|
||||
Self { kernel_controller }
|
||||
}
|
||||
|
||||
pub fn calculate_primes(
|
||||
&self,
|
||||
mut offset: u64,
|
||||
numbers_per_step: usize,
|
||||
stop: u64,
|
||||
no_cache: bool,
|
||||
num_threads: usize,
|
||||
sender: Sender<PrimeCalculationResult>,
|
||||
) {
|
||||
let mut handles = Vec::new();
|
||||
if offset % 2 == 0 {
|
||||
offset += 1;
|
||||
}
|
||||
let offset = Arc::new(AtomicU64::new(offset));
|
||||
let panic = Arc::new(AtomicBool::new(false));
|
||||
|
||||
for i in 0..num_threads {
|
||||
let sender = Sender::clone(&sender);
|
||||
let controller = self.kernel_controller.clone();
|
||||
let offset = Arc::clone(&offset);
|
||||
let panic = Arc::clone(&panic);
|
||||
|
||||
handles.push(
|
||||
ThreadBuilder::new()
|
||||
.name(format!("executor-{}", i))
|
||||
.spawn(move || loop {
|
||||
if panic.load(Ordering::Relaxed) {
|
||||
panic!("Planned panic");
|
||||
}
|
||||
if offset.load(Ordering::SeqCst) >= stop {
|
||||
break;
|
||||
}
|
||||
let offset =
|
||||
offset.fetch_add(numbers_per_step as u64 * 2, Ordering::SeqCst);
|
||||
|
||||
let numbers = (offset..(numbers_per_step as u64 * 2 + offset))
|
||||
.step_by(2)
|
||||
.collect::<Vec<u64>>();
|
||||
let prime_result = if no_cache {
|
||||
controller
|
||||
.filter_primes_simple(numbers)
|
||||
.map_err(|e| {
|
||||
panic.store(true, Ordering::Relaxed);
|
||||
e
|
||||
})
|
||||
.unwrap()
|
||||
} else {
|
||||
controller
|
||||
.filter_primes(numbers)
|
||||
.map_err(|e| {
|
||||
panic.store(true, Ordering::Relaxed);
|
||||
e
|
||||
})
|
||||
.unwrap()
|
||||
};
|
||||
if let Err(e) = sender.send(prime_result) {
|
||||
panic.store(true, Ordering::Relaxed);
|
||||
panic!(e);
|
||||
}
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
for handle in handles {
|
||||
handle.join().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
pub mod executor;
|
Loading…
Reference in New Issue