doc: Edit microkernel_mutexes.rst; add ReST syntax, clarifications.

Making all the files in this section consistent with :dfn: in
the intro paragraph, API headings, present-tense verbs in APIs.
Clarified paragraphs on priorty-bazed waiting and priority
inheritance.

Change-Id: I26cc49926bc49c9c68300b6249aeb52c1be33625
Signed-off-by: L.S. Cook <leonax.cook@intel.com>
This commit is contained in:
L.S. Cook 2016-02-29 10:20:08 -08:00 committed by Gerrit Code Review
commit fd2c760593

View file

@ -6,7 +6,7 @@ Mutexes
Concepts Concepts
******** ********
The microkernel's mutex objects provide reentrant mutex The microkernel's :dfn:`mutex` objects provide reentrant mutex
capabilities with basic priority inheritance. capabilities with basic priority inheritance.
Each mutex allows multiple tasks to safely share an associated Each mutex allows multiple tasks to safely share an associated
@ -14,32 +14,33 @@ resource by ensuring mutual exclusivity while the resource is
being accessed by a task. being accessed by a task.
Any number of mutexes can be defined in a microkernel system. Any number of mutexes can be defined in a microkernel system.
Each mutex has a name that uniquely identifies it. Typically, Each mutex needs a **name** that uniquely identifies it. Typically,
the name should relate to the resource being shared, but this is the name should relate to the resource being shared, although this
not a requirement. is not a requirement.
A task that needs to use a shared resource must first gain A task that needs to use a shared resource must first gain exclusive
exclusive access by locking the associated mutex. When the mutex access by locking the associated mutex. If the mutex is already locked
is already locked by another task, the requesting task may by another task, the requesting task can wait for the mutex to be
choose to wait for the mutex to be unlocked. After obtaining the lock, unlocked.
a task can safely use the shared resource for as long as needed.
When the task no longer needs the resource, it must unlock the
associated mutex to allow other tasks to use the resource.
Any number of tasks may wait on a locked mutex simultaneously. After obtaining the mutex, the task may safely use the shared
When there is more than one waiting task, the mutex locks the resource for as long as needed. And when the task no longer needs
resource for the highest priority task that has waited the longest the resource, it must release the associated mutex to allow
first. other tasks to use the resource.
Priority inheritance occurs whenever a high priority task waits Any number of tasks may wait on a locked mutex. When more than one
on a mutex that is locked by a lower priority task. The priority task is waiting, the mutex locks the resource for the highest-priority
of the lower priority task increases temporarily to the priority task that has waited the longest first; this is known as
of the highest priority task that is waiting on a mutex held by :dfn:`priority-based waiting`. The order is decided when a task decides
the lower priority task. This allows the lower priority to wait on the object: it is queued in priority order.
task to complete its work and unlock the mutex as quickly as
possible. Once the mutex has been unlocked, the lower priority task The task currently owning the mutex is also eligible for :dfn:`priority inheritance`.
sets its task priority to the priority it had prior to locking that Priority inheritance is the concept by which a task of lower priority gets its
mutex. priority *temporarily* elevated to the priority of the highest-priority
task that is waiting on a mutex held by the lower priority task. Thus, the
lower-priority task can complete its work and release the mutex as quickly
as possible. Once the mutex has been released, the lower-priority task resets
its task priority to the priority it had before locking that mutex.
.. note:: .. note::
@ -49,29 +50,26 @@ mutex.
When two or more tasks wait on a mutex held by a lower priority task, the When two or more tasks wait on a mutex held by a lower priority task, the
kernel adjusts the owning task's priority each time a task begins waiting kernel adjusts the owning task's priority each time a task begins waiting
(or gives up waiting). When the mutex is eventually released the owning (or gives up waiting). When the mutex is eventually released, the owning
task's priority correctly reverts to its original non-elevated priority. task's priority correctly reverts to its original non-elevated priority.
.. note:: The kernel does *not* fully support priority inheritance when a task holds
two or more mutexes simultaneously. This situation can result in the task's
priority not reverting to its original non-elevated priority when all mutexes
have been released. Preferably, a task holds only a single mutex when multiple
mutexes are shared between tasks of different priorities.
The kernel does *not* fully support priority inheritance when a task The microkernel also allows a task to repeatedly lock a mutex it has already
holds two or more mutexes simultaneously. This situation can result locked. This ensures that the task can access the resource at a point in its
in the task's priority not reverting to its original non-elevated execution when the resource may or may not already be locked. A mutex that is
priority when all mutexes have been released. It is recommended that repeatedly locked must be unlocked an equal number of times before the mutex
a task hold only a single mutex at a time when multiple mutexes are can release the resource completely.
shared between tasks of different priorities.
The microkernel also allows a task to repeatedly lock a mutex it
already locked. This ensures that the task can access the resource
at a point in its execution when the resource may or may not
already be locked. A mutex that is repeatedly locked must be unlocked
an equal number of times before the mutex releases the resource
completely.
Purpose Purpose
******* *******
Use mutexes to provide exclusive access to a resource,
such as a physical device. Use mutexes to provide exclusive access to a resource, such as a physical
device.
Usage Usage
***** *****
@ -87,7 +85,7 @@ The following parameters must be defined:
Public Mutex Public Mutex
------------ ------------
Define the mutex in the application's MDEF using the following syntax: Define the mutex in the application's MDEF file with the following syntax:
.. code-block:: console .. code-block:: console
@ -119,12 +117,14 @@ For example, the following code defines a private mutex named ``XYZ``.
DEFINE_MUTEX(XYZ); DEFINE_MUTEX(XYZ);
To utilize this mutex from a different source file use the following syntax: The following syntax allows this mutex to be accessed from a different
source file:
.. code-block:: c .. code-block:: c
extern const kmutex_t XYZ; extern const kmutex_t XYZ;
Example: Locking a Mutex with No Conditions Example: Locking a Mutex with No Conditions
=========================================== ===========================================
@ -138,6 +138,7 @@ mutex is in use.
lineto(200,100); lineto(200,100);
task_mutex_unlock(XYZ); task_mutex_unlock(XYZ);
Example: Locking a Mutex with a Conditional Timeout Example: Locking a Mutex with a Conditional Timeout
=================================================== ===================================================
@ -179,13 +180,15 @@ This code gives an immediate warning when a mutex is in use.
APIs APIs
**** ****
The following Mutex APIs are provided by :file:`microkernel.h`: Mutex APIs provided by :file:`microkernel.h`
============================================
:cpp:func:`task_mutex_lock()` :cpp:func:`task_mutex_lock()`
Waits on a locked mutex for the period of time defined by the timeout Wait on a locked mutex for the period of time defined by the timeout
parameter. If the mutex becomes available during that period, the function parameter. Lock the mutex and increment the lock count if the mutex
locks the mutex, and increments the lock count. becomes available during that period.
:c:func:`task_mutex_unlock()` :cpp:func:`task_mutex_unlock()`
Decrements a mutex lock count, and unlocks the mutex when the count Decrement a mutex lock count, and unlock the mutex when the count
reaches zero. reaches zero.