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/05/24 14:00:34 UTC

[incubator-nuttx] branch master updated: include:add recursive lock

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


The following commit(s) were added to refs/heads/master by this push:
     new 247a13cc02 include:add recursive lock
247a13cc02 is described below

commit 247a13cc02a56e2e81742e81c3d122b7e1a920ab
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Thu May 12 16:07:01 2022 +0800

    include:add recursive lock
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 include/nuttx/mutex.h | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 213 insertions(+)

diff --git a/include/nuttx/mutex.h b/include/nuttx/mutex.h
index f52cd36d04..c15e1ece44 100644
--- a/include/nuttx/mutex.h
+++ b/include/nuttx/mutex.h
@@ -28,6 +28,8 @@
 #include <stdbool.h>
 #include <errno.h>
 #include <assert.h>
+#include <unistd.h>
+#include <nuttx/sched.h>
 #include <nuttx/semaphore.h>
 
 /****************************************************************************
@@ -35,6 +37,7 @@
  ****************************************************************************/
 
 #define MUTEX_INITIALIZER    SEM_INITIALIZER(1);
+#define RMUTEX_INITIALIZER   {SEM_INITIALIZER(1), INVALID_PROCESS_ID, 0}
 
 /****************************************************************************
  * Public Type Definitions
@@ -42,6 +45,15 @@
 
 typedef sem_t mutex_t;
 
+struct rmutex_s
+{
+  mutex_t mutex;
+  pid_t holder;
+  uint16_t count;
+};
+
+typedef struct rmutex_s rmutex_t;
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -205,6 +217,207 @@ static inline int nxmutex_unlock(FAR mutex_t *mutex)
   return nxsem_post(mutex);
 }
 
+/****************************************************************************
+ * Name: nxrmutex_init
+ *
+ * Description:
+ *   This function initializes the UNNAMED recursive mutex. Following a
+ *   successful call to nxrmutex_init(), the recursive mutex may be used in
+ *   subsequent calls to nxrmutex_lock(), nxrmutex_unlock(),
+ *   and nxrmutex_trylock(). The recursive mutex remains usable
+ *   until it is destroyed.
+ *
+ * Parameters:
+ *   rmutex - Recursive mutex to be initialized
+ *
+ * Return Value:
+ *   This is an internal OS interface and should not be used by applications.
+ *   It follows the NuttX internal error return policy:  Zero (OK) is
+ *   returned on success.  A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+static inline int nxrmutex_init(FAR rmutex_t *rmutex)
+{
+  rmutex->count = 0;
+  rmutex->holder = INVALID_PROCESS_ID;
+  return nxmutex_init(&rmutex->mutex);
+}
+
+/****************************************************************************
+ * Name: nxrmutex_destroy
+ *
+ * Description:
+ *   This function destroy the UNNAMED recursive mutex.
+ *
+ * Parameters:
+ *   rmutex - Recursive mutex to be destroyed
+ *
+ * Return Value:
+ *   This is an internal OS interface and should not be used by applications.
+ *   It follows the NuttX internal error return policy:  Zero (OK) is
+ *   returned on success.  A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+static inline int nxrmutex_destroy(FAR rmutex_t *rmutex)
+{
+  return nxmutex_destroy(&rmutex->mutex);
+}
+
+/****************************************************************************
+ * Name: nrxmutex_lock
+ *
+ * Description:
+ *   This function attempts to lock the recursive mutex referenced by
+ *   'rmutex'.The recursive mutex can be locked multiple times in the same
+ *   thread.
+ *
+ * Parameters:
+ *   rmutex - Recursive mutex descriptor.
+ *
+ * Return Value:
+ *   This is an internal OS interface and should not be used by applications.
+ *   It follows the NuttX internal error return policy:  Zero (OK) is
+ *   returned on success.  A negated errno value is returned on failure.
+ *   Possible returned errors:
+ *
+ ****************************************************************************/
+
+static inline int nxrmutex_lock(FAR rmutex_t *rmutex)
+{
+  int ret = OK;
+  pid_t tid = gettid();
+
+  if (rmutex->holder == tid)
+    {
+      DEBUGASSERT(rmutex->count < UINT16_MAX);
+      rmutex->count++;
+    }
+  else
+    {
+      ret = nxmutex_lock(&rmutex->mutex);
+      if (ret == OK)
+        {
+          rmutex->holder = tid;
+          rmutex->count = 1;
+        }
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nxrmutex_trylock
+ *
+ * Description:
+ *   This function locks the recursive mutex if the recursive mutex is
+ *   currently not locked or the same thread call.
+ *   If the recursive mutex is locked and other thread call it,
+ *   the call returns without blocking.
+ *
+ * Parameters:
+ *   rmutex - Recursive mutex descriptor.
+ *
+ * Return Value:
+ *   This is an internal OS interface and should not be used by applications.
+ *   It follows the NuttX internal error return policy:  Zero (OK) is
+ *   returned on success.  A negated errno value is returned on failure.
+ *   Possible returned errors:
+ *
+ *     -EINVAL - Invalid attempt to lock the recursive mutex
+ *     -EAGAIN - The recursive mutex is not available.
+ *
+ ****************************************************************************/
+
+static inline int nxrmutex_trylock(FAR rmutex_t *rmutex)
+{
+  int ret = OK;
+  pid_t tid = gettid();
+
+  if (rmutex->holder == tid)
+    {
+      DEBUGASSERT(rmutex->count < UINT16_MAX);
+      rmutex->count++;
+    }
+  else
+    {
+      ret = nxmutex_trylock(&rmutex->mutex);
+      if (ret == OK)
+      {
+        rmutex->holder = tid;
+        rmutex->count = 1;
+      }
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nxrmutex_is_locked
+ *
+ * Description:
+ *   This function get the lock state the recursive mutex
+ *   referenced by 'rmutex'.
+ *
+ * Parameters:
+ *   rmutex - Recursive mutex descriptor.
+ *
+ * Return Value:
+ *
+ ****************************************************************************/
+
+static inline bool nxrmutex_is_locked(FAR rmutex_t *rmutex)
+{
+  return rmutex->count > 0;
+}
+
+/****************************************************************************
+ * Name: nxrmutex_unlock
+ *
+ * Description:
+ *   This function attempts to unlock the recursive mutex
+ *   referenced by 'rmutex'.
+ *
+ * Parameters:
+ *   rmutex - Recursive mutex descriptor.
+ *
+ * Return Value:
+ *   This is an internal OS interface and should not be used by applications.
+ *   It follows the NuttX internal error return policy:  Zero (OK) is
+ *   returned on success.  A negated errno value is returned on failure.
+ *   Possible returned errors:
+ *
+ * Assumptions:
+ *   This function may be called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static inline int nxrmutex_unlock(FAR rmutex_t *rmutex)
+{
+  int ret = OK;
+  pid_t tid = gettid();
+
+  if (rmutex->holder != tid)
+  {
+    return -EPERM;
+  }
+
+  DEBUGASSERT(rmutex->count > 0);
+  if (rmutex->count == 1)
+    {
+      rmutex->count = 0;
+      rmutex->holder = INVALID_PROCESS_ID;
+      ret = nxmutex_unlock(&rmutex->mutex);
+    }
+  else
+    {
+      rmutex->count--;
+    }
+
+  return ret;
+}
+
 #undef EXTERN
 #ifdef __cplusplus
 }