summaryrefslogtreecommitdiffstats
path: root/tokio/src/runtime/thread_pool/tests/loom_queue.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/runtime/thread_pool/tests/loom_queue.rs')
-rw-r--r--tokio/src/runtime/thread_pool/tests/loom_queue.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/tokio/src/runtime/thread_pool/tests/loom_queue.rs b/tokio/src/runtime/thread_pool/tests/loom_queue.rs
new file mode 100644
index 00000000..b7c86f6c
--- /dev/null
+++ b/tokio/src/runtime/thread_pool/tests/loom_queue.rs
@@ -0,0 +1,68 @@
+use crate::runtime::task::{self, Task};
+use crate::runtime::tests::mock_schedule::{Noop, NOOP_SCHEDULE};
+use crate::runtime::thread_pool::queue;
+
+use loom::thread;
+
+use std::cell::Cell;
+use std::rc::Rc;
+
+#[test]
+fn multi_worker() {
+ const THREADS: usize = 2;
+ const PER_THREAD: usize = 7;
+
+ fn work(_i: usize, q: queue::Worker<Noop>, rem: Rc<Cell<usize>>) {
+ let mut rem_local = PER_THREAD;
+
+ while rem.get() != 0 {
+ for _ in 0..3 {
+ if rem_local > 0 {
+ q.push(val(0));
+ rem_local -= 1;
+ }
+ }
+
+ // Try to work
+ while let Some(task) = q.pop_local_first() {
+ assert!(task.run(&mut || Some(From::from(&NOOP_SCHEDULE))).is_none());
+ let r = rem.get();
+ assert!(r > 0);
+ rem.set(r - 1);
+ }
+
+ // Try to steal
+ if let Some(task) = q.steal(0) {
+ assert!(task.run(&mut || Some(From::from(&NOOP_SCHEDULE))).is_none());
+ let r = rem.get();
+ assert!(r > 0);
+ rem.set(r - 1);
+ }
+
+ thread::yield_now();
+ }
+ }
+
+ loom::model(|| {
+ let rem = Rc::new(Cell::new(THREADS * PER_THREAD));
+
+ let mut qs = queue::build(THREADS);
+ let q1 = qs.remove(0);
+
+ for i in 1..THREADS {
+ let q = qs.remove(0);
+ let rem = rem.clone();
+ thread::spawn(move || {
+ work(i, q, rem);
+ });
+ }
+
+ work(0, q1, rem);
+
+ // th.join().unwrap();
+ });
+}
+
+fn val(num: u32) -> Task<Noop> {
+ task::background(async move { num })
+}