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,