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/nuttx.git

commit 01864d262c80e4c0abb53094a4e7105fa6fc0f43
Author: yinshengkai <[email protected]>
AuthorDate: Mon May 6 15:54:51 2024 +0800

    sched: add mutex_holder and mutex_clocklock API
    
    Signed-off-by: yinshengkai <[email protected]>
---
 include/nuttx/mutex.h      |  86 ++++++++++++++++++++++++++++
 libs/libc/misc/lib_mutex.c | 140 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 213 insertions(+), 13 deletions(-)

diff --git a/include/nuttx/mutex.h b/include/nuttx/mutex.h
index f92a9d344b..e69017e807 100644
--- a/include/nuttx/mutex.h
+++ b/include/nuttx/mutex.h
@@ -131,6 +131,21 @@ int nxmutex_destroy(FAR mutex_t *mutex);
 
 bool nxmutex_is_hold(FAR mutex_t *mutex);
 
+/****************************************************************************
+ * Name: nxmutex_get_holder
+ *
+ * Description:
+ *   This function get the holder of the mutex referenced by 'mutex'.
+ *
+ * Parameters:
+ *   mutex - mutex descriptor.
+ *
+ * Return Value:
+ *
+ ****************************************************************************/
+
+int nxmutex_get_holder(FAR mutex_t *mutex);
+
 /****************************************************************************
  * Name: nxmutex_is_locked
  *
@@ -191,6 +206,34 @@ int nxmutex_lock(FAR mutex_t *mutex);
 
 int nxmutex_trylock(FAR mutex_t *mutex);
 
+/****************************************************************************
+ * Name: nxmutex_clocklock
+ *
+ * Description:
+ *   This function attempts to lock the mutex referenced by 'mutex'.  If the
+ *   mutex value is (<=) zero, then the calling task will not return until it
+ *   successfully acquires the lock or timed out
+ *
+ * Input Parameters:
+ *   mutex   - Mutex object
+ *   clockid - The clock to be used as the time base
+ *   abstime - The absolute time when the mutex lock timed out
+ *
+ * Returned Value:
+ *   OK        The mutex successfully acquires
+ *   EINVAL    The mutex argument does not refer to a valid mutex.  Or the
+ *             thread would have blocked, and the abstime parameter specified
+ *             a nanoseconds field value less than zero or greater than or
+ *             equal to 1000 million.
+ *   ETIMEDOUT The mutex could not be locked before the specified timeout
+ *             expired.
+ *   EDEADLK   A deadlock condition was detected.
+ *
+ ****************************************************************************/
+
+int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid,
+                      FAR const struct timespec *abstime);
+
 /****************************************************************************
  * Name: nxmutex_timedlock
  *
@@ -349,6 +392,21 @@ int nxrmutex_destroy(FAR rmutex_t *rmutex);
 
 bool nxrmutex_is_hold(FAR rmutex_t *rmutex);
 
+/****************************************************************************
+ * Name: nxrmutex_get_holder
+ *
+ * Description:
+ *   This function get the holder of the mutex referenced by 'mutex'.
+ *
+ * Parameters:
+ *   rmutex - Rmutex descriptor.
+ *
+ * Return Value:
+ *
+ ****************************************************************************/
+
+int nxrmutex_get_holder(FAR rmutex_t *rmutex);
+
 /****************************************************************************
  * Name: nxrmutex_is_locked
  *
@@ -411,6 +469,34 @@ int nxrmutex_lock(FAR rmutex_t *rmutex);
 
 int nxrmutex_trylock(FAR rmutex_t *rmutex);
 
+/****************************************************************************
+ * Name: nxrmutex_clocklock
+ *
+ * Description:
+ *   This function attempts to lock the mutex referenced by 'mutex'.  If the
+ *   mutex value is (<=) zero, then the calling task will not return until it
+ *   successfully acquires the lock or timed out
+ *
+ * Input Parameters:
+ *   rmutex  - Rmutex object
+ *   clockid - The clock to be used as the time base
+ *   abstime - The absolute time when the mutex lock timed out
+ *
+ * Returned Value:
+ *   OK        The mutex successfully acquires
+ *   EINVAL    The mutex argument does not refer to a valid mutex.  Or the
+ *             thread would have blocked, and the abstime parameter specified
+ *             a nanoseconds field value less than zero or greater than or
+ *             equal to 1000 million.
+ *   ETIMEDOUT The mutex could not be locked before the specified timeout
+ *             expired.
+ *   EDEADLK   A deadlock condition was detected.
+ *
+ ****************************************************************************/
+
+int nxrmutex_clocklock(FAR rmutex_t *rmutex, clockid_t clockid,
+                       FAR const struct timespec *abstime);
+
 /****************************************************************************
  * Name: nxrmutex_timedlock
  *
diff --git a/libs/libc/misc/lib_mutex.c b/libs/libc/misc/lib_mutex.c
index 379c812d06..6c2aac6cf4 100644
--- a/libs/libc/misc/lib_mutex.c
+++ b/libs/libc/misc/lib_mutex.c
@@ -149,6 +149,24 @@ bool nxmutex_is_hold(FAR mutex_t *mutex)
   return mutex->holder == _SCHED_GETTID();
 }
 
+/****************************************************************************
+ * Name: nxmutex_get_holder
+ *
+ * Description:
+ *   This function get the holder of the mutex referenced by 'mutex'.
+ *
+ * Parameters:
+ *   mutex - mutex descriptor.
+ *
+ * Return Value:
+ *
+ ****************************************************************************/
+
+int nxmutex_get_holder(FAR mutex_t *mutex)
+{
+  return mutex->holder;
+}
+
 /****************************************************************************
  * Name: nxmutex_is_locked
  *
@@ -252,16 +270,17 @@ int nxmutex_trylock(FAR mutex_t *mutex)
 }
 
 /****************************************************************************
- * Name: nxmutex_timedlock
+ * Name: nxmutex_clocklock
  *
  * Description:
- *   This function attempts to lock the mutex .  If the mutex value
- *   is (<=) zero,then the calling task will not return until it
+ *   This function attempts to lock the mutex referenced by 'mutex'.  If the
+ *   mutex value is (<=) zero, then the calling task will not return until it
  *   successfully acquires the lock or timed out
  *
  * Input Parameters:
  *   mutex   - Mutex object
- *   timeout - The time when mutex lock timed out
+ *   clockid - The clock to be used as the time base
+ *   abstime - The absolute time when the mutex lock timed out
  *
  * Returned Value:
  *   OK        The mutex successfully acquires
@@ -275,22 +294,16 @@ int nxmutex_trylock(FAR mutex_t *mutex)
  *
  ****************************************************************************/
 
