Update docs
This commit is contained in:
parent
e4f3979ec8
commit
890f29ccfe
@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- Replaced Pender. Implementations now must define an extern function called `__pender`.
|
||||||
|
|
||||||
## 0.2.1 - 2023-08-10
|
## 0.2.1 - 2023-08-10
|
||||||
|
|
||||||
- Avoid calling `pend()` when waking expired timers
|
- Avoid calling `pend()` when waking expired timers
|
||||||
|
@ -291,21 +291,6 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Platform/architecture-specific action executed when an executor has pending work.
|
|
||||||
///
|
|
||||||
/// When a task within an executor is woken, the `Pender` is called. This does a
|
|
||||||
/// platform/architecture-specific action to signal there is pending work in the executor.
|
|
||||||
/// When this happens, you must arrange for [`Executor::poll`] to be called.
|
|
||||||
///
|
|
||||||
/// You can think of it as a waker, but for the whole executor.
|
|
||||||
///
|
|
||||||
/// Platform/architecture implementations must provide a function that can be referred to as:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// extern "Rust" {
|
|
||||||
/// fn __pender(context: *mut ());
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) struct Pender(*mut ());
|
pub(crate) struct Pender(*mut ());
|
||||||
|
|
||||||
@ -451,15 +436,31 @@ impl SyncExecutor {
|
|||||||
///
|
///
|
||||||
/// - To get the executor to do work, call `poll()`. This will poll all queued tasks (all tasks
|
/// - To get the executor to do work, call `poll()`. This will poll all queued tasks (all tasks
|
||||||
/// that "want to run").
|
/// that "want to run").
|
||||||
/// - You must supply a [`Pender`]. The executor will call it to notify you it has work
|
/// - You must supply a pender function, as shown below. The executor will call it to notify you
|
||||||
/// to do. You must arrange for `poll()` to be called as soon as possible.
|
/// 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 enable `arch-xx` features.
|
||||||
///
|
///
|
||||||
/// The [`Pender`] can be called from *any* context: any thread, any interrupt priority
|
/// 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.
|
/// level, etc. It may be called synchronously from any `Executor` method call as well.
|
||||||
/// You must deal with this correctly.
|
/// You must deal with this correctly.
|
||||||
///
|
///
|
||||||
/// In particular, you must NOT call `poll` directly from the pender callback, as this violates
|
/// 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 requirement for `poll` to not be called reentrantly.
|
||||||
|
///
|
||||||
|
/// The pender function must be exported with the name `__pender` and have the following signature:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #[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.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Executor {
|
pub struct Executor {
|
||||||
pub(crate) inner: SyncExecutor,
|
pub(crate) inner: SyncExecutor,
|
||||||
@ -474,9 +475,9 @@ impl Executor {
|
|||||||
|
|
||||||
/// Create a new executor.
|
/// Create a new executor.
|
||||||
///
|
///
|
||||||
/// When the executor has work to do, it will call the [`Pender`].
|
/// When the executor has work to do, it will call the pender function and pass `context` to it.
|
||||||
///
|
///
|
||||||
/// See [`Executor`] docs for details on `Pender`.
|
/// See [`Executor`] docs for details on the pender.
|
||||||
pub fn new(context: *mut ()) -> Self {
|
pub fn new(context: *mut ()) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: SyncExecutor::new(Pender(context)),
|
inner: SyncExecutor::new(Pender(context)),
|
||||||
@ -502,16 +503,16 @@ impl Executor {
|
|||||||
/// This loops over all tasks that are queued to be polled (i.e. they're
|
/// 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.
|
/// 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
|
/// 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
|
/// to call `poll` even when not requested by the pender, but it wastes
|
||||||
/// energy.
|
/// energy.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// You must NOT call `poll` reentrantly on the same executor.
|
/// You must NOT call `poll` reentrantly on the same executor.
|
||||||
///
|
///
|
||||||
/// In particular, note that `poll` may call the `Pender` synchronously. Therefore, you
|
/// 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
|
/// 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
|
/// somehow schedule for `poll()` to be called later, at a time you know for sure there's
|
||||||
/// no `poll()` already running.
|
/// no `poll()` already running.
|
||||||
pub unsafe fn poll(&'static self) {
|
pub unsafe fn poll(&'static self) {
|
||||||
|
Loading…
Reference in New Issue
Block a user