Update docs
This commit is contained in:
parent
e4f3979ec8
commit
890f29ccfe
2 changed files with 29 additions and 24 deletions
|
@ -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/),
|
||||
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
|
||||
|
||||
- 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)]
|
||||
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
|
||||
/// that "want to run").
|
||||
/// - You must supply a [`Pender`]. 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.
|
||||
/// - 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 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.
|
||||
/// 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:
|
||||
///
|
||||
/// ```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)]
|
||||
pub struct Executor {
|
||||
pub(crate) inner: SyncExecutor,
|
||||
|
@ -474,9 +475,9 @@ impl 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 {
|
||||
Self {
|
||||
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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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.
|
||||
pub unsafe fn poll(&'static self) {
|
||||
|
|
Loading…
Reference in a new issue