Skip to content

Commit 3835497

Browse files
committed
feat: improve docs and tests
1 parent 938da84 commit 3835497

File tree

16 files changed

+2007
-623
lines changed

16 files changed

+2007
-623
lines changed

Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,6 @@ missing_docs = "warn"
6868
unsafe_op_in_unsafe_fn = "warn"
6969
unused_qualifications = "warn"
7070

71-
[[test]]
72-
name = "integration"
73-
path = "tests/tests.rs"
74-
7571
[[bench]]
7672
name = "fork_join"
7773
harness = false

benches/bevy_tasks.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
//! Comparative benchmarks against bevy_tasks
22
3-
struct BevyParChunks<'a, T>(core::slice::Chunks<'a, T>);
4-
impl<'a, T> bevy_tasks::ParallelIterator<core::slice::Iter<'a, T>> for BevyParChunks<'a, T>
5-
where
6-
T: 'a + Send + Sync,
7-
{
8-
fn next_batch(&mut self) -> Option<core::slice::Iter<'a, T>> {
9-
self.0.next().map(|s| s.iter())
10-
}
11-
}
12-
133
struct BevyParChunksMut<'a, T>(core::slice::ChunksMut<'a, T>);
144
impl<'a, T> bevy_tasks::ParallelIterator<core::slice::IterMut<'a, T>> for BevyParChunksMut<'a, T>
155
where
@@ -97,7 +87,7 @@ mod overhead {
9787

9888
bencher.bench_local(|| {
9989
THREAD_POOL.with_worker(|worker| {
100-
forte_chunks::<100, _, _>(worker, &mut vec, &|c| {
90+
forte_chunks::<8, _, _>(worker, &mut vec, &|c| {
10191
c.iter_mut().for_each(work);
10292
});
10393
})

benches/fork_join.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! A benchmark for fork-join workloads adapted from `chili`.
22
33
use chili::Scope;
4-
use criterion::black_box;
54
use divan::Bencher;
65
use forte::Worker;
76
use tracing::info;
@@ -78,14 +77,8 @@ static COMPUTE: forte::ThreadPool = forte::ThreadPool::new();
7877
fn forte(bencher: Bencher, nodes: (usize, usize)) {
7978
fn sum(node: &Node, worker: &Worker) -> u64 {
8079
let (left, right) = worker.join(
81-
|w| {
82-
let sum = node.left.as_deref().map(|n| sum(n, w)).unwrap_or_default();
83-
sum
84-
},
85-
|w| {
86-
let sum = node.right.as_deref().map(|n| sum(n, w)).unwrap_or_default();
87-
sum
88-
},
80+
|w| node.left.as_deref().map(|n| sum(n, w)).unwrap_or_default(),
81+
|w| node.right.as_deref().map(|n| sum(n, w)).unwrap_or_default(),
8982
);
9083

9184
node.val + left + right

ci/src/ci.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,19 @@ impl CI {
7171
None => {
7272
// Note that we are running the subcommands directly rather than using any aliases
7373
let mut cmds = vec![];
74+
// Lint commands
7475
cmds.append(&mut commands::FormatCommand::default().prepare(sh, flags));
7576
cmds.append(&mut commands::ClippyCommand::default().prepare(sh, flags));
7677
cmds.append(&mut commands::LintsCommand::default().prepare(sh, flags));
78+
// Compile commands
7779
cmds.append(&mut commands::CompileCheckCommand::default().prepare(sh, flags));
80+
// Documentation commands
7881
cmds.append(&mut commands::DocCheckCommand::default().prepare(sh, flags));
7982
cmds.append(&mut commands::DocTestCommand::default().prepare(sh, flags));
83+
// Shuttle commands
84+
cmds.append(&mut commands::ShuttleCheckCommand::default().prepare(sh, flags));
85+
cmds.append(&mut commands::ShuttleClippyCommand::default().prepare(sh, flags));
86+
cmds.append(&mut commands::ShuttleTestCommand::default().prepare(sh, flags));
8087
cmds
8188
}
8289
}

ci/src/commands/shuttle.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use crate::commands::ShuttleCheckCommand;
77
use crate::commands::ShuttleClippyCommand;
88
use crate::commands::ShuttleTestCommand;
99

10-
/// Alias for running the `loom-check`, `loom-clippy` and `loom-test` subcommands.
10+
/// Alias for running the `shuttle-check`, `shuttle-clippy` and `shuttle-test` subcommands.
1111
#[derive(FromArgs, Default)]
12-
#[argh(subcommand, name = "loom")]
12+
#[argh(subcommand, name = "shuttle")]
1313
pub struct ShuttleCommand {}
1414

1515
impl Prepare for ShuttleCommand {

ci/src/commands/shuttle_clippy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::PreparedCommand;
77

88
/// Checks for clippy warnings and errors in the loom test suite.
99
#[derive(FromArgs, Default)]
10-
#[argh(subcommand, name = "loom-clippy")]
10+
#[argh(subcommand, name = "shuttle-clippy")]
1111
pub struct ShuttleClippyCommand {}
1212

1313
impl Prepare for ShuttleClippyCommand {

ci/src/commands/shuttle_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::PreparedCommand;
77

88
/// Runs the loom concurrency test suite.
99
#[derive(FromArgs, Default)]
10-
#[argh(subcommand, name = "loom-test")]
10+
#[argh(subcommand, name = "shuttle-test")]
1111
pub struct ShuttleTestCommand {}
1212

1313
impl Prepare for ShuttleTestCommand {

src/compile_fail.rs

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
//! Contains a set of compile failure doctests.
2+
3+
// -----------------------------------------------------------------------------
4+
// Ensures non-send data cannot be moved into a join.
5+
6+
/** ```compile_fail,E0277
7+
8+
use std::rc::Rc;
9+
use forte::ThreadPool;
10+
11+
static THREAD_POOL: ThreadPool = ThreadPool::new();
12+
13+
let r = Rc::new(22);
14+
THREAD_POOL.join(|_| r.clone(), |_| r.clone());
15+
//~^ ERROR
16+
17+
``` */
18+
mod nonsend_input {}
19+
20+
// -----------------------------------------------------------------------------
21+
// Ensures non-send data cannot be returned by join.
22+
23+
/** ```compile_fail,E0277
24+
25+
use std::rc::Rc;
26+
use forte::ThreadPool;
27+
28+
static THREAD_POOL: ThreadPool = ThreadPool::new();
29+
30+
THREAD_POOL.join(|_| Rc::new(22), |_| ()); //~ ERROR
31+
32+
THREAD_POOL.depopulate();
33+
34+
``` */
35+
mod nonsend_left_join {}
36+
37+
/** ```compile_fail,E0277
38+
39+
use std::rc::Rc;
40+
use forte::ThreadPool;
41+
42+
static THREAD_POOL: ThreadPool = ThreadPool::new();
43+
44+
THREAD_POOL.join(|_| (), |_| Rc::new(23)); //~ ERROR
45+
46+
THREAD_POOL.depopulate();
47+
48+
``` */
49+
mod nonsend_right_join {}
50+
51+
// -----------------------------------------------------------------------------
52+
// Ensures scopes can not borrow data spawned within the closure.
53+
54+
/** ```compile_fail,E0373
55+
56+
use forte::ThreadPool;
57+
use forte::Worker;
58+
59+
static THREAD_POOL: ThreadPool = ThreadPool::new();
60+
61+
fn bad_scope<F>(f: F)
62+
where F: FnOnce(&i32) + Send,
63+
{
64+
THREAD_POOL.scope(|scope| {
65+
let x = 22;
66+
scope.spawn(|_: &Worker| f(&x)); //~ ERROR `x` does not live long enough
67+
});
68+
}
69+
70+
fn good_scope<F>(f: F)
71+
where F: FnOnce(&i32) + Send,
72+
{
73+
let x = 22;
74+
THREAD_POOL.scope(|scope| {
75+
scope.spawn(|_: &Worker| f(&x));
76+
});
77+
}
78+
79+
fn main() { }
80+
81+
``` */
82+
mod scope_join_bad {}
83+
84+
// -----------------------------------------------------------------------------
85+
// Ensures the two branches of a join mutably borrow the same data.
86+
87+
/** ```compile_fail,E0524
88+
89+
use forte::ThreadPool;
90+
use forte::Worker;
91+
92+
static THREAD_POOL: ThreadPool = ThreadPool::new();
93+
94+
fn quick_sort<T:PartialOrd+Send>(v: &mut [T]) {
95+
if v.len() <= 1 {
96+
return;
97+
}
98+
99+
let mid = partition(v);
100+
let (lo, _hi) = v.split_at_mut(mid);
101+
THREAD_POOL.join(|_| quick_sort(lo), |_| quick_sort(lo)); //~ ERROR
102+
}
103+
104+
fn partition<T:PartialOrd+Send>(v: &mut [T]) -> usize {
105+
let pivot = v.len() - 1;
106+
let mut i = 0;
107+
for j in 0..pivot {
108+
if v[j] <= v[pivot] {
109+
v.swap(i, j);
110+
i += 1;
111+
}
112+
}
113+
v.swap(i, pivot);
114+
i
115+
}
116+
117+
fn main() { }
118+
119+
``` */
120+
mod quicksort_race_1 {}
121+
122+
/** ```compile_fail,E0500
123+
124+
use forte::ThreadPool;
125+
use forte::Worker;
126+
127+
static THREAD_POOL: ThreadPool = ThreadPool::new();
128+
129+
fn quick_sort<T:PartialOrd+Send>(v: &mut [T]) {
130+
if v.len() <= 1 {
131+
return;
132+
}
133+
134+
let mid = partition(v);
135+
let (lo, _hi) = v.split_at_mut(mid);
136+
THREAD_POOL.join(|_| quick_sort(lo), |_| quick_sort(v)); //~ ERROR
137+
}
138+
139+
fn partition<T:PartialOrd+Send>(v: &mut [T]) -> usize {
140+
let pivot = v.len() - 1;
141+
let mut i = 0;
142+
for j in 0..pivot {
143+
if v[j] <= v[pivot] {
144+
v.swap(i, j);
145+
i += 1;
146+
}
147+
}
148+
v.swap(i, pivot);
149+
i
150+
}
151+
152+
fn main() { }
153+
154+
``` */
155+
mod quicksort_race_2 {}
156+
157+
/** ```compile_fail,E0524
158+
159+
use forte::ThreadPool;
160+
use forte::Worker;
161+
162+
static THREAD_POOL: ThreadPool = ThreadPool::new();
163+
164+
fn quick_sort<T:PartialOrd+Send>(v: &mut [T]) {
165+
if v.len() <= 1 {
166+
return;
167+
}
168+
169+
let mid = partition(v);
170+
let (_lo, hi) = v.split_at_mut(mid);
171+
THREAD_POOL.join(|_| quick_sort(hi), |_| quick_sort(hi)); //~ ERROR
172+
}
173+
174+
fn partition<T:PartialOrd+Send>(v: &mut [T]) -> usize {
175+
let pivot = v.len() - 1;
176+
let mut i = 0;
177+
for j in 0..pivot {
178+
if v[j] <= v[pivot] {
179+
v.swap(i, j);
180+
i += 1;
181+
}
182+
}
183+
v.swap(i, pivot);
184+
i
185+
}
186+
187+
fn main() { }
188+
189+
``` */
190+
mod quicksort_race_3 {}

0 commit comments

Comments
 (0)