You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/10/22 06:50:58 UTC
[incubator-nuttx] 04/04: Documentation:add nxmutex Description
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 1c416b1712ae41756f090139c7cd5ebebb2b6ba4
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Wed Oct 19 19:32:21 2022 +0800
Documentation:add nxmutex Description
Signed-off-by: anjiahao <an...@xiaomi.com>
---
Documentation/reference/os/index.rst | 1 +
Documentation/reference/os/mutex.rst | 130 +++++++++++++++++++++
.../reference/user/05_counting_semaphore.rst | 6 +
3 files changed, 137 insertions(+)
diff --git a/Documentation/reference/os/index.rst b/Documentation/reference/os/index.rst
index 65f822bc85..f0317126a9 100644
--- a/Documentation/reference/os/index.rst
+++ b/Documentation/reference/os/index.rst
@@ -13,6 +13,7 @@ in other header files.
arch.rst
board.rst
time_clock.rst
+ mutex.rst
wqueue.rst
addrenv.rst
nuttx.rst
diff --git a/Documentation/reference/os/mutex.rst b/Documentation/reference/os/mutex.rst
new file mode 100644
index 0000000000..008417b0b8
--- /dev/null
+++ b/Documentation/reference/os/mutex.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.
diff --git a/Documentation/reference/user/05_counting_semaphore.rst b/Documentation/reference/user/05_counting_semaphore.rst
index 693ba40769..638037718b 100644
--- a/Documentation/reference/user/05_counting_semaphore.rst
+++ b/Documentation/reference/user/05_counting_semaphore.rst
@@ -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,