Skip to content

Commit 46d3d0f

Browse files
committed
work: Specialize Arc-based Work
Instead of hard-coding `Pin<Arc<Work<T>>>`, have a constructor that wraps the `Arc<Work<T>>` in a new type `ArcWork`. This has the methods for submitting work on this particular pointer type. This leaves room for `StaticWork` which will have a static reference. Removes all references to Pin. Now that the Work queue itself is stored in a ZephyrObject, we have a mechanism to panic on move, which although a runtime check, does catch issues where values have been moved. Signed-off-by: David Brown <[email protected]>
1 parent f936c70 commit 46d3d0f

File tree

2 files changed

+120
-144
lines changed

2 files changed

+120
-144
lines changed

samples/bench/src/lib.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,16 @@
1010
extern crate alloc;
1111

1212
use core::mem;
13-
use core::pin::Pin;
1413

1514
use alloc::collections::vec_deque::VecDeque;
1615
use alloc::vec;
1716
use executor::AsyncTests;
1817
use static_cell::StaticCell;
1918
use zephyr::define_work_queue;
2019
use zephyr::raw::k_yield;
21-
use zephyr::sync::{PinWeak, SpinMutex};
20+
use zephyr::sync::{SpinMutex, Weak};
2221
use zephyr::time::NoWait;
23-
use zephyr::work::{SimpleAction, Work};
22+
use zephyr::work::{ArcWork, SimpleAction, Work};
2423
use zephyr::{
2524
kconfig::CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,
2625
printkln,
@@ -583,22 +582,22 @@ impl Simple {
583582

584583
fn run(&self, workers: usize, iterations: usize) {
585584
// printkln!("Running Simple");
586-
let main: Pin<Arc<Work<_>>> = Work::new(SimpleMain::new(workers * iterations, self.workq));
585+
let main = Work::new_arc(SimpleMain::new(workers * iterations, self.workq));
587586

588587
let children: VecDeque<_> = (0..workers)
589-
.map(|n| Work::new(SimpleWorker::new(main.clone(), self.workq, n)))
588+
.map(|n| Work::new_arc(SimpleWorker::new(main.0.clone(), self.workq, n)).0)
590589
.collect();
591590

592-
let mut locked = main.action().locked.lock().unwrap();
591+
let mut locked = main.0.action().locked.lock().unwrap();
593592
let _ = mem::replace(&mut locked.works, children);
594593
drop(locked);
595594

596595
let start = now();
597596
// Fire off main, which will run everything.
598-
Work::submit_to_queue(main.clone(), self.workq).unwrap();
597+
main.clone().submit_to_queue(self.workq).unwrap();
599598

600599
// And wait for the completion semaphore.
601-
main.action().done.take(Forever).unwrap();
600+
main.0.action().done.take(Forever).unwrap();
602601

603602
let stop = now();
604603
let time = (stop - start) as f64 / (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC as f64) * 1000.0;
@@ -619,41 +618,39 @@ impl Simple {
619618
);
620619

621620
// Before we go away, make sure that there aren't any leaked workers.
622-
let mut locked = main.action().locked.lock().unwrap();
621+
let mut locked = main.0.action().locked.lock().unwrap();
623622
while let Some(other) = locked.works.pop_front() {
624-
let other = Pin::into_inner(other);
625623
assert_eq!(Arc::strong_count(&other), 1);
626624
}
627625
drop(locked);
628626

629627
// And nothing has leaked main, either.
630-
let main = Pin::into_inner(main);
631-
assert_eq!(Arc::strong_count(&main), 1);
628+
assert_eq!(Arc::strong_count(&main.0), 1);
632629
}
633630
}
634631

635632
/// A simple worker. When run, it submits the main worker to do the next work.
636633
struct SimpleWorker {
637-
main: PinWeak<Work<SimpleMain>>,
634+
main: Weak<Work<SimpleMain>>,
638635
workq: &'static WorkQueue,
639636
_id: usize,
640637
}
641638

642639
impl SimpleWorker {
643-
fn new(main: Pin<Arc<Work<SimpleMain>>>, workq: &'static WorkQueue, id: usize) -> Self {
640+
fn new(main: Arc<Work<SimpleMain>>, workq: &'static WorkQueue, id: usize) -> Self {
644641
Self {
645-
main: PinWeak::downgrade(main),
642+
main: Arc::downgrade(&main),
646643
workq,
647644
_id: id,
648645
}
649646
}
650647
}
651648

652649
impl SimpleAction for SimpleWorker {
653-
fn act(self: Pin<&Self>) {
650+
fn act(self: &Self) {
654651
// Each time we are run, fire the main worker back up.
655-
let main = self.main.upgrade().unwrap();
656-
Work::submit_to_queue(main.clone(), self.workq).unwrap();
652+
let main = ArcWork(self.main.upgrade().unwrap());
653+
main.clone().submit_to_queue(self.workq).unwrap();
657654
}
658655
}
659656

@@ -668,7 +665,7 @@ struct SimpleMain {
668665
}
669666

670667
impl SimpleAction for SimpleMain {
671-
fn act(self: Pin<&Self>) {
668+
fn act(self: &Self) {
672669
// Each time, take a worker from the queue, and submit it.
673670
let mut lock = self.locked.lock().unwrap();
674671

@@ -683,7 +680,7 @@ impl SimpleAction for SimpleMain {
683680
lock.count -= 1;
684681
drop(lock);
685682

686-
Work::submit_to_queue(worker.clone(), self.workq).unwrap();
683+
ArcWork(worker.clone()).submit_to_queue(self.workq).unwrap();
687684
}
688685
}
689686

@@ -698,7 +695,7 @@ impl SimpleMain {
698695
}
699696

700697
struct Locked {
701-
works: VecDeque<Pin<Arc<Work<SimpleWorker>>>>,
698+
works: VecDeque<Arc<Work<SimpleWorker>>>,
702699
count: usize,
703700
}
704701

0 commit comments

Comments
 (0)