1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use crateScope;
use queue;
/// Entry point for building a statically typed [`TaskQueue`] to run in parallel
/// via [`ThreadPool::run_all`].
///
/// Since the queue is typed rather than relying on dynamic dispatch, pushed tasks
/// are stored inline: no object safety, boxing or heap allocation is required.
///
/// [`ThreadPool::run_all`]: crate::ThreadPool::run_all
///
/// # Example
///
/// ```rust
/// use orx_parallel::*;
///
/// let work_for = |n| std::thread::sleep(std::time::Duration::from_millis(n));
///
/// let tasks = Tasks::new()
/// .push(|| {
/// work_for(90);
/// println!("t1 completes 4th");
/// })
/// .push(|| println!("t2 completes 1st"))
/// .push(|| {
/// work_for(10);
/// println!("t3 completes 2nd");
/// })
/// .push(|| {
/// work_for(50);
/// println!("t4 completes 3rd");
/// });
///
/// Pool::global().run_all(tasks);
///
/// // prints:
/// // t2 completes 1st
/// // t3 completes 2nd
/// // t4 completes 3rd
/// // t1 completes 4th
/// ```
///
/// Below is a more practical example: computing independent statistics over the same
/// input concurrently and collecting the results:
///
/// ```rust
/// use orx_parallel::*;
/// use std::sync::Mutex;
///
/// let numbers = [4, 8, 15, 16, 23, 42];
///
/// let sum = Mutex::new(0);
/// let max = Mutex::new(i32::MIN);
/// let all_positive = Mutex::new(false);
///
/// let tasks = tasks![
/// || *sum.lock().unwrap() = numbers.iter().sum(),
/// || *max.lock().unwrap() = numbers.iter().copied().max().unwrap(),
/// || *all_positive.lock().unwrap() = numbers.iter().all(|&x| x > 0),
/// ];
///
/// Pool::global().run_all(tasks);
///
/// println!(
/// "sum={}, max={}, all_positive={}",
/// sum.into_inner().unwrap(),
/// max.into_inner().unwrap(),
/// all_positive.into_inner().unwrap(),
/// );
/// ```
///
/// Tasks can also be built fluently via [`Tasks::new`] and [`TaskQueue::push`].
;
/// Macro helper to build a statically typed [`TaskQueue`] with the given tasks.
///
/// Returns a task queue (equivalent to chaining [`Tasks::new().push(...)`](Tasks::new)).
///
/// # Example
///
/// ```rust
/// use orx_parallel::*;
/// use std::sync::Mutex;
///
/// let numbers = [4, 8, 15, 16, 23, 42];
///
/// let sum = Mutex::new(0);
/// let max = Mutex::new(i32::MIN);
/// let all_positive = Mutex::new(false);
///
/// let tasks = tasks![
/// || *sum.lock().unwrap() = numbers.iter().sum(),
/// || *max.lock().unwrap() = numbers.iter().copied().max().unwrap(),
/// || *all_positive.lock().unwrap() = numbers.iter().all(|&x| x > 0),
/// ];
///
/// Pool::global().run_all(tasks);
///
/// assert_eq!(*sum.lock().unwrap(), 108);
/// assert_eq!(*max.lock().unwrap(), 42);
/// assert!(*all_positive.lock().unwrap());
/// ```
///
/// See [`adhoc_tasks.rs`](https://github.com/orxfun/orx-parallel/blob/main/examples/adhoc_tasks.rs)
/// for a complete example of running independent ad-hoc tasks concurrently.