Added critical! macro. Added "private" to par_for. Converted par_for to use tail-recursive parsing.

This commit is contained in:
Jack Yu 2021-04-18 22:49:40 -04:00
parent 24c3772926
commit d7745fd38a
2 changed files with 125 additions and 39 deletions

View File

@ -1,5 +1,5 @@
use rand::Rng; use rand::Rng;
use rustmp::par_for; use rustmp::{par_for, critical};
use std::time; use std::time;
#[derive(Debug)] #[derive(Debug)]
@ -11,9 +11,11 @@ struct Student {
impl Student { impl Student {
pub fn new(age: u8) -> Student { pub fn new(age: u8) -> Student {
Student { name: "Default".to_string(), Student {
name: "Default".to_string(),
age, age,
gpa: age as f32 } gpa: age as f32,
}
} }
} }
@ -21,23 +23,32 @@ fn main() {
let numbers: Vec<Student> = vec![]; let numbers: Vec<Student> = vec![];
par_for! { par_for! {
for i in 1..32, capturing numbers { for i in 1..32, blocksize 4, capturing numbers, {
//std::thread::sleep( //std::thread::sleep(
// time::Duration::from_secs( // time::Duration::from_secs(
// rand::thread_rng().gen_range(1..10))); // rand::thread_rng().gen_range(1..10)));
let mut lock = numbers.write(); critical! {
lock.push(Student::new(i)); // Automatically locks numbers as read+write,
// and makes the result accessible as number
readwrite numbers;
numbers.push(Student::new(i));
}
println!("Thread {} running!", i); 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 { for num in numbers {
println!("{:?}", num); println!("{:?}", num);
} }
//let mut local = 0;
//par_for! {
//for i in 1..32, blocksize 1, capturing numbers, private local, {
//local += 1;
//println!("{}", local);
//let mut lock = numbers.write();
//lock.push(Student::new(i));
//println!("Thread {} running!", i);
//} }
} }

View File

@ -39,18 +39,54 @@ impl<T> Capture<T> {
} }
} }
#[macro_export]
macro_rules! critical {
(read $($r:ident)+; readwrite $($w:ident)+; $($ops:tt)+) => {
{
$(let $r = $r.read();)*
$(let mut $w = $w.write();)*
$($ops)*
}
};
(readwrite $($w:ident)+; read $($r:ident)+; $($ops:tt)+) => {
{
$(let $r = $r.read();)*
$(let mut $w = $w.write();)*
$($ops)*
}
};
(readwrite $($w:ident)+; $($ops:tt)+) => {
{
$(let mut $w = $w.write();)*
$($ops)*
}
};
(read $($r:ident)+; $($ops:tt)+) => {
{
$(let $r = $r.read();)*
$($ops)*
}
};
}
#[macro_export] #[macro_export]
macro_rules! __internal_par_for { macro_rules! __internal_par_for {
($name:ident, $iterator:expr, $size:expr, $($captured:ident)*, $blk:block) => { (var_name($name:ident),
iterator($iter:expr),
blocksize($size:expr),
captured($($captured:ident)*),
private($($private:ident)*),
$blk:block) => {
let mut __rmp_tasks = Vec::new(); let mut __rmp_tasks = Vec::new();
$(let $captured = rustmp::Capture::new($captured);)* $(let $captured = rustmp::Capture::new($captured);)*
{ {
let __rmp_tpm_mtx = rustmp::ThreadPoolManager::get_instance_guard(); let __rmp_tpm_mtx = rustmp::ThreadPoolManager::get_instance_guard();
let __rmp_tpm = __rmp_tpm_mtx.lock().unwrap(); let __rmp_tpm = __rmp_tpm_mtx.lock().unwrap();
let __rmp_iters = __rmp_tpm.split_iterators($iterator, $size); let __rmp_iters = __rmp_tpm.split_iterators($iter, $size);
for iter in __rmp_iters { for iter in __rmp_iters {
$(let $captured = $captured.clone();)* $(let $captured = $captured.clone();)*
__rmp_tasks.push(rustmp::as_static_job(move || { __rmp_tasks.push(rustmp::as_static_job(move || {
$(let mut $private = $private.clone();)*
for &$name in &iter for &$name in &iter
$blk $blk
})); }));
@ -59,6 +95,54 @@ macro_rules! __internal_par_for {
} }
$(let $captured = $captured.unwrap();)* $(let $captured = $captured.unwrap();)*
}; };
// Parse blocksize
(var_name($name:ident),
iterator($iter:expr),
blocksize($size:expr),
captured($($captured:ident)*),
private($($private:ident)*),
blocksize $new_size:expr,
$($rem:tt)+) => {
rustmp::__internal_par_for!(
var_name($name),
iterator($iter),
blocksize($new_size),
captured($($captured)*),
private($($private)*),
$($rem)*)
};
// Parse capturing
(var_name($name:ident),
iterator($iter:expr),
blocksize($size:expr),
captured($($captured:ident)*),
private($($private:ident)*),
capturing $($new_captured:ident)*,
$($rem:tt)+) => {
rustmp::__internal_par_for!(
var_name($name),
iterator($iter),
blocksize($size),
captured($($new_captured)*),
private($($private)*),
$($rem)*)
};
// Parse private
(var_name($name:ident),
iterator($iter:expr),
blocksize($size:expr),
captured($($captured:ident)*),
private($($private:ident)*),
private $($new_private:ident)*,
$($rem:tt)+) => {
rustmp::__internal_par_for!(
var_name($name),
iterator($iter),
blocksize($size),
captured($($captured)*),
private($($new_private)*),
$($rem)*)
};
} }
/// "parallel for" wrapper /// "parallel for" wrapper
@ -67,22 +151,13 @@ macro_rules! __internal_par_for {
/// Current implementation save limited (max depth 32) stack space for macro expansion. /// Current implementation save limited (max depth 32) stack space for macro expansion.
#[macro_export] #[macro_export]
macro_rules! par_for { macro_rules! par_for {
(for $name:ident in $iterator:expr, blocksize $size:expr, capturing $($captured:ident)+, $blk:block) => { (for $name:ident in $iter:expr, $($rem:tt)+) => {
rustmp::__internal_par_for!($name, $iterator, $size, $($captured)*, $blk); rustmp::__internal_par_for!(
}; var_name($name),
(for $name:ident in $iterator:expr, blocksize $size:expr, capturing $($captured:ident)+ $blk:block) => { iterator($iter),
rustmp::__internal_par_for!($name, $iterator, $size, $($captured)*, $blk); blocksize(1),
}; captured(),
(for $name:ident in $iterator:expr, capturing $($captured:ident)+, blocksize $size:expr, $blk:block) => { private(),
rustmp::__internal_par_for!($name, $iterator, $size, $($captured)*, $blk); $($rem)*)
};
(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);
} }
} }