#[repr(transparent)]pub struct Queue(_);
Expand description
A kernel work queue.
Wraps the kernel’s C struct workqueue_struct
.
It allows work items to be queued to run on thread pools managed by the kernel. Several are
always available, for example, the ones returned by system
, system_highpri
,
system_long
, etc.
Examples
The following example is the simplest way to launch a work item:
spawn_work_item!(workqueue::system(), || pr_info!("Hello from a work item\n"))?;
The following example is used to create a work item and enqueue it several times. We note that enqueuing while the work item is already queued is a no-op, so we enqueue it when it is not enqueued yet.
use core::sync::atomic::{AtomicU32, Ordering};
use kernel::sync::UniqueArc;
struct Example {
count: AtomicU32,
work: Work,
}
kernel::impl_self_work_adapter!(Example, work, |w| {
let count = w.count.fetch_add(1, Ordering::Relaxed);
pr_info!("Called with count={}\n", count);
// Queue again if the count is less than 10.
if count < 10 {
workqueue::system().enqueue(w);
}
});
let e = UniqueArc::try_new(Example {
count: AtomicU32::new(0),
// SAFETY: `work` is initialised below.
work: unsafe { Work::new() },
})?;
kernel::init_work_item!(&e);
// Queue the first time.
workqueue::system().enqueue(e.into());
The following example has two different work items in the same struct, which allows it to be queued twice.
use core::sync::atomic::{AtomicU32, Ordering};
use kernel::sync::{Arc, UniqueArc};
struct Example {
work1: Work,
work2: Work,
}
kernel::impl_self_work_adapter!(Example, work1, |_| pr_info!("First work\n"));
struct SecondAdapter;
kernel::impl_work_adapter!(SecondAdapter, Example, work2, |_| pr_info!("Second work\n"));
let e = UniqueArc::try_new(Example {
// SAFETY: `work1` is initialised below.
work1: unsafe { Work::new() },
// SAFETY: `work2` is initialised below.
work2: unsafe { Work::new() },
})?;
kernel::init_work_item!(&e);
kernel::init_work_item_adapter!(SecondAdapter, &e);
let e = Arc::from(e);
// Enqueue the two different work items.
workqueue::system().enqueue(e.clone());
workqueue::system().enqueue_adapter::<SecondAdapter>(e);
Implementations
sourceimpl Queue
impl Queue
sourcepub fn try_new(name: Arguments<'_>) -> Result<BoxedQueue>
pub fn try_new(name: Arguments<'_>) -> Result<BoxedQueue>
Tries to allocate a new work queue.
Callers should first consider using one of the existing ones (e.g. system
) before
deciding to create a new one.
sourcepub fn enqueue<T: WorkAdapter<Target = T>>(&self, w: Arc<T>) -> bool
pub fn enqueue<T: WorkAdapter<Target = T>>(&self, w: Arc<T>) -> bool
Enqueues a work item.
Returns true
if the work item was successfully enqueue; returns false
if it had already
been (and continued to be) enqueued.
sourcepub fn enqueue_adapter<A: WorkAdapter + ?Sized>(&self, w: Arc<A::Target>) -> bool
pub fn enqueue_adapter<A: WorkAdapter + ?Sized>(&self, w: Arc<A::Target>) -> bool
Enqueues a work item with an explicit adapter.
Returns true
if the work item was successfully enqueue; returns false
if it had already
been (and continued to be) enqueued.
sourcepub fn try_spawn<T: 'static + Send + Fn()>(
&self,
key: &'static LockClassKey,
func: T
) -> Result
pub fn try_spawn<T: 'static + Send + Fn()>(
&self,
key: &'static LockClassKey,
func: T
) -> Result
Tries to spawn the given function or closure as a work item.
Users are encouraged to use spawn_work_item
as it automatically defines the lock class
key to be used.