Mutex
=====

Mutex is short for "mutual exclusion"; a mutex provides mutually
exclusive access to a shared resource. A mutex provides *priority
inheritance* in order to prevent *priority inversion*. Priority
inversion occurs when a higher priority task is waiting on a resource
owned by a lower priority task. Using a mutex, the lower priority task
will inherit the highest priority of any task waiting on the mutex.

Description
-------------

The first order of business when using a mutex is to declare the mutex
globally. The mutex needs to be initialized before it is used (see the
examples). It is generally a good idea to initialize the mutex before
tasks start running in order to avoid a task possibly using the mutex
before it is initialized.

When a task wants exclusive access to a shared resource it needs to
obtain the mutex by calling :c:func:`os_mutex_pend`. If the mutex is currently
owned by a different task (a lower priority task), the requesting task
will be put to sleep and the owners priority will be elevated to the
priority of the requesting task. Note that multiple tasks can request
ownership and the current owner is elevated to the highest priority of
any task waitin on the mutex. When the task is done using the shared
resource, it needs to release the mutex by called :c:func:`os_mutex_release`.
There needs to be one release per call to pend. Note that nested calls
to :c:func:`os_mutex_pend` are allowed but there needs to be one release per
pend.

The following example will illustrate how priority inheritance works. In
this example, the task number is the same as its priority. Remember that
the lower the number, the higher the priority (i.e. priority 0 is higher
priority than priority 1). Suppose that task 5 gets ownership of a mutex
but is preempted by task 4. Task 4 attempts to gain ownership of the
mutex but cannot as it is owned by task 5. Task 4 is put to sleep and
task 5 is temporarily raised to priority 4. Before task 5 can release
the mutex, task 3 runs and attempts to acquire the mutex. At this point,
both task 3 and task 4 are waiting on the mutex (sleeping). Task 5 now
runs at priority 3 (the highest priority of all the tasks waiting on the
mutex). When task 5 finally releases the mutex it will be preempted as
two higher priority tasks are waiting for it.

Note that when multiple tasks are waiting on a mutex owned by another
task, once the mutex is released the highest priority task waiting on
the mutex is run.

API
----

.. doxygengroup:: OSMutex
    :content-only:
    :members:
