Documentation:add nxmutex Description
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
parent
577e550698
commit
1c416b1712
|
@ -13,6 +13,7 @@ in other header files.
|
|||
arch.rst
|
||||
board.rst
|
||||
time_clock.rst
|
||||
mutex.rst
|
||||
wqueue.rst
|
||||
addrenv.rst
|
||||
nuttx.rst
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
=====================
|
||||
Mutual Exclusion lock
|
||||
=====================
|
||||
|
||||
nxmutex
|
||||
=======
|
||||
|
||||
Use `nxmutex` prefixed api to 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 do not support priority inheritance by default
|
||||
|
||||
usually usage:
|
||||
|
||||
call nxmutex_init() for driver, when two tasks will use driver, their timing will be:
|
||||
=============== ================
|
||||
taskA taskB
|
||||
================ ================
|
||||
nxmutex_lock() nxmutex_lock()
|
||||
================ ================
|
||||
get lock running wait for lock
|
||||
================= ================
|
||||
nxmutex_unlock() wait for lock
|
||||
================= ================
|
||||
get lock running
|
||||
================= ================
|
||||
nxmutex_unlock()
|
||||
|
||||
Priority inheritance
|
||||
====================
|
||||
|
||||
If `CONFIG_PRIORITY_INHERITANCE` is chosen, the priority of the task holding the mutex
|
||||
may be changed.
|
||||
This is an 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 running order
|
||||
#. `Ltask` hold a mutex first
|
||||
#. Then `Htask` running, `Htask` can't hold the mutex,so wait
|
||||
#. Then `Mtask` running, 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 running order
|
||||
#. `Ltask` hold a mutex first.
|
||||
#. Then `Htask` running, `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 running.
|
||||
#. When 'Ltask' finish, `Htask` will start running.
|
||||
#. When `Htask` finish, `Mtask` will start running.
|
||||
|
||||
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 resets mutex states by 'mutex'.
|
||||
|
||||
:param mutex: mutex descriptor.
|
||||
|
||||
:return:
|
||||
Zero(OK) is returned on success.A negated errno value is returned on failure.
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue