#[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::UniqueRef;

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 = UniqueRef::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::{Ref, UniqueRef};

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 = UniqueRef::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 = Ref::from(e);

// Enqueue the two different work items.
workqueue::system().enqueue(e.clone());
workqueue::system().enqueue_adapter::<SecondAdapter>(e);

Implementations

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.

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.

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.

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.

Trait Implementations

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.