-int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout)
+int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid,
+                      FAR const struct timespec *abstime)
 {
   int ret;
-  struct timespec now;
-  struct timespec delay;
-  struct timespec rqtp;
-
-  clock_gettime(CLOCK_MONOTONIC, &now);
-  clock_ticks2time(MSEC2TICK(timeout), &delay);
-  clock_timespec_add(&now, &delay, &rqtp);
 
   /* Wait until we get the lock or until the timeout expires */
 
   do
     {
-      ret = nxsem_clockwait(&mutex->sem, CLOCK_MONOTONIC, &rqtp);
+      ret = nxsem_clockwait(&mutex->sem, clockid, abstime);
     }
   while (ret == -EINTR || ret == -ECANCELED);
 
@@ -302,6 +315,45 @@ int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int 
timeout)
   return ret;
 }
 
+/****************************************************************************
+ * Name: nxmutex_timedlock
+ *
+ * Description:
+ *   This function attempts to lock the mutex .  If the mutex value
+ *   is (<=) zero,then the calling task will not return until it
+ *   successfully acquires the lock or timed out
+ *
+ * Input Parameters:
+ *   mutex   - Mutex object
+ *   timeout - The time when mutex lock timed out
+ *
+ * Returned Value:
+ *   OK        The mutex successfully acquires
+ *   EINVAL    The mutex argument does not refer to a valid mutex.  Or the
+ *             thread would have blocked, and the abstime parameter specified
+ *             a nanoseconds field value less than zero or greater than or
+ *             equal to 1000 million.
+ *   ETIMEDOUT The mutex could not be locked before the specified timeout
+ *             expired.
+ *   EDEADLK   A deadlock condition was detected.
+ *
+ ****************************************************************************/
+
+int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout)
+{
+  struct timespec now;
+  struct timespec delay;
+  struct timespec rqtp;
+
+  clock_gettime(CLOCK_MONOTONIC, &now);
+  clock_ticks2time(MSEC2TICK(timeout), &delay);
+  clock_timespec_add(&now, &delay, &rqtp);
+
+  /* Wait until we get the lock or until the timeout expires */
+
+  return nxmutex_clocklock(mutex, CLOCK_MONOTONIC, &rqtp);
+}
+
 /****************************************************************************
  * Name: nxmutex_unlock
  *
@@ -494,6 +546,24 @@ bool nxrmutex_is_hold(FAR rmutex_t *rmutex)
   return nxmutex_is_hold(&rmutex->mutex);
 }
 
+/****************************************************************************
+ * Name: nxrmutex_get_holder
+ *
+ * Description:
+ *   This function get the holder of the mutex referenced by 'mutex'.
+ *
+ * Parameters:
+ *   rmutex - Rmutex descriptor.
+ *
+ * Return Value:
+ *
+ ****************************************************************************/
+
+int nxrmutex_get_holder(FAR rmutex_t *rmutex)
+{
+  return nxmutex_get_holder(&rmutex->mutex);
+}
+
 /****************************************************************************
  * Name: nxrmutex_is_locked
  *
@@ -591,6 +661,50 @@ int nxrmutex_trylock(FAR rmutex_t *rmutex)
   return ret;
 }
 
+/****************************************************************************
+ * Name: nxrmutex_clocklock
+ *
+ * Description:
+ *   This function attempts to lock the mutex referenced by 'mutex'.  If the
+ *   mutex value is (<=) zero, then the calling task will not return until it
+ *   successfully acquires the lock or timed out
+ *
+ * Input Parameters:
+ *   rmutex  - Rmutex object
+ *   clockid - The clock to be used as the time base
+ *   abstime - The absolute time when the mutex lock timed out
+ *
+ * Returned Value:
+ *   OK        The mutex successfully acquires
+ *   EINVAL    The mutex argument does not refer to a valid mutex.  Or the
+ *             thread would have blocked, and the abstime parameter specified
+ *             a nanoseconds field value less than zero or greater than or
+ *             equal to 1000 million.
+ *   ETIMEDOUT The mutex could not be locked before the specified timeout
+ *             expired.
+ *   EDEADLK   A deadlock condition was detected.
+ *
+ ****************************************************************************/
+
+int nxrmutex_clocklock(FAR rmutex_t *rmutex, clockid_t clockid,
+                       FAR const struct timespec *abstime)
+{
+  int ret = OK;
+
+  if (!nxrmutex_is_hold(rmutex))
+    {
+      ret = nxmutex_clocklock(&rmutex->mutex, clockid, abstime);
+    }
+
+  if (ret >= 0)
+    {
+      DEBUGASSERT(rmutex->count < UINT_MAX);
+      ++rmutex->count;
+    }
+
+  return ret;
+}
+
 /****************************************************************************
  * Name: nxrmutex_timedlock
  *

Reply via email to