Struct embassy_executor::raw::Executor
source · pub struct Executor { /* private fields */ }
Expand description
原始执行器
这是 Embassy 执行器的核心。它是底层的需要手动处理唤醒和任务执行。更推荐使用 上层执行器
原始执行器将唤醒和调度留给你去处理:
- 为了让执行器工作,调用
poll()
。这会运行队列中的所有任务(所有“想运行”的任务)。 - 如下所示,你必须提供一个 pender 函数。执行器会通知你有工作可以做了。你必须尽可能快的调用你的
poll()
。 - 启用
arch-xx
特性会为你定义一个 pender 函数。这意味着你只能使用架构/平台为你实现的执行器。 如果你有一个不同的执行器,你就不能启用arch-xx
特性。
pender 可以在任何上下文中被调用: 任何线程,任何中断优先级。它也可能被任何执行器的方法同时调用, 你必须正确的处理这些情况。
特别说明,你不能在 pender 的回调中直接调用 poll
,因为这违反了 poll
不能被重入调用的要求。
pender 函数被暴露的名称必须为 __pender
,并且需要如下的签名:
#[export_name = "__pender"]
fn pender(context: *mut ()) {
// schedule `poll()` to be called
}
context
参数是执行器将传递给 pender 的任意数据。你可以在调用 Executor::new()
时设置 context
。
例如,你可以使用它来区分执行器,也可以传一个回调指针。
Raw executor.
This is the core of the Embassy executor. It is low-level, requiring manual handling of wakeups and task polling. If you can, prefer using one of the higher level executors.
The raw executor leaves it up to you to handle wakeups and scheduling:
- To get the executor to do work, call
poll()
. This will poll all queued tasks (all tasks that “want to run”). - You must supply a pender function, as shown below. The executor will call it to notify you
it has work to do. You must arrange for
poll()
to be called as soon as possible. - Enabling
arch-xx
features will define a pender function for you. This means that you are limited to using the executors provided to you by the architecture/platform implementation. If you need a different executor, you must not enablearch-xx
features.
The pender can be called from any context: any thread, any interrupt priority
level, etc. It may be called synchronously from any Executor
method call as well.
You must deal with this correctly.
In particular, you must NOT call poll
directly from the pender callback, as this violates
the requirement for poll
to not be called reentrantly.
The pender function must be exported with the name __pender
and have the following signature:
#[export_name = "__pender"]
fn pender(context: *mut ()) {
// schedule `poll()` to be called
}
The context
argument is a piece of arbitrary data the executor will pass to the pender.
You can set the context
when calling Executor::new()
. You can use it to, for example,
differentiate between executors, or to pass a pointer to a callback that should be called.
Implementations§
source§impl Executor
impl Executor
sourcepub unsafe fn poll(&'static self)
pub unsafe fn poll(&'static self)
拉取当前执行器队列中的所有任务
这个方法会遍历队列中所有待拉取的任务(如刚被创建的或被唤醒的)。其他任务不会被拉取。
在收到 pender 调用后,必须调用 poll
。即使 pender 没有被调用,也可以去调用 poll
,
只是这样会浪费资源。。
安全性
禁止在相同的执行器中重入的调用 poll
。
特别注意 poll
可能会被并发调用。因此,禁止在 pender 的回调中直接调用 poll()
。换而言之,
回调方法必须稍后再以某种调度方式调用 poll()
,这时你必须确认 poll()
已经没有在运行。
Poll all queued tasks in this executor.
This loops over all tasks that are queued to be polled (i.e. they’re freshly spawned or they’ve been woken). Other tasks are not polled.
You must call poll
after receiving a call to the pender. It is OK
to call poll
even when not requested by the pender, but it wastes
energy.
Safety
You must NOT call poll
reentrantly on the same executor.
In particular, note that poll
may call the pender synchronously. Therefore, you
must NOT directly call poll()
from the pender callback. Instead, the callback has to
somehow schedule for poll()
to be called later, at a time you know for sure there’s
no poll()
already running.