Skip to content

Commit

Permalink
Documentation:add nxmutex Description
Browse files Browse the repository at this point in the history
Signed-off-by: anjiahao <[email protected]>
  • Loading branch information
anjiahao1 committed Oct 19, 2022
1 parent ec7b424 commit d9b38f7
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 0 deletions.
1 change: 1 addition & 0 deletions Documentation/reference/os/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ in other header files.
arch.rst
board.rst
time_clock.rst
mutex.rst
wqueue.rst
addrenv.rst
nuttx.rst
Expand Down
130 changes: 130 additions & 0 deletions Documentation/reference/os/mutex.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
=====================
Mutual Exclusion lock
=====================

nxmutex
=======

Use `nxmutex` prefixed api for protect resources.In fact, nxmutex is implemented
based on nxsem,The difference between nxmutex and nxsem is that nxmutex supports
priority inheritance by default, nxsem not support priority inheritance by default

usually usage:

call nxmutex_init() for driver,when two task will use driver, Their timing will be
============== ==============
taskA taskB
=============== ==============
nxmutex_lock() nxmutex_lock()
=============== ==============
get lock runing wait for lock
================ ==============
nxmutex_unlock() wait for lock
================ ===============
get lock runing
================ ===============
nxmutex_unlock

Priority inheritance
====================

if `CONFIG_PRIORITY_INHERITANCE` is chosen, The priority of the task holding the mutex
may be changed.
This is a example:

There are three tasks.Their priorities are high, medium, and low.
We refer to them as `Htask` `Mtask` `Ltask`

`Htask` and `Ltask` will hold the same mutex. `Mtask` does not hold mutex

if `CONFIG_PRIORITY_INHERITANCE` is not chosen, task runing order
#. `Ltask` hold a mutex first
#. Then `Htask` runing, `Htask` can't hold the mutex,so wait
#. Then `Mtask` runing, because `Mtask` priority higher than `Ltask`.
#. When `Mtask` finish, `Ltask` will start running.
#. When `Ltask` finish, `Htask` will start running.

From the above process, we can see that the medium-priority tasks run ahead of
the high-priority tasks, which is unacceptable.

if `CONFIG_PRIORITY_INHERITANCE` is chosen, task runing order
#. `Ltask` hold a mutex first.
#. Then `Htask` runing, `Htask` can't hold the mutex, then boost the priority of `Ltask`
to be the same as `Htask`.
#. Because `Ltask` priority is higher than `Mtask`,so `Mtask` not runing.
#. When 'Ltask' finish, `Htask` will start runing.
#. When `Htask` finish, `Mtask` will start runing.

Priority inheritance prevents medium-priority tasks from running ahead of
high-priority tasks

Api description
===============
.. c:function:: void nxmutex_init(FAR mutex_t *mutex)
This function initialize the UNNAMED mutex
:param mutex: mutex to be initialized.
:return:
Zero(OK) is returned on success.A negated errno value is returned on failure.
.. c:function:: void nxmutex_destroy(FAR mutex_t *mutex)
This function destroy the UNNAMED mutex
:param mutex: mutex to be destroyed.
:return:
Zero(OK) is returned on success.A negated errno value is returned on failure.
.. c:function:: void nxmutex_lock(FAR mutex_t *mutex)
This function attempts to lock the mutex referenced by 'mutex'. The
mutex is implemented with a semaphore, so if the semaphore value is
(<=) zero, then the calling task will not return until it successfully
acquires the lock.
:param mutex: mutex descriptor.
:return:
Zero(OK) is returned on success.A negated errno value is returned on failure.
.. c:function:: void nxmutex_trylock(FAR mutex_t *mutex)
This function locks the mutex only if the mutex is currently not locked.
If the mutex has been locked already, the call returns without blocking.
:param mutex: mutex descriptor.
:return:
Zero(OK) is returned on success.A negated errno value is returned on failure.
Possible returned errors:
EINVAL - Invalid attempt to lock the mutex
EAGAIN - The mutex is not available.
.. c:function:: void nxmutex_is_locked(FAR mutex_t *mutex)
This function get the lock state the mutex referenced by 'mutex'.
:param mutex: mutex descriptor.
:return:
if mutex is locked will return `ture`. if not will reutrn `false`
.. c:function:: void nxmutex_unlock(FAR mutex_t *mutex)
This function attempts to unlock the mutex referenced by 'mutex'.
:param mutex: mutex descriptor.
:return:
Zero(OK) is returned on success.A negated errno value is returned on failure.
.. c:function:: void nxmutex_reset(FAR mutex_t *mutex)
This function rset mutex states by 'mutex'.
:param mutex: mutex descriptor.
:return:
Zero(OK) is returned on success.A negated errno value is returned on failure.
6 changes: 6 additions & 0 deletions Documentation/reference/user/05_counting_semaphore.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ different thread posts the semaphore. Priority inheritance should
*never* be used in this signaling case. Subtle, strange behaviors may
result.

Semaphore does not support priority inheritance by default. If you need to
use a semaphore as a mutex you need to change its default behavior.

In user space, it is recommended to use pthread_mutex instead of
semaphore for resource protection

When priority inheritance is enabled with
``CONFIG_PRIORITY_INHERITANCE``, the default *protocol* for the
semaphore will be to use priority inheritance. For signaling semaphores,
Expand Down

0 comments on commit d9b38f7

Please sign in to comment.