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
}