201 lines
6.8 KiB
ReStructuredText
201 lines
6.8 KiB
ReStructuredText
.. _api_terms:
|
|
|
|
API Terminology
|
|
###############
|
|
|
|
The following terms may be used as shorthand API tags to indicate the
|
|
allowed calling context (thread, ISR, pre-kernel), the effect of a call
|
|
on the current thread state, and other behavioral characteristics.
|
|
|
|
:ref:`api_term_reschedule`
|
|
if executing the function reaches a reschedule point
|
|
:ref:`api_term_sleep`
|
|
if executing the function can cause the invoking thread to sleep
|
|
:ref:`api_term_no-wait`
|
|
if a parameter to the function can prevent the invoking thread from
|
|
trying to sleep
|
|
:ref:`api_term_isr-ok`
|
|
if the function can be safely called and will have its specified
|
|
effect whether invoked from interrupt or thread context
|
|
:ref:`api_term_pre-kernel-ok`
|
|
if the function can be safely called before the kernel has been fully
|
|
initialized and will have its specified effect when invoked from that
|
|
context.
|
|
:ref:`api_term_async`
|
|
if the function may return before the operation it initializes is
|
|
complete (i.e. function return and operation completion are
|
|
asynchronous)
|
|
:ref:`api_term_supervisor`
|
|
if the calling thread must have supervisor privileges to execute the
|
|
function
|
|
|
|
Details on the behavioral impact of each attribute are in the following
|
|
sections.
|
|
|
|
.. _api_term_reschedule:
|
|
|
|
reschedule
|
|
==========
|
|
|
|
The reschedule attribute is used on a function that can reach a
|
|
:ref:`reschedule point <scheduling_v2>` within its execution.
|
|
|
|
Details
|
|
-------
|
|
|
|
The significance of this attribute is that when a rescheduling function
|
|
is invoked by a thread it is possible for that thread to be suspended as
|
|
a consequence of a higher-priority thread being made ready. Whether the
|
|
suspension actually occurs depends on the operation associated with the
|
|
reschedule point and the relative priorities of the invoking thread and
|
|
the head of the ready queue.
|
|
|
|
Note that in the case of timeslicing, or reschedule points executed from
|
|
interrupts, any thread may be suspended in any function.
|
|
|
|
Functions that are not **reschedule** may be invoked from either thread
|
|
or interrupt context.
|
|
|
|
Functions that are **reschedule** may be invoked from thread context.
|
|
|
|
Functions that are **reschedule** but not **sleep** may be invoked from
|
|
interrupt context.
|
|
|
|
.. _api_term_sleep:
|
|
|
|
sleep
|
|
=====
|
|
|
|
The sleep attribute is used on a function that can cause the invoking
|
|
thread to sleep.
|
|
|
|
Explanation
|
|
-----------
|
|
|
|
This attribute is of relevance specifically when considering
|
|
applications that use only non-preemptible threads, because the kernel
|
|
will not replace a running cooperative-only thread at a reschedule point
|
|
unless that thread has explicitly invoked an operation that caused it to
|
|
sleep.
|
|
|
|
This attribute does not imply the function will sleep unconditionally,
|
|
but that the operation may require an invoking thread that would have to
|
|
suspend, wait, or invoke :cpp:func:`k_yield()` before it can complete
|
|
its operation. This behavior may be mediated by **no-wait**.
|
|
|
|
Functions that are **sleep** are implicitly **reschedule**.
|
|
|
|
Functions that are **sleep** may be invoked from thread context.
|
|
|
|
Functions that are **sleep** may be invoked from interrupt and
|
|
pre-kernel contexts if and only if invoked in **no-wait** mode.
|
|
|
|
.. _api_term_no-wait:
|
|
|
|
no-wait
|
|
=======
|
|
|
|
The no-wait attribute is used on a function that is also **sleep** to
|
|
indicate that a parameter to the function can force an execution path
|
|
that will not cause the invoking thread to sleep.
|
|
|
|
Explanation
|
|
-----------
|
|
|
|
The paradigmatic case of a no-wait function is a function that takes a
|
|
timeout, to which :c:macro:`K_NO_WAIT` can be passed. The semantics of
|
|
this special timeout value are to execute the function's operation as
|
|
long as it can be completed immediately, and to return an error code
|
|
rather than sleep if it cannot.
|
|
|
|
It is use of the no-wait feature that allows functions like
|
|
:cpp:func:`k_sem_take` to be invoked from ISRs, since it is not
|
|
permitted to sleep in interrupt context.
|
|
|
|
A function with a no-wait path does not imply that taking that path
|
|
guarantees the function is synchronous.
|
|
|
|
Functions with this attribute may be invoked from interrupt and
|
|
pre-kernel contexts only when the parameter selects the no-wait path.
|
|
|
|
.. _api_term_isr-ok:
|
|
|
|
isr-ok
|
|
======
|
|
|
|
The isr-ok attribute is used on a function to indicate that it works
|
|
whether it is being invoked from interrupt or thread context.
|
|
|
|
Explanation
|
|
-----------
|
|
|
|
Any function that is not **sleep** is inherently **isr-ok**. Functions
|
|
that are **sleep** are **isr-ok** if the implementation ensures that the
|
|
documented behavior is implemented even if called from an interrupt
|
|
context. This may be achieved by having the implementation detect the
|
|
calling context and transfer the operation that would sleep to a thread,
|
|
or by documenting that when invoked from a non-thread context the
|
|
function will return a specific error (generally ``-EWOULDBLOCK``).
|
|
|
|
Note that a function that is **no-wait** is safe to call from interrupt
|
|
context only when the no-wait path is selected. **isr-ok** functions
|
|
need not provide a no-wait path.
|
|
|
|
.. _api_term_pre-kernel-ok:
|
|
|
|
pre-kernel-ok
|
|
=============
|
|
|
|
The pre-kernel-ok attribute is used on a function to indicate that it
|
|
works as documented even when invoked before the kernel main thread has
|
|
been started.
|
|
|
|
Explanation
|
|
-----------
|
|
|
|
This attribute is similar to **isr-ok** in function, but is intended for
|
|
use by any API that is expected to be called in :c:func:`DEVICE_INIT()`
|
|
or :c:func:`SYS_INIT()` calls that may be invoked with ``PRE_KERNEL_1``
|
|
or ``PRE_KERNEL_2`` initialization levels.
|
|
|
|
Generally a function that is **pre-kernel-ok** checks
|
|
:cpp:func:`k_is_pre_kernel` when determining whether it can fulfill its
|
|
required behavior. In many cases it would also check
|
|
:cpp:func:`k_is_in_isr` so it can be **isr-ok** as well.
|
|
|
|
.. _api_term_async:
|
|
|
|
async
|
|
=====
|
|
|
|
A function is **async** (i.e. asynchronous) if it may return before the
|
|
operation it initiates has completed. An asynchronous function will
|
|
generally provide a mechanism by which operation completion is reported,
|
|
e.g. a callback or event.
|
|
|
|
A function that is not asynchronous is synchronous, i.e. the operation
|
|
will always be complete when the function returns. As most functions
|
|
are synchronous this behavior does not have a distinct attribute to
|
|
identify it.
|
|
|
|
Explanation
|
|
-----------
|
|
|
|
Be aware that **async** is orthogonal to context-switching. Some APIs
|
|
may provide completion information through a callback, but may suspend
|
|
while waiting for the resource necessary to initiate the operation; an
|
|
example is :cpp:func:`spi_transceive_async`.
|
|
|
|
If a function is both **no-wait** and **async** then selecting the
|
|
no-wait path only guarantees that the function will not sleep. It does
|
|
not affect whether the operation will be completed before the function
|
|
returns.
|
|
|
|
.. _api_term_supervisor:
|
|
|
|
supervisor
|
|
==========
|
|
|
|
The supervisor attribute is relevant only in user-mode applications, and
|
|
indicates that the function cannot be invoked from user mode.
|