From e23b39ee415269259d27e49c7fd7d1576b8791c5 Mon Sep 17 00:00:00 2001 From: Yiyao Yu Date: Sun, 18 Apr 2021 15:19:03 -0400 Subject: [PATCH] Removed imports for multiple calls to par_for!, renamed variables to avoid clashing, added blocksize parameter --- .gitignore | 1 + src/bin/test_simple.rs | 12 ++++++-- src/lib.rs | 70 ++++++++++++++++++++++++------------------ 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 96ef6c0..2de3917 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +/.idea diff --git a/src/bin/test_simple.rs b/src/bin/test_simple.rs index f631d55..bb1df9f 100644 --- a/src/bin/test_simple.rs +++ b/src/bin/test_simple.rs @@ -12,7 +12,7 @@ struct Student { impl Student { pub fn new(age: u8) -> Student { Student { name: "Default".to_string(), - age: age, + age, gpa: age as f32 } } } @@ -21,8 +21,7 @@ fn main() { let numbers: Vec = vec![]; par_for! { - for i in 1..10, capturing numbers { - + for i in 1..32, capturing numbers { //std::thread::sleep( // time::Duration::from_secs( // rand::thread_rng().gen_range(1..10))); @@ -31,6 +30,13 @@ fn main() { println!("Thread {} running!", i); } }; + par_for! { + for i in 1..32, blocksize 16, capturing numbers { + let mut lock = numbers.write(); + lock.push(Student::new(i)); + println!("Thread {} running!", i); + } }; + for num in numbers { println!("{:?}", num); } diff --git a/src/lib.rs b/src/lib.rs index b7c6f55..af0e402 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,8 @@ mod sysinfo; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; +pub use threadpool::{as_static_job, Job, ThreadPoolManager}; + pub struct Capture { value: Arc>, } @@ -38,41 +40,49 @@ impl Capture { } #[macro_export] -macro_rules! par_for { - (for $name:ident in $iterator:expr, capturing $captured:ident $blk:block) => { - use rustmp::Capture; - use rustmp::threadpool::{Job, ThreadPoolManager, as_static_job}; - use std::sync::{Arc, RwLock}; - use std::thread; - - let mut tasks = Vec::new(); - let $captured = Capture::new($captured); +macro_rules! __internal_par_for { + ($name:ident, $iterator:expr, $size:expr, $($captured:ident)*, $blk:block) => { + let mut __rmp_tasks = Vec::new(); + $(let $captured = rustmp::Capture::new($captured);)* { - let tpm_mtx = ThreadPoolManager::get_instance_guard(); - let tpm = tpm_mtx.lock().unwrap(); - let iters = tpm.split_iterators($iterator, 1); - for iter in iters { - let $captured = $captured.clone(); - tasks.push(as_static_job(move || { + let __rmp_tpm_mtx = rustmp::ThreadPoolManager::get_instance_guard(); + let __rmp_tpm = __rmp_tpm_mtx.lock().unwrap(); + let __rmp_iters = __rmp_tpm.split_iterators($iterator, $size); + for iter in __rmp_iters { + $(let $captured = $captured.clone();)* + __rmp_tasks.push(rustmp::as_static_job(move || { for &$name in &iter $blk })); } - tpm.exec(tasks); + __rmp_tpm.exec(__rmp_tasks); } - - //let itr = $iterator; - //let $captured = Capture::new($captured); - //let mut handles: Vec> = vec![]; - //for $name in itr { - // let $captured = $captured.clone(); - // handles.push(thread::spawn(move || $blk)); - //} - - //for handle in handles { - // handle.join().expect("Thread paniced!"); - //} - - let $captured = $captured.unwrap(); + $(let $captured = $captured.unwrap();)* }; } + +/// "parallel for" wrapper +/// +/// If the number of arguments increases, convert this to a tail recursive parser instead. +/// Current implementation save limited (max depth 32) stack space for macro expansion. +#[macro_export] +macro_rules! par_for { + (for $name:ident in $iterator:expr, blocksize $size:expr, capturing $($captured:ident)+, $blk:block) => { + rustmp::__internal_par_for!($name, $iterator, $size, $($captured)*, $blk); + }; + (for $name:ident in $iterator:expr, blocksize $size:expr, capturing $($captured:ident)+ $blk:block) => { + rustmp::__internal_par_for!($name, $iterator, $size, $($captured)*, $blk); + }; + (for $name:ident in $iterator:expr, capturing $($captured:ident)+, blocksize $size:expr, $blk:block) => { + rustmp::__internal_par_for!($name, $iterator, $size, $($captured)*, $blk); + }; + (for $name:ident in $iterator:expr, blocksize $size:expr, $blk:block) => { + rustmp::__internal_par_for!($name, $iterator, $size,, $blk); + }; + (for $name:ident in $iterator:expr, capturing $($captured:ident)+, $blk:block) => { + rustmp::__internal_par_for!($name, $iterator, 1, $($captured)*, $blk); + }; + (for $name:ident in $iterator:expr, capturing $($captured:ident)+ $blk:block) => { + rustmp::__internal_par_for!($name, $iterator, 1, $($captured)*, $blk); + } +}