Skip to content

Commit e608483

Browse files
committed
zephyr: work: Add &'static Work
Support enqueueing &'static Work as well as the Arc-based work. Signed-off-by: David Brown <[email protected]>
1 parent 46d3d0f commit e608483

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

zephyr/src/work.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,37 @@ impl<T: SimpleAction + Send> ArcWork<T> {
469469
}
470470
}
471471

472+
/// Static Work.
473+
///
474+
/// Work items can also be declared statically. Note that the work should only be submitted after
475+
/// it has been moved to it's final static location.
476+
pub struct StaticWork<T: SimpleAction + Send + 'static>(pub &'static Work<T>);
477+
478+
impl<T: SimpleAction + Send + 'static> StaticWork<T> {
479+
/// Submit this work to the system work queue.
480+
pub fn submit(self) -> crate::Result<SubmitResult> {
481+
SubmitResult::to_result(unsafe { k_work_submit(self.0.work.get()) })
482+
}
483+
484+
/// Submit this work to the a specific work queue.
485+
pub fn submit_to_queue(self, queue: &'static WorkQueue) -> crate::Result<SubmitResult> {
486+
SubmitResult::to_result(unsafe { k_work_submit_to_queue(queue.item.get(), self.0.work.get()) })
487+
}
488+
489+
/// The handler for static work.
490+
extern "C" fn handler(work: *mut k_work) {
491+
let ptr = unsafe {
492+
work
493+
.cast::<u8>()
494+
.sub(mem::offset_of!(Work<T>, work))
495+
.cast::<Work<T>>()
496+
};
497+
let this = unsafe { &*ptr };
498+
let action = &this.action;
499+
action.act();
500+
}
501+
}
502+
472503
impl<T: SimpleAction + Send> Work<T> {
473504
/// Construct a new Work from the given action.
474505
///
@@ -491,6 +522,20 @@ impl<T: SimpleAction + Send> Work<T> {
491522

492523
ArcWork(this)
493524
}
525+
}
526+
527+
impl<T: SimpleAction + Send + 'static> Work<T> {
528+
/// Construct a static worker.
529+
pub const fn new_static(action: T) -> Work<T> {
530+
let work = <ZephyrObject<k_work>>::new_raw();
531+
532+
unsafe {
533+
let addr = work.get_uninit();
534+
(*addr).handler = Some(StaticWork::<T>::handler);
535+
}
536+
537+
Work { work, action }
538+
}
494539

495540
/// Access the inner action.
496541
pub fn action(&self) -> &T {
@@ -517,6 +562,16 @@ impl<T: SimpleAction + Send> SubmittablePointer<T> for Arc<Work<T>> {
517562
}
518563
}
519564

565+
impl<T: SimpleAction + Send + 'static> SubmittablePointer<T> for &'static Work<T> {
566+
fn submit(self) -> crate::Result<SubmitResult> {
567+
StaticWork(self).submit()
568+
}
569+
570+
fn submit_to_queue(self, queue: &'static WorkQueue) -> crate::Result<SubmitResult> {
571+
StaticWork(self).submit_to_queue(queue)
572+
}
573+
}
574+
520575
impl ObjectInit<k_work> for ZephyrObject<k_work> {
521576
fn init(item: *mut k_work) {
522577
// SAFETY: The handler was stashed in this field when constructing. At this point, the item

0 commit comments

Comments
 (0)