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/30 11:43:55 UTC

[incubator-nuttx] branch master updated: use rmutex inside of all repeated implementation

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 b88a8cf39f use rmutex inside of all repeated implementation
b88a8cf39f is described below

commit b88a8cf39ff1019ad787c4316b22ce29c7daa2dc
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Sun May 29 23:59:14 2022 +0800

    use rmutex inside of all repeated implementation
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 drivers/1wire/1wire.c              | 108 +-------------------------
 drivers/1wire/1wire_internal.h     |  14 +---
 drivers/1wire/1wire_read.c         |   4 +-
 drivers/1wire/1wire_write.c        |   4 +-
 drivers/1wire/1wire_writeread.c    |   4 +-
 drivers/1wire/ds28e17.c            |  16 ++--
 drivers/clk/clk.c                  |   2 +-
 drivers/clk/clk_rpmsg.c            |   2 +-
 drivers/power/pm.h                 |   2 +-
 drivers/power/regulator_rpmsg.c    |   2 +-
 drivers/rptun/rptun.c              |  61 ++-------------
 drivers/syslog/syslog_device.c     |  79 +++----------------
 drivers/usbhost/usbhost_max3421e.c |  80 +++-----------------
 fs/aio/aio_initialize.c            |  53 ++-----------
 fs/inode/fs_inode.c                |  74 +-----------------
 fs/spiffs/src/spiffs.h             |  17 +----
 fs/spiffs/src/spiffs_vfs.c         |  77 +------------------
 fs/tmpfs/fs_tmpfs.c                | 151 ++++++-------------------------------
 fs/tmpfs/fs_tmpfs.h                |  23 ++----
 include/nuttx/fs/fs.h              |   5 +-
 include/nuttx/mutex.h              |  70 ++++++++++++++---
 libs/libc/modlib/modlib_registry.c |  73 +-----------------
 libs/libc/netdb/lib_dnsinit.c      |  47 ++----------
 libs/libc/stdio/lib_fclose.c       |   2 +-
 libs/libc/stdio/lib_libfilesem.c   |  58 +-------------
 libs/libc/stdio/lib_libstream.c    |   8 +-
 net/route/net_fileroute.c          | 146 +++++------------------------------
 27 files changed, 189 insertions(+), 993 deletions(-)

diff --git a/drivers/1wire/1wire.c b/drivers/1wire/1wire.c
index 43aee5c15b..f1fbfed9ff 100644
--- a/drivers/1wire/1wire.c
+++ b/drivers/1wire/1wire.c
@@ -103,32 +103,6 @@ static inline uint32_t onewire_leuint32(uint32_t x)
 }
 #endif
 
-/****************************************************************************
- * Name: onewire_sem_init
- *
- * Description:
- *
- ****************************************************************************/
-
-static inline void onewire_sem_init(FAR struct onewire_sem_s *sem)
-{
-  sem->holder = NO_HOLDER;
-  sem->count  = 0;
-  nxsem_init(&sem->sem, 0, 1);
-}
-
-/****************************************************************************
- * Name: onewire_sem_destroy
- *
- * Description:
- *
- ****************************************************************************/
-
-static inline void onewire_sem_destroy(FAR struct onewire_sem_s *sem)
-{
-  nxsem_destroy(&sem->sem);
-}
-
 /****************************************************************************
  * Name: onewire_pm_prepare
  *
@@ -211,80 +185,6 @@ static int onewire_pm_prepare(FAR struct pm_callback_s *cb, int domain,
  * Public Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: onewire_sem_wait
- *
- * Description:
- *   Take the exclusive access, waiting as necessary
- *
- ****************************************************************************/
-
-int onewire_sem_wait(FAR struct onewire_master_s *master)
-{
-  pid_t me;
-  int ret;
-
-  /* Do we already hold the semaphore? */
-
-  me = getpid();
-  if (me == master->devsem.holder)
-    {
-      /* Yes... just increment the count */
-
-      master->devsem.count++;
-      DEBUGASSERT(master->devsem.count > 0);
-    }
-
-  /* Take the semaphore (perhaps waiting) */
-
-  else
-    {
-      ret = nxsem_wait(&master->devsem.sem);
-      if (ret < 0)
-        {
-          return ret;
-        }
-
-      /* Now we hold the semaphore */
-
-      master->devsem.holder = me;
-      master->devsem.count  = 1;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: onewire_sem_post
- *
- * Description:
- *   Release the mutual exclusion semaphore
- *
- ****************************************************************************/
-
-void onewire_sem_post(FAR struct onewire_master_s *master)
-{
-  DEBUGASSERT(master->devsem.holder == getpid());
-
-  /* Is this our last count on the semaphore? */
-
-  if (master->devsem.count > 1)
-    {
-      /* No.. just decrement the count */
-
-      master->devsem.count--;
-    }
-
-  /* Yes.. then we can really release the semaphore */
-
-  else
-    {
-      master->devsem.holder = NO_HOLDER;
-      master->devsem.count  = 0;
-      nxsem_post(&master->devsem.sem);
-    }
-}
-
 /****************************************************************************
  * Name: onewire_reset_resume
  *
@@ -529,7 +429,7 @@ int onewire_search(FAR struct onewire_master_s *master,
 
   /* Make complete search on the bus mutal exclusive */
 
-  ret = onewire_sem_wait(master);
+  ret = nxrmutex_lock(&master->devlock);
   if (ret < 0)
     {
       return ret;
@@ -663,7 +563,7 @@ int onewire_search(FAR struct onewire_master_s *master,
     }
 
 unlock:
-  onewire_sem_post(master);
+  nxrmutex_unlock(&master->devlock);
   return (ret < 0) ? ret : nslaves_match;
 }
 
@@ -743,7 +643,7 @@ onewire_initialize(FAR struct onewire_dev_s *dev, int maxslaves)
   /* Initialize the device structure */
 
   master->dev = dev;
-  onewire_sem_init(&master->devsem);
+  nxrmutex_init(&master->devlock);
   master->nslaves = 0;
   master->maxslaves = maxslaves;
   master->insearch = false;
@@ -780,7 +680,7 @@ int onewire_uninitialize(FAR struct onewire_master_s *master)
 
   /* Release resources. This does not touch the underlying onewire_dev_s */
 
-  onewire_sem_destroy(&master->devsem);
+  nxrmutex_destroy(&master->devlock);
   kmm_free(master);
   return OK;
 }
diff --git a/drivers/1wire/1wire_internal.h b/drivers/1wire/1wire_internal.h
index 2465948121..0e7aad9e90 100644
--- a/drivers/1wire/1wire_internal.h
+++ b/drivers/1wire/1wire_internal.h
@@ -28,7 +28,7 @@
 #include <nuttx/config.h>
 
 #include <stdbool.h>
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 #include <nuttx/power/pm.h>
 
 /****************************************************************************
@@ -37,17 +37,10 @@
 
 struct onewire_dev_s;
 
-struct onewire_sem_s
-{
-  sem_t sem;
-  pid_t holder;                        /* The current holder of the semaphore */
-  int16_t count;                       /* Number of counts held */
-};
-
 struct onewire_master_s
 {
   FAR struct onewire_dev_s *dev;       /* 1-Wire lower half */
-  struct onewire_sem_s devsem;         /* Re-entrant semaphore */
+  rmutex_t devlock;                    /* Re-entrant lock */
   int nslaves;                         /* Number of 1-wire slaves */
   int maxslaves;                       /* Maximum number of 1-wire slaves */
   bool insearch;                       /* If we are in middle of 1-wire search */
@@ -72,9 +65,6 @@ bool onewire_valid_rom(uint64_t rom);
 
 /* Rest are from 1wire.c */
 
-int  onewire_sem_wait(FAR struct onewire_master_s *master);
-void onewire_sem_post(FAR struct onewire_master_s *master);
-
 int onewire_addslave(FAR struct onewire_master_s *master,
                      FAR struct onewire_slave_s *slave);
 int onewire_removeslave(FAR struct onewire_master_s *master,
diff --git a/drivers/1wire/1wire_read.c b/drivers/1wire/1wire_read.c
index d6903aadf4..b4f27c2d78 100644
--- a/drivers/1wire/1wire_read.c
+++ b/drivers/1wire/1wire_read.c
@@ -69,7 +69,7 @@ int onewire_read(FAR struct onewire_master_s *master,
       return -EAGAIN;
     }
 
-  ret = onewire_sem_wait(master);
+  ret = nxrmutex_lock(&master->devlock);
   if (ret < 0)
     {
       return ret;
@@ -86,6 +86,6 @@ int onewire_read(FAR struct onewire_master_s *master,
   ret = ONEWIRE_READ(master->dev, buffer, buflen);
 
 err_unlock:
-  onewire_sem_post(master);
+  nxrmutex_unlock(&master->devlock);
   return ret;
 }
diff --git a/drivers/1wire/1wire_write.c b/drivers/1wire/1wire_write.c
index 5e24a5cb1a..6b9edc0060 100644
--- a/drivers/1wire/1wire_write.c
+++ b/drivers/1wire/1wire_write.c
@@ -70,7 +70,7 @@ int onewire_write(FAR struct onewire_master_s *master,
       return -EAGAIN;
     }
 
-  ret = onewire_sem_wait(master);
+  ret = nxrmutex_lock(&master->devlock);
   if (ret < 0)
     {
       return ret;
@@ -87,6 +87,6 @@ int onewire_write(FAR struct onewire_master_s *master,
   ret = ONEWIRE_WRITE(master->dev, buffer, buflen);
 
 err_unlock:
-  onewire_sem_post(master);
+  nxrmutex_unlock(&master->devlock);
   return ret;
 }
diff --git a/drivers/1wire/1wire_writeread.c b/drivers/1wire/1wire_writeread.c
index d31914a918..9560b97d44 100644
--- a/drivers/1wire/1wire_writeread.c
+++ b/drivers/1wire/1wire_writeread.c
@@ -74,7 +74,7 @@ int onewire_writeread(FAR struct onewire_master_s *master,
       return -EAGAIN;
     }
 
-  ret = onewire_sem_wait(master);
+  ret = nxrmutex_lock(&master->devlock);
   if (ret < 0)
     {
       return ret;
@@ -97,6 +97,6 @@ int onewire_writeread(FAR struct onewire_master_s *master,
   ret = ONEWIRE_READ(master->dev, rbuffer, rbuflen);
 
 err_unlock:
-  onewire_sem_post(master);
+  nxrmutex_unlock(&master->devlock);
   return ret;
 }
diff --git a/drivers/1wire/ds28e17.c b/drivers/1wire/ds28e17.c
index ad7dc57757..a93a29f104 100644
--- a/drivers/1wire/ds28e17.c
+++ b/drivers/1wire/ds28e17.c
@@ -155,7 +155,7 @@ static inline int ds_i2c_sem_wait(FAR struct i2c_master_s *i2cdev)
   FAR struct ds_i2c_inst_s *inst = (FAR struct ds_i2c_inst_s *)i2cdev;
   FAR struct onewire_master_s *master = inst->master;
 
-  return onewire_sem_wait(master);
+  return nxrmutex_lock(&master->devlock);
 }
 
 /****************************************************************************
@@ -171,7 +171,7 @@ static inline void ds_i2c_sem_post(FAR struct i2c_master_s *i2cdev)
   FAR struct ds_i2c_inst_s *inst = (FAR struct ds_i2c_inst_s *)i2cdev;
   FAR struct onewire_master_s *master = inst->master;
 
-  onewire_sem_post(master);
+  nxrmutex_unlock(&master->devlock);
 }
 
 static int ds_error(uint8_t buf[])
@@ -917,7 +917,7 @@ FAR struct i2c_master_s *
 
   /* We need a recursive lock as this may be called from a search callback. */
 
-  ret = onewire_sem_wait(master);
+  ret = nxrmutex_lock(&master->devlock);
   if (ret < 0)
     {
       kmm_free(inst);
@@ -929,7 +929,7 @@ FAR struct i2c_master_s *
     {
       kmm_free(inst);
       i2cerr("ERROR: Failed to add slave\n");
-      onewire_sem_post(master);
+      nxrmutex_unlock(&master->devlock);
       return NULL;
     }
 
@@ -947,7 +947,7 @@ FAR struct i2c_master_s *
       ds28e17_selftest(inst);
     }
 
-  onewire_sem_post(master);
+  nxrmutex_unlock(&master->devlock);
   return (struct i2c_master_s *)inst;
 }
 
@@ -973,7 +973,7 @@ int ds28e17_lower_half_unregister(FAR struct ds28e17_dev_s *priv,
   FAR struct onewire_master_s *master = inst->master;
   int ret;
 
-  ret = onewire_sem_wait(master);
+  ret = nxrmutex_lock(&master->devlock);
   if (ret < 0)
     {
       return ret;
@@ -984,12 +984,12 @@ int ds28e17_lower_half_unregister(FAR struct ds28e17_dev_s *priv,
     {
       kmm_free(inst);
       i2cerr("ERROR: Failed to remove slave\n");
-      onewire_sem_post(master);
+      nxrmutex_unlock(&master->devlock);
       return ret;
     }
 
   kmm_free(inst);
-  onewire_sem_post(master);
+  nxrmutex_unlock(&master->devlock);
 
   return OK;
 }
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 512a09d20c..6d5ce529d3 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -45,7 +45,7 @@
  * Private Datas
  ****************************************************************************/
 
-static mutex_t g_clk_list_lock            = MUTEX_INITIALIZER;
+static mutex_t g_clk_list_lock            = NXMUTEX_INITIALIZER;
 
 static struct list_node g_clk_root_list
                             = LIST_INITIAL_VALUE(g_clk_root_list);
diff --git a/drivers/clk/clk_rpmsg.c b/drivers/clk/clk_rpmsg.c
index f96387ddb7..2d7ff00812 100644
--- a/drivers/clk/clk_rpmsg.c
+++ b/drivers/clk/clk_rpmsg.c
@@ -192,7 +192,7 @@ static int clk_rpmsg_set_phase(FAR struct clk_s *clk, int degrees);
  * Private Datas
  ****************************************************************************/
 
-static mutex_t g_clk_rpmsg_lock          = MUTEX_INITIALIZER;
+static mutex_t g_clk_rpmsg_lock          = NXMUTEX_INITIALIZER;
 static struct list_node g_clk_rpmsg_priv =
               LIST_INITIAL_VALUE(g_clk_rpmsg_priv);
 
diff --git a/drivers/power/pm.h b/drivers/power/pm.h
index c3cdb67595..1814f70ec7 100644
--- a/drivers/power/pm.h
+++ b/drivers/power/pm.h
@@ -29,7 +29,7 @@
 
 #include <queue.h>
 
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 #include <nuttx/clock.h>
 #include <nuttx/power/pm.h>
 #include <nuttx/wdog.h>
diff --git a/drivers/power/regulator_rpmsg.c b/drivers/power/regulator_rpmsg.c
index 77e86f40b0..689e999201 100644
--- a/drivers/power/regulator_rpmsg.c
+++ b/drivers/power/regulator_rpmsg.c
@@ -153,7 +153,7 @@ static int regulator_rpmsg_is_enabled(FAR struct regulator_dev_s *rdev);
  * Private Data
  ****************************************************************************/
 
-static mutex_t g_regulator_rpmsg_lock          =  MUTEX_INITIALIZER;
+static mutex_t g_regulator_rpmsg_lock          =  NXMUTEX_INITIALIZER;
 static struct list_node g_regulator_rpmsg_priv =
           LIST_INITIAL_VALUE(g_regulator_rpmsg_priv);
 
diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c
index 3a6aae7773..11d277cf02 100644
--- a/drivers/rptun/rptun.c
+++ b/drivers/rptun/rptun.c
@@ -32,6 +32,7 @@
 #include <nuttx/board.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/kthread.h>
+#include <nuttx/mutex.h>
 #include <nuttx/semaphore.h>
 #include <nuttx/rptun/openamp.h>
 #include <nuttx/rptun/rptun.h>
@@ -53,8 +54,10 @@
 #  define ALIGN_UP(s, a)            (((s) + (a) - 1) & ~((a) - 1))
 #endif
 
+#define rptun_lock()                nxrmutex_lock(&g_rptunlock)
+#define rptun_unlock()              nxrmutex_unlock(&g_rptunlock)
+
 #define RPTUNIOC_NONE               0
-#define NO_HOLDER                   (INVALID_PROCESS_ID)
 
 #define RPTUN_OPS_START             0
 #define RPTUN_OPS_DUMP              1
@@ -197,9 +200,7 @@ static struct image_store_ops g_rptun_storeops =
 };
 #endif
 
-static sem_t        g_rptunlock = SEM_INITIALIZER(1);
-static pid_t        g_holder    = NO_HOLDER;
-static unsigned int g_count;
+static rmutex_t g_rptunlock = NXRMUTEX_INITIALIZER;
 
 static METAL_DECLARE_LIST(g_rptun_cb);
 static METAL_DECLARE_LIST(g_rptun_priv);
@@ -208,58 +209,6 @@ static METAL_DECLARE_LIST(g_rptun_priv);
  * Private Functions
  ****************************************************************************/
 
-static int rptun_lock(void)
-{
-  pid_t me = getpid();
-  int ret = OK;
-
-  /* Does this thread already hold the semaphore? */
-
-  if (g_holder == me)
-    {
-      /* Yes.. just increment the reference count */
-
-      g_count++;
-    }
-  else
-    {
-      /* No.. take the semaphore (perhaps waiting) */
-
-      ret = nxsem_wait_uninterruptible(&g_rptunlock);
-      if (ret >= 0)
-        {
-          /* Now this thread holds the semaphore */
-
-          g_holder = me;
-          g_count  = 1;
-        }
-    }
-
-  return ret;
-}
-
-static void rptun_unlock(void)
-{
-  DEBUGASSERT(g_holder == getpid() && g_count > 0);
-
-  /* If the count would go to zero, then release the semaphore */
-
-  if (g_count == 1)
-    {
-      /* We no longer hold the semaphore */
-
-      g_holder = NO_HOLDER;
-      g_count  = 0;
-      nxsem_post(&g_rptunlock);
-    }
-  else
-    {
-      /* We still hold the semaphore. Just decrement the count */
-
-      g_count--;
-    }
-}
-
 #ifdef CONFIG_RPTUN_PM
 static inline void rptun_pm_action(FAR struct rptun_priv_s *priv,
                                    bool stay)
diff --git a/drivers/syslog/syslog_device.c b/drivers/syslog/syslog_device.c
index 51d441c923..ea744232f5 100644
--- a/drivers/syslog/syslog_device.c
+++ b/drivers/syslog/syslog_device.c
@@ -38,7 +38,7 @@
 #include <nuttx/arch.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/fs/fs.h>
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 #include <nuttx/syslog/syslog.h>
 #include <nuttx/compiler.h>
 
@@ -54,10 +54,8 @@
  */
 
 #define SYSLOG_OFLAGS (O_WRONLY | O_CREAT | O_APPEND)
-
-/* An invalid thread ID */
-
-#define NO_HOLDER     (INVALID_PROCESS_ID)
+#define syslog_dev_takesem(s) nxrmutex_lock(&(s)->sl_lock)
+#define syslog_dev_givesem(s) nxrmutex_unlock(&(s)->sl_lock)
 
 /****************************************************************************
  * Private Types
@@ -83,8 +81,7 @@ struct syslog_dev_s
   uint8_t      sl_state;    /* See enum syslog_dev_state */
   uint8_t      sl_oflags;   /* Saved open mode (for re-open) */
   uint16_t     sl_mode;     /* Saved open flags (for re-open) */
-  sem_t        sl_sem;      /* Enforces mutually exclusive access */
-  pid_t        sl_holder;   /* PID of the thread that holds the semaphore */
+  rmutex_t     sl_lock;     /* Enforces mutually exclusive access */
   struct file  sl_file;     /* The syslog file structure */
   FAR char    *sl_devpath;  /* Full path to the character device */
 };
@@ -123,63 +120,6 @@ static const uint8_t g_syscrlf[2] =
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: syslog_dev_takesem
- ****************************************************************************/
-
-static inline int syslog_dev_takesem(FAR struct syslog_dev_s *syslog_dev)
-{
-  pid_t me = getpid();
-  int ret;
-
-  /* Does this thread already hold the semaphore?  That could happen if
-   * we were called recursively, i.e., if the logic kicked off by
-   * file_write() where to generate more debug output.  Return an
-   * error in that case.
-   */
-
-  if (syslog_dev->sl_holder == me)
-    {
-      /* Return an error (instead of deadlocking) */
-
-      return -EWOULDBLOCK;
-    }
-
-  /* Either the semaphore is available or is currently held by another
-   * thread.  Wait for it to become available.
-   */
-
-  ret = nxsem_wait(&syslog_dev->sl_sem);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* We hold the semaphore.  We can safely mark ourself as the holder
-   * of the semaphore.
-   */
-
-  syslog_dev->sl_holder = me;
-  return OK;
-}
-
-/****************************************************************************
- * Name: syslog_dev_givesem
- ****************************************************************************/
-
-static inline void syslog_dev_givesem(FAR struct syslog_dev_s *syslog_dev)
-{
-#ifdef CONFIG_DEBUG_ASSERTIONS
-  pid_t me = getpid();
-  DEBUGASSERT(syslog_dev->sl_holder == me);
-#endif
-
-  /* Relinquish the semaphore */
-
-  syslog_dev->sl_holder = NO_HOLDER;
-  nxsem_post(&syslog_dev->sl_sem);
-}
-
 /****************************************************************************
  * Name: syslog_dev_open
  *
@@ -272,9 +212,8 @@ static int syslog_dev_open(FAR struct syslog_dev_s *syslog_dev,
 
   /* The SYSLOG device is open and ready for writing. */
 
-  nxsem_init(&syslog_dev->sl_sem, 0, 1);
-  syslog_dev->sl_holder = NO_HOLDER;
-  syslog_dev->sl_state  = SYSLOG_OPENED;
+  nxrmutex_init(&syslog_dev->sl_lock);
+  syslog_dev->sl_state = SYSLOG_OPENED;
   return OK;
 }
 
@@ -303,7 +242,7 @@ static int syslog_dev_open(FAR struct syslog_dev_s *syslog_dev,
  *     close the device, and set it for later re-opening.
  *
  * NOTE: That the third case is different.  It applies only to the thread
- * that currently holds the sl_sem semaphore.  Other threads should wait.
+ * that currently holds the sl_lock.  Other threads should wait.
  * that is why that case is handled in syslog_semtake().
  *
  * Input Parameters:
@@ -352,7 +291,7 @@ static int syslog_dev_outputready(FAR struct syslog_dev_s *syslog_dev)
       if (syslog_dev->sl_state == SYSLOG_FAILURE)
         {
           file_close(&syslog_dev->sl_file);
-          nxsem_destroy(&syslog_dev->sl_sem);
+          nxrmutex_destroy(&syslog_dev->sl_lock);
 
           syslog_dev->sl_state = SYSLOG_REOPEN;
         }
@@ -795,7 +734,7 @@ void syslog_dev_uninitialize(FAR struct syslog_channel_s *channel)
       syslog_dev->sl_state == SYSLOG_FAILURE)
     {
       file_close(&syslog_dev->sl_file);
-      nxsem_destroy(&syslog_dev->sl_sem);
+      nxrmutex_destroy(&syslog_dev->sl_lock);
     }
 
   /* Set the device in UNINITIALIZED state. */
diff --git a/drivers/usbhost/usbhost_max3421e.c b/drivers/usbhost/usbhost_max3421e.c
index cf72d6078f..b3ef780b9c 100644
--- a/drivers/usbhost/usbhost_max3421e.c
+++ b/drivers/usbhost/usbhost_max3421e.c
@@ -45,6 +45,7 @@
 #include <nuttx/kmalloc.h>
 #include <nuttx/clock.h>
 #include <nuttx/signal.h>
+#include <nuttx/mutex.h>
 #include <nuttx/semaphore.h>
 #include <nuttx/wqueue.h>
 #include <nuttx/spi/spi.h>
@@ -130,6 +131,11 @@
 
 #define TRENTRY(id,fmt1,string) {string}
 
+/* Lock *********************************************************************/
+
+#define max3421e_take_exclsem(s) nxrmutex_lock(&(s)->lock)
+#define max3421e_give_exclsem(s) nxrmutex_unlock(&(s)->lock);
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -211,11 +217,9 @@ struct max3421e_usbhost_s
   uint8_t           xfrtype;   /* See enum mx3421e_hxfrdn_e */
   uint8_t           inflight;  /* Number of Tx bytes "in-flight" (<= 128) */
   uint8_t           result;    /* The result of the transfer */
-  uint8_t           exclcount; /* Number of nested exclem locks */
   uint16_t          buflen;    /* Buffer length (at start of transfer) */
   uint16_t          xfrd;      /* Bytes transferred (at end of transfer) */
-  pid_t             holder;    /* Current hold of the exclsem */
-  sem_t             exclsem;   /* Support mutually exclusive access */
+  rmutex_t          lock;      /* Support mutually exclusive access */
   sem_t             pscsem;    /* Semaphore to wait for a port event */
   sem_t             waitsem;   /* Channel wait semaphore */
   FAR uint8_t      *buffer;    /* Transfer buffer pointer */
@@ -1126,71 +1130,6 @@ static int max3421e_takesem(FAR sem_t *sem)
   return nxsem_wait_uninterruptible(sem);
 }
 
-/****************************************************************************
- * Name: max3421e_take_exclsem and max3421e_give_exclsem
- *
- * Description:
- *   Implements a mutual re-entrant mutex for exclsem.
- *
- ****************************************************************************/
-
-static int max3421e_take_exclsem(FAR struct max3421e_usbhost_s *priv)
-{
-  pid_t me = getpid();
-  int ret = OK;
-
-  /* Does this thread already hold the mutual exclusion mutex? */
-
-  if (priv->holder == me)
-    {
-      /* Yes.. just increment the count */
-
-      DEBUGASSERT(priv->exclcount < UINT8_MAX);
-      priv->exclcount++;
-    }
-  else
-    {
-      /* No.. take the semaphore */
-
-      ret = max3421e_takesem(&priv->exclsem);
-      if (ret >= 0)
-        {
-          /* Now this thread is the holder with a count of one */
-
-          priv->holder = me;
-          priv->exclcount = 1;
-        }
-    }
-
-  return ret;
-}
-
-static void max3421e_give_exclsem(FAR struct max3421e_usbhost_s *priv)
-{
-#ifdef CONFIG_DEBUG_ASSERTIONS
-  pid_t me = getpid();
-
-  DEBUGASSERT(priv->holder == me);
-#endif
-
-  /* Is the lock nested? */
-
-  if (priv->exclcount > 0)
-    {
-      /* Yes.. just decrement the count */
-
-      priv->exclcount--;
-    }
-  else
-    {
-      /* No.. give the semaphore */
-
-      priv->holder    = NO_HOLDER;
-      priv->exclcount = 0;
-      max3421e_givesem(&priv->exclsem);
-    }
-}
-
 /****************************************************************************
  * Name: max3421e_getle16
  *
@@ -4784,9 +4723,12 @@ static inline int max3421e_sw_initialize(FAR struct max3421e_usbhost_s *priv,
   /* Initialize semaphores */
 
   nxsem_init(&priv->pscsem,  0, 0);
-  nxsem_init(&priv->exclsem, 0, 1);
   nxsem_init(&priv->waitsem,  0, 0);
 
+  /* Initialize lock */
+
+  nxrmutex_init(&priv->lock);
+
   /* The pscsem and waitsem semaphores are used for signaling and, hence,
    * should not have
    * priority inheritance enabled.
diff --git a/fs/aio/aio_initialize.c b/fs/aio/aio_initialize.c
index 968065a513..ae7b7935ad 100644
--- a/fs/aio/aio_initialize.c
+++ b/fs/aio/aio_initialize.c
@@ -29,7 +29,7 @@
 #include <queue.h>
 
 #include <nuttx/sched.h>
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 
 #include "aio/aio.h"
 
@@ -52,14 +52,12 @@ static dq_queue_t g_aioc_free;
 static sem_t g_aioc_freesem = NXSEM_INITIALIZER(CONFIG_FS_NAIOC,
                                                 PRIOINHERIT_FLAGS_DISABLE);
 
-/* This binary semaphore supports exclusive access to the list of pending
+/* This binary lock supports exclusive access to the list of pending
  * asynchronous I/O.  g_aio_holder and a_aio_count support the reentrant
  * lock.
  */
 
-static sem_t g_aio_exclsem = SEM_INITIALIZER(1);
-static pid_t g_aio_holder = INVALID_PROCESS_ID;
-static uint16_t g_aio_count;
+static rmutex_t g_aio_lock = NXRMUTEX_INITIALIZER;
 
 /****************************************************************************
  * Public Data
@@ -119,53 +117,12 @@ void aio_initialize(void)
 
 int aio_lock(void)
 {
-  pid_t me = getpid();
-  int ret = OK;
-
-  /* Does this thread already hold the semaphore? */
-
-  if (g_aio_holder == me)
-    {
-      /* Yes, just increment the counts held */
-
-      DEBUGASSERT(g_aio_count > 0 && g_aio_count < UINT16_MAX);
-      g_aio_count++;
-    }
-  else
-    {
-      ret = nxsem_wait_uninterruptible(&g_aio_exclsem);
-      if (ret >= 0)
-        {
-          /* And mark it as ours */
-
-          g_aio_holder = me;
-          g_aio_count  = 1;
-        }
-    }
-
-  return ret;
+  return nxrmutex_lock(&g_aio_lock);
 }
 
 void aio_unlock(void)
 {
-  DEBUGASSERT(g_aio_holder == getpid() && g_aio_count > 0);
-
-  /* Would decrementing the count release the lock? */
-
-  if (g_aio_count <= 1)
-    {
-      /* Yes.. that we will no longer be the holder */
-
-      g_aio_holder = INVALID_PROCESS_ID;
-      g_aio_count  = 0;
-      nxsem_post(&g_aio_exclsem);
-    }
-  else
-    {
-      /* Otherwise, just decrement the count.  We still hold the lock. */
-
-      g_aio_count--;
-    }
+  nxrmutex_unlock(&g_aio_lock);
 }
 
 /****************************************************************************
diff --git a/fs/inode/fs_inode.c b/fs/inode/fs_inode.c
index a5aa0dbbad..8ed88badd1 100644
--- a/fs/inode/fs_inode.c
+++ b/fs/inode/fs_inode.c
@@ -29,7 +29,7 @@
 #include <errno.h>
 
 #include <nuttx/fs/fs.h>
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 
 #include "inode/inode.h"
 
@@ -37,35 +37,15 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define NO_HOLDER (INVALID_PROCESS_ID)
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
-/* Implements a re-entrant mutex for inode access.  This must be re-entrant
- * because there can be cycles.  For example, it may be necessary to destroy
- * a block driver inode on umount() after a removable block device has been
- * removed.  In that case umount() holds the inode semaphore, but the block
- * driver may callback to unregister_blockdriver() after the un-mount,
- * requiring the semaphore again.
- */
-
-struct inode_sem_s
-{
-  sem_t   sem;     /* The semaphore */
-  pid_t   holder;  /* The current holder of the semaphore */
-  int16_t count;   /* Number of counts held */
-};
-
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
-static struct inode_sem_s g_inode_sem =
-{
-  SEM_INITIALIZER(1), NO_HOLDER, 0
-};
+static rmutex_t g_inode_lock = NXRMUTEX_INITIALIZER;
 
 /****************************************************************************
  * Public Functions
@@ -97,35 +77,7 @@ void inode_initialize(void)
 
 int inode_semtake(void)
 {
-  pid_t me;
-  int ret = OK;
-
-  /* Do we already hold the semaphore? */
-
-  me = getpid();
-  if (me == g_inode_sem.holder)
-    {
-      /* Yes... just increment the count */
-
-      g_inode_sem.count++;
-      DEBUGASSERT(g_inode_sem.count > 0);
-    }
-
-  /* Take the semaphore (perhaps waiting) */
-
-  else
-    {
-      ret = nxsem_wait_uninterruptible(&g_inode_sem.sem);
-      if (ret >= 0)
-        {
-          /* No we hold the semaphore */
-
-          g_inode_sem.holder = me;
-          g_inode_sem.count  = 1;
-        }
-    }
-
-  return ret;
+  return nxrmutex_lock(&g_inode_lock);
 }
 
 /****************************************************************************
@@ -138,23 +90,5 @@ int inode_semtake(void)
 
 void inode_semgive(void)
 {
-  DEBUGASSERT(g_inode_sem.holder == getpid());
-
-  /* Is this our last count on the semaphore? */
-
-  if (g_inode_sem.count > 1)
-    {
-      /* No.. just decrement the count */
-
-      g_inode_sem.count--;
-    }
-
-  /* Yes.. then we can really release the semaphore */
-
-  else
-    {
-      g_inode_sem.holder = NO_HOLDER;
-      g_inode_sem.count  = 0;
-      nxsem_post(&g_inode_sem.sem);
-    }
+  DEBUGVERIFY(nxrmutex_unlock(&g_inode_lock));
 }
diff --git a/fs/spiffs/src/spiffs.h b/fs/spiffs/src/spiffs.h
index bf4b832c70..f011511868 100644
--- a/fs/spiffs/src/spiffs.h
+++ b/fs/spiffs/src/spiffs.h
@@ -57,7 +57,7 @@ extern "C"
 #include <sys/mount.h>
 #include <queue.h>
 
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 #include <nuttx/mtd/mtd.h>
 
 /****************************************************************************
@@ -68,10 +68,6 @@ extern "C"
 
 #define SFO_FLAG_UNLINKED               (1 << 0)
 
-/* Re-entrant semaphore definitions */
-
-#define SPIFFS_NO_HOLDER                (INVALID_PROCESS_ID)
-
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -110,15 +106,6 @@ typedef int32_t(*spiffs_write_t)(uint32_t addr,
 
 typedef int32_t(*spiffs_erase_t)(uint32_t addr, uint32_t size);
 
-/* Re-entrant semaphore */
-
-struct spiffs_sem_s
-{
-  sem_t    sem;                     /* The actual semaphore */
-  pid_t    holder;                  /* Current older (-1 if not held) */
-  uint16_t count;                   /* Number of counts held */
-};
-
 /* spiffs SPI configuration struct */
 
 /* This structure represents the current state of an SPIFFS volume */
@@ -128,7 +115,7 @@ struct spiffs_file_s;               /* Forward reference */
 struct spiffs_s
 {
   struct mtd_geometry_s geo;        /* FLASH geometry */
-  struct spiffs_sem_s exclsem;      /* Supports mutually exclusive access */
+  rmutex_t lock;                    /* Supports mutually exclusive access */
   dq_queue_t objq;                  /* A doubly linked list of open file objects */
   FAR struct mtd_dev_s *mtd;        /* The contained MTD interface */
   FAR uint8_t *lu_work;             /* Primary work buffer, size of a logical page */
diff --git a/fs/spiffs/src/spiffs_vfs.c b/fs/spiffs/src/spiffs_vfs.c
index 1945ef2f90..9bc47dd536 100644
--- a/fs/spiffs/src/spiffs_vfs.c
+++ b/fs/spiffs/src/spiffs_vfs.c
@@ -72,18 +72,13 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define spiffs_lock_volume(fs)       (spiffs_lock_reentrant(&fs->exclsem))
-#define spiffs_unlock_volume(fs)     (spiffs_unlock_reentrant(&fs->exclsem))
+#define spiffs_lock_volume(fs)       (nxrmutex_lock(&fs->lock))
+#define spiffs_unlock_volume(fs)     (nxrmutex_unlock(&fs->lock))
 
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
 
-/* SPIFFS helpers */
-
-static int  spiffs_lock_reentrant(FAR struct spiffs_sem_s *sem);
-static void spiffs_unlock_reentrant(FAR struct spiffs_sem_s *sem);
-
 /* File system operations */
 
 static int  spiffs_open(FAR struct file *filep, FAR const char *relpath,
@@ -175,70 +170,6 @@ static inline int spiffs_map_errno(int errcode)
   return errcode < SPIFFS_ERR_INTERNAL ? -EFTYPE : errcode;
 }
 
-/****************************************************************************
- * Name: spiffs_lock_reentrant
- ****************************************************************************/
-
-static int spiffs_lock_reentrant(FAR struct spiffs_sem_s *rsem)
-{
-  pid_t me;
-  int ret = OK;
-
-  /* Do we already hold the semaphore? */
-
-  me = getpid();
-  if (me == rsem->holder)
-    {
-      /* Yes... just increment the count */
-
-      rsem->count++;
-      DEBUGASSERT(rsem->count > 0);
-    }
-
-  /* Take the semaphore (perhaps waiting) */
-
-  else
-    {
-      ret = nxsem_wait_uninterruptible(&rsem->sem);
-      if (ret >= 0)
-        {
-          /* No we hold the semaphore */
-
-          rsem->holder = me;
-          rsem->count  = 1;
-        }
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: spiffs_unlock_reentrant
- ****************************************************************************/
-
-static void spiffs_unlock_reentrant(FAR struct spiffs_sem_s *rsem)
-{
-  DEBUGASSERT(rsem->holder == getpid());
-
-  /* Is this our last count on the semaphore? */
-
-  if (rsem->count > 1)
-    {
-      /* No.. just decrement the count */
-
-      rsem->count--;
-    }
-
-  /* Yes.. then we can really release the semaphore */
-
-  else
-    {
-      rsem->holder = SPIFFS_NO_HOLDER;
-      rsem->count  = 0;
-      nxsem_post(&rsem->sem);
-    }
-}
-
 /****************************************************************************
  * Name: spiffs_consistency_check
  ****************************************************************************/
@@ -1505,7 +1436,7 @@ static int spiffs_bind(FAR struct inode *mtdinode, FAR const void *data,
   fs->lu_work   = &work[SPIFFS_GEO_PAGE_SIZE(fs)];
   fs->mtd_work  = &work[2 * SPIFFS_GEO_PAGE_SIZE(fs)];
 
-  nxsem_init(&fs->exclsem.sem, 0, 1);
+  nxrmutex_init(&fs->lock);
 
   /* Check the file system */
 
@@ -1608,7 +1539,7 @@ static int spiffs_unbind(FAR void *handle, FAR struct inode **mtdinode,
 
   /* Free the volume memory (note that the semaphore is now stale!) */
 
-  nxsem_destroy(&fs->exclsem.sem);
+  nxrmutex_destroy(&fs->lock);
   kmm_free(fs);
   ret = OK;
 
diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c
index d15dab86fd..8165a19833 100644
--- a/fs/tmpfs/fs_tmpfs.c
+++ b/fs/tmpfs/fs_tmpfs.c
@@ -55,14 +55,22 @@
 #  warning CONFIG_FS_TMPFS_FILE_FREEGUARD needs to be > ALLOCGUARD
 #endif
 
+#define tmpfs_lock(fs) \
+           nxrmutex_lock(&fs->tfs_lock)
+#define tmpfs_lock_object(to) \
+           nxrmutex_lock(&to->to_lock)
 #define tmpfs_lock_file(tfo) \
-           (tmpfs_lock_object((FAR struct tmpfs_object_s *)tfo))
+           nxrmutex_lock(&tfo->tfo_lock)
 #define tmpfs_lock_directory(tdo) \
-           (tmpfs_lock_object((FAR struct tmpfs_object_s *)tdo))
+           nxrmutex_lock(&tdo->tdo_lock)
+#define tmpfs_unlock(fs) \
+           nxrmutex_unlock(&fs->tfs_lock)
+#define tmpfs_unlock_object(to) \
+           nxrmutex_unlock(&to->to_lock)
 #define tmpfs_unlock_file(tfo) \
-           (tmpfs_unlock_object((FAR struct tmpfs_object_s *)tfo))
+           nxrmutex_unlock(&tfo->tfo_lock)
 #define tmpfs_unlock_directory(tdo) \
-           (tmpfs_unlock_object((FAR struct tmpfs_object_s *)tdo))
+           nxrmutex_unlock(&tdo->tdo_lock)
 
 /****************************************************************************
  * Private Function Prototypes
@@ -70,12 +78,6 @@
 
 /* TMPFS helpers */
 
-static int  tmpfs_lock_reentrant(FAR struct tmpfs_sem_s *sem);
-static int  tmpfs_lock(FAR struct tmpfs_s *fs);
-static void tmpfs_unlock_reentrant(FAR struct tmpfs_sem_s *sem);
-static void tmpfs_unlock(FAR struct tmpfs_s *fs);
-static int  tmpfs_lock_object(FAR struct tmpfs_object_s *to);
-static void tmpfs_unlock_object(FAR struct tmpfs_object_s *to);
 static int  tmpfs_realloc_directory(FAR struct tmpfs_directory_s *tdo,
               unsigned int nentries);
 static int  tmpfs_realloc_file(FAR struct tmpfs_file_s *tfo,
@@ -193,106 +195,6 @@ const struct mountpt_operations tmpfs_operations =
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: tmpfs_lock_reentrant
- ****************************************************************************/
-
-static int tmpfs_lock_reentrant(FAR struct tmpfs_sem_s *sem)
-{
-  pid_t me;
-  int ret = OK;
-
-  /* Do we already hold the semaphore? */
-
-  me = getpid();
-  if (me == sem->ts_holder)
-    {
-      /* Yes... just increment the count */
-
-      sem->ts_count++;
-      DEBUGASSERT(sem->ts_count > 0);
-    }
-
-  /* Take the semaphore (perhaps waiting) */
-
-  else
-    {
-      ret = nxsem_wait_uninterruptible(&sem->ts_sem);
-      if (ret >= 0)
-        {
-          /* No we hold the semaphore */
-
-          sem->ts_holder = me;
-          sem->ts_count  = 1;
-        }
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: tmpfs_lock
- ****************************************************************************/
-
-static int tmpfs_lock(FAR struct tmpfs_s *fs)
-{
-  return tmpfs_lock_reentrant(&fs->tfs_exclsem);
-}
-
-/****************************************************************************
- * Name: tmpfs_lock_object
- ****************************************************************************/
-
-static int tmpfs_lock_object(FAR struct tmpfs_object_s *to)
-{
-  return tmpfs_lock_reentrant(&to->to_exclsem);
-}
-
-/****************************************************************************
- * Name: tmpfs_unlock_reentrant
- ****************************************************************************/
-
-static void tmpfs_unlock_reentrant(FAR struct tmpfs_sem_s *sem)
-{
-  DEBUGASSERT(sem->ts_holder == getpid());
-
-  /* Is this our last count on the semaphore? */
-
-  if (sem->ts_count > 1)
-    {
-      /* No.. just decrement the count */
-
-      sem->ts_count--;
-    }
-
-  /* Yes.. then we can really release the semaphore */
-
-  else
-    {
-      sem->ts_holder = TMPFS_NO_HOLDER;
-      sem->ts_count  = 0;
-      nxsem_post(&sem->ts_sem);
-    }
-}
-
-/****************************************************************************
- * Name: tmpfs_unlock
- ****************************************************************************/
-
-static void tmpfs_unlock(FAR struct tmpfs_s *fs)
-{
-  tmpfs_unlock_reentrant(&fs->tfs_exclsem);
-}
-
-/****************************************************************************
- * Name: tmpfs_unlock_object
- ****************************************************************************/
-
-static void tmpfs_unlock_object(FAR struct tmpfs_object_s *to)
-{
-  tmpfs_unlock_reentrant(&to->to_exclsem);
-}
-
 /****************************************************************************
  * Name: tmpfs_realloc_directory
  ****************************************************************************/
@@ -435,7 +337,7 @@ static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo)
 
   if (tfo->tfo_refs == 1 && (tfo->tfo_flags & TFO_FLAG_UNLINKED) != 0)
     {
-      nxsem_destroy(&tfo->tfo_exclsem.ts_sem);
+      nxrmutex_destroy(&tfo->tfo_lock);
       kmm_free(tfo->tfo_data);
       kmm_free(tfo);
     }
@@ -612,9 +514,8 @@ static FAR struct tmpfs_file_s *tmpfs_alloc_file(void)
   tfo->tfo_size  = 0;
   tfo->tfo_data  = NULL;
 
-  tfo->tfo_exclsem.ts_holder = getpid();
-  tfo->tfo_exclsem.ts_count  = 1;
-  nxsem_init(&tfo->tfo_exclsem.ts_sem, 0, 0);
+  nxrmutex_init(&tfo->tfo_lock);
+  tmpfs_lock_file(tfo);
 
   return tfo;
 }
@@ -727,7 +628,7 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs,
   /* Error exits */
 
 errout_with_file:
-  nxsem_destroy(&newtfo->tfo_exclsem.ts_sem);
+  nxrmutex_destroy(&newtfo->tfo_lock);
   kmm_free(newtfo);
 
 errout_with_parent:
@@ -760,9 +661,7 @@ static FAR struct tmpfs_directory_s *tmpfs_alloc_directory(void)
   tdo->tdo_nentries = 0;
   tdo->tdo_entry    = NULL;
 
-  tdo->tdo_exclsem.ts_holder = TMPFS_NO_HOLDER;
-  tdo->tdo_exclsem.ts_count  = 0;
-  nxsem_init(&tdo->tdo_exclsem.ts_sem, 0, 1);
+  nxrmutex_init(&tdo->tdo_lock);
 
   return tdo;
 }
@@ -880,7 +779,7 @@ static int tmpfs_create_directory(FAR struct tmpfs_s *fs,
   /* Error exits */
 
 errout_with_directory:
-  nxsem_destroy(&newtdo->tdo_exclsem.ts_sem);
+  nxrmutex_destroy(&newtdo->tdo_lock);
   kmm_free(newtdo);
 
 errout_with_parent:
@@ -1251,7 +1150,7 @@ static int tmpfs_free_callout(FAR struct tmpfs_directory_s *tdo,
 
   /* Free the object now */
 
-  nxsem_destroy(&to->to_exclsem.ts_sem);
+  nxrmutex_destroy(&to->to_lock);
   kmm_free(to);
   return TMPFS_DELETED;
 }
@@ -2107,9 +2006,7 @@ static int tmpfs_bind(FAR struct inode *blkdriver, FAR const void *data,
 
   /* Initialize the file system state */
 
-  fs->tfs_exclsem.ts_holder = TMPFS_NO_HOLDER;
-  fs->tfs_exclsem.ts_count  = 0;
-  nxsem_init(&fs->tfs_exclsem.ts_sem, 0, 1);
+  nxrmutex_init(&fs->tfs_lock);
 
   /* Return the new file system handle */
 
@@ -2147,11 +2044,11 @@ static int tmpfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
 
   /* Now we can destroy the root file system and the file system itself. */
 
-  nxsem_destroy(&tdo->tdo_exclsem.ts_sem);
+  nxrmutex_destroy(&tdo->tdo_lock);
   kmm_free(tdo->tdo_entry);
   kmm_free(tdo);
 
-  nxsem_destroy(&fs->tfs_exclsem.ts_sem);
+  nxrmutex_destroy(&fs->tfs_lock);
   kmm_free(fs);
   return ret;
 }
@@ -2314,7 +2211,7 @@ static int tmpfs_unlink(FAR struct inode *mountpt, FAR const char *relpath)
 
   else
     {
-      nxsem_destroy(&tfo->tfo_exclsem.ts_sem);
+      nxrmutex_destroy(&tfo->tfo_lock);
       kmm_free(tfo->tfo_data);
       kmm_free(tfo);
     }
@@ -2456,7 +2353,7 @@ static int tmpfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath)
 
   /* Free the directory object */
 
-  nxsem_destroy(&tdo->tdo_exclsem.ts_sem);
+  nxrmutex_destroy(&tdo->tdo_lock);
   kmm_free(tdo->tdo_entry);
   kmm_free(tdo);
 
diff --git a/fs/tmpfs/fs_tmpfs.h b/fs/tmpfs/fs_tmpfs.h
index 27c1eb78ad..0a14e6f58c 100644
--- a/fs/tmpfs/fs_tmpfs.h
+++ b/fs/tmpfs/fs_tmpfs.h
@@ -30,16 +30,12 @@
 #include <stdint.h>
 
 #include <nuttx/fs/fs.h>
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-/* Indicates that there is no holder of the re-entrant semaphore */
-
-#define TMPFS_NO_HOLDER   -1
-
 /* Bit definitions for file object flags */
 
 #define TFO_FLAG_UNLINKED (1 << 0)  /* Bit 0: File is unlinked */
@@ -66,15 +62,6 @@ enum tmpfs_foreach_e
   TMPFS_UNLINKED         /* Only the directory entry was deleted */
 };
 
-/* Re-entrant semaphore */
-
-struct tmpfs_sem_s
-{
-  sem_t    ts_sem;       /* The actual semaphore */
-  pid_t    ts_holder;    /* Current older (-1 if not held) */
-  uint16_t ts_count;     /* Number of counts held */
-};
-
 /* The form of one directory entry */
 
 struct tmpfs_dirent_s
@@ -87,7 +74,7 @@ struct tmpfs_dirent_s
 
 struct tmpfs_object_s
 {
-  struct tmpfs_sem_s to_exclsem;
+  rmutex_t to_lock;
 
   size_t   to_alloc;     /* Allocated size of the memory object */
   uint8_t  to_type;      /* See enum tmpfs_objtype_e */
@@ -100,7 +87,7 @@ struct tmpfs_directory_s
 {
   /* First fields must match common TMPFS object layout */
 
-  struct tmpfs_sem_s tdo_exclsem;
+  rmutex_t tdo_lock;
 
   size_t   tdo_alloc;    /* Allocated size of the directory object */
   uint8_t  tdo_type;     /* See enum tmpfs_objtype_e */
@@ -126,7 +113,7 @@ struct tmpfs_file_s
 {
   /* First fields must match common TMPFS object layout */
 
-  struct tmpfs_sem_s tfo_exclsem;
+  rmutex_t tfo_lock;
 
   size_t   tfo_alloc;    /* Allocated size of the file object */
   uint8_t  tfo_type;     /* See enum tmpfs_objtype_e */
@@ -146,7 +133,7 @@ struct tmpfs_s
   /* The root directory */
 
   FAR struct tmpfs_dirent_s tfs_root;
-  struct tmpfs_sem_s tfs_exclsem;
+  rmutex_t tfs_lock;
 };
 
 /* This is the type used the tmpfs_statfs_callout to accumulate memory
diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h
index 8c7b5d2ff7..c411cc60c7 100644
--- a/include/nuttx/fs/fs.h
+++ b/include/nuttx/fs/fs.h
@@ -34,6 +34,7 @@
 #include <stdbool.h>
 #include <time.h>
 
+#include <nuttx/mutex.h>
 #include <nuttx/semaphore.h>
 
 /****************************************************************************
@@ -461,9 +462,7 @@ struct file_struct
   FAR struct file_struct *fs_next;      /* Pointer to next file stream */
   int                     fs_fd;        /* File descriptor associated with stream */
 #ifndef CONFIG_STDIO_DISABLE_BUFFERING
-  sem_t                   fs_sem;       /* For thread safety */
-  pid_t                   fs_holder;    /* Holder of sem */
-  int                     fs_counts;    /* Number of times sem is held */
+  rmutex_t                fs_lock;      /* Recursive lock */
   FAR unsigned char      *fs_bufstart;  /* Pointer to start of buffer */
   FAR unsigned char      *fs_bufend;    /* Pointer to 1 past end of buffer */
   FAR unsigned char      *fs_bufpos;    /* Current position in buffer */
diff --git a/include/nuttx/mutex.h b/include/nuttx/mutex.h
index 267e1f89d6..d2367639a1 100644
--- a/include/nuttx/mutex.h
+++ b/include/nuttx/mutex.h
@@ -29,15 +29,15 @@
 #include <errno.h>
 #include <assert.h>
 #include <unistd.h>
-#include <nuttx/sched.h>
 #include <nuttx/semaphore.h>
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define MUTEX_INITIALIZER    SEM_INITIALIZER(1)
-#define RMUTEX_INITIALIZER   {SEM_INITIALIZER(1), INVALID_PROCESS_ID, 0}
+#define NXRMUTEX_NO_HOLDER     (pid_t)-1
+#define NXMUTEX_INITIALIZER    SEM_INITIALIZER(1)
+#define NXRMUTEX_INITIALIZER   {SEM_INITIALIZER(1), NXRMUTEX_NO_HOLDER, 0}
 
 /****************************************************************************
  * Public Type Definitions
@@ -89,7 +89,14 @@ extern "C"
 
 static inline int nxmutex_init(FAR mutex_t *mutex)
 {
-  return nxsem_init(mutex, 0, 1);
+  int ret = _SEM_INIT(mutex, 0, 1);
+
+  if (ret < 0)
+    {
+      return _SEM_ERRVAL(ret);
+    }
+
+  return ret;
 }
 
 /****************************************************************************
@@ -113,7 +120,14 @@ static inline int nxmutex_init(FAR mutex_t *mutex)
 
 static inline int nxmutex_destroy(FAR mutex_t *mutex)
 {
-  return nxsem_destroy(mutex);
+  int ret = _SEM_DESTROY(mutex);
+
+  if (ret < 0)
+    {
+      return _SEM_ERRVAL(ret);
+    }
+
+  return ret;
 }
 
 /****************************************************************************
@@ -138,7 +152,26 @@ static inline int nxmutex_destroy(FAR mutex_t *mutex)
 
 static inline int nxmutex_lock(FAR mutex_t *mutex)
 {
-  return nxsem_wait_uninterruptible(mutex);
+  int ret;
+
+  for (; ; )
+    {
+      /* Take the semaphore (perhaps waiting) */
+
+      ret = _SEM_WAIT(mutex);
+      if (ret >= 0)
+        {
+          break;
+        }
+
+      ret = _SEM_ERRVAL(ret);
+      if (ret != -EINTR && ret != -ECANCELED)
+        {
+          break;
+        }
+    }
+
+  return ret;
 }
 
 /****************************************************************************
@@ -164,7 +197,14 @@ static inline int nxmutex_lock(FAR mutex_t *mutex)
 
 static inline int nxmutex_trylock(FAR mutex_t *mutex)
 {
-  return nxsem_trywait(mutex);
+  int ret = _SEM_TRYWAIT(mutex);
+
+  if (ret < 0)
+    {
+      return _SEM_ERRVAL(ret);
+    }
+
+  return ret;
 }
 
 /****************************************************************************
@@ -185,7 +225,7 @@ static inline bool nxmutex_is_locked(FAR mutex_t *mutex)
   int cnt;
   int ret;
 
-  ret = nxsem_get_value(mutex, &cnt);
+  ret = _SEM_GETVALUE(mutex, &cnt);
 
   DEBUGASSERT(ret == OK);
 
@@ -214,7 +254,15 @@ static inline bool nxmutex_is_locked(FAR mutex_t *mutex)
 
 static inline int nxmutex_unlock(FAR mutex_t *mutex)
 {
-  return nxsem_post(mutex);
+  int ret;
+
+  ret = _SEM_POST(mutex);
+  if (ret < 0)
+    {
+      return _SEM_ERRVAL(ret);
+    }
+
+  return ret;
 }
 
 /****************************************************************************
@@ -240,7 +288,7 @@ static inline int nxmutex_unlock(FAR mutex_t *mutex)
 static inline int nxrmutex_init(FAR rmutex_t *rmutex)
 {
   rmutex->count = 0;
-  rmutex->holder = INVALID_PROCESS_ID;
+  rmutex->holder = NXRMUTEX_NO_HOLDER;
   return nxmutex_init(&rmutex->mutex);
 }
 
@@ -406,7 +454,7 @@ static inline int nxrmutex_unlock(FAR rmutex_t *rmutex)
       if (rmutex->count == 1)
         {
           rmutex->count = 0;
-          rmutex->holder = INVALID_PROCESS_ID;
+          rmutex->holder = NXRMUTEX_NO_HOLDER;
           ret = nxmutex_unlock(&rmutex->mutex);
         }
       else
diff --git a/libs/libc/modlib/modlib_registry.c b/libs/libc/modlib/modlib_registry.c
index 53e4e22138..6194de11c5 100644
--- a/libs/libc/modlib/modlib_registry.c
+++ b/libs/libc/modlib/modlib_registry.c
@@ -29,36 +29,22 @@
 #include <debug.h>
 #include <errno.h>
 
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 #include <nuttx/lib/modlib.h>
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define NO_HOLDER (INVALID_PROCESS_ID)
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
-struct mod_registrylock_s
-{
-  sem_t lock;         /* The actual registry lock */
-  pid_t holder;       /* The PID of the current holder of the lock */
-  int16_t count;      /* The number of nested calls to modlib_registry_lock */
-};
-
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
-static struct mod_registrylock_s g_modlock =
-{
-  SEM_INITIALIZER(1), /* lock */
-  NO_HOLDER,          /* pid */
-  0                   /* count */
-};
+static rmutex_t g_modlock = NXRMUTEX_INITIALIZER;
 
 static FAR struct module_s *g_mod_registry;
 
@@ -82,40 +68,7 @@ static FAR struct module_s *g_mod_registry;
 
 void modlib_registry_lock(void)
 {
-  pid_t me;
-  int ret;
-
-  /* Do we already hold the semaphore? */
-
-  me = getpid();
-  if (me == g_modlock.holder)
-    {
-      /* Yes... just increment the count */
-
-      g_modlock.count++;
-      DEBUGASSERT(g_modlock.count > 0);
-    }
-
-  /* Take the semaphore (perhaps waiting) */
-
-  else
-    {
-      while ((ret = _SEM_WAIT(&g_modlock.lock)) < 0)
-        {
-          /* The only case that an error should occur here is if
-           * the wait was awakened by a signal.
-           */
-
-          DEBUGASSERT(_SEM_ERRNO(ret) == EINTR ||
-                      _SEM_ERRNO(ret) == ECANCELED);
-          UNUSED(ret);
-        }
-
-      /* No we hold the semaphore */
-
-      g_modlock.holder = me;
-      g_modlock.count  = 1;
-    }
+  nxrmutex_lock(&g_modlock);
 }
 
 /****************************************************************************
@@ -134,25 +87,7 @@ void modlib_registry_lock(void)
 
 void modlib_registry_unlock(void)
 {
-  DEBUGASSERT(g_modlock.holder == getpid());
-
-  /* Is this our last count on the semaphore? */
-
-  if (g_modlock.count > 1)
-    {
-      /* No.. just decrement the count */
-
-      g_modlock.count--;
-    }
-
-  /* Yes.. then we can really release the semaphore */
-
-  else
-    {
-      g_modlock.holder = NO_HOLDER;
-      g_modlock.count  = 0;
-      _SEM_POST(&g_modlock.lock);
-    }
+  nxrmutex_unlock(&g_modlock);
 }
 
 /****************************************************************************
diff --git a/libs/libc/netdb/lib_dnsinit.c b/libs/libc/netdb/lib_dnsinit.c
index ae45b82142..51795168a7 100644
--- a/libs/libc/netdb/lib_dnsinit.c
+++ b/libs/libc/netdb/lib_dnsinit.c
@@ -31,8 +31,7 @@
 #include <arpa/inet.h>
 
 #include <nuttx/sched.h>
-#include <nuttx/semaphore.h>
-
+#include <nuttx/mutex.h>
 #include "netdb/lib_dns.h"
 
 /****************************************************************************
@@ -41,9 +40,7 @@
 
 /* Protects DNS cache, nameserver list and notify list. */
 
-static sem_t g_dns_sem    = SEM_INITIALIZER(1);
-static pid_t g_dns_holder = INVALID_PROCESS_ID;
-static int   g_dns_count;
+static rmutex_t g_dns_lock = NXRMUTEX_INITIALIZER;
 
 /****************************************************************************
  * Public Data
@@ -140,56 +137,24 @@ bool dns_initialize(void)
  * Name: dns_semtake
  *
  * Description:
- *   Take the DNS semaphore, ignoring errors due to the receipt of signals.
+ *   Take the DNS lock, ignoring errors due to the receipt of signals.
  *
  ****************************************************************************/
 
 void dns_semtake(void)
 {
-  pid_t me = getpid();
-  int errcode = 0;
-  int ret;
-
-  /* Does this thread already hold the semaphore? */
-
-  if (g_dns_holder == me)
-    {
-      /* Yes.. just increment the reference count */
-
-      g_dns_count++;
-      return;
-    }
-
-  do
-    {
-      ret = _SEM_WAIT(&g_dns_sem);
-      if (ret < 0)
-        {
-          errcode = _SEM_ERRNO(ret);
-          DEBUGASSERT(errcode == EINTR || errcode == ECANCELED);
-        }
-    }
-  while (ret < 0 && errcode == EINTR);
-
-  g_dns_holder = me;
-  g_dns_count  = 1;
+  nxrmutex_lock(&g_dns_lock);
 }
 
 /****************************************************************************
  * Name: dns_semgive
  *
  * Description:
- *   Release the DNS semaphore
+ *   Release the DNS lock
  *
  ****************************************************************************/
 
 void dns_semgive(void)
 {
-  DEBUGASSERT(g_dns_holder == getpid() && g_dns_count > 0);
-
-  if (--g_dns_count == 0)
-    {
-      g_dns_holder = INVALID_PROCESS_ID;
-      DEBUGVERIFY(_SEM_POST(&g_dns_sem));
-    }
+  nxrmutex_unlock(&g_dns_lock);
 }
diff --git a/libs/libc/stdio/lib_fclose.c b/libs/libc/stdio/lib_fclose.c
index ac9c1d790e..d414f5abee 100644
--- a/libs/libc/stdio/lib_fclose.c
+++ b/libs/libc/stdio/lib_fclose.c
@@ -135,7 +135,7 @@ int fclose(FAR FILE *stream)
 #ifndef CONFIG_STDIO_DISABLE_BUFFERING
       /* Destroy the semaphore */
 
-      _SEM_DESTROY(&stream->fs_sem);
+      nxrmutex_destroy(&stream->fs_lock);
 
       /* Release the buffer */
 
diff --git a/libs/libc/stdio/lib_libfilesem.c b/libs/libc/stdio/lib_libfilesem.c
index a67a89dbfb..6f778a62f0 100644
--- a/libs/libc/stdio/lib_libfilesem.c
+++ b/libs/libc/stdio/lib_libfilesem.c
@@ -50,10 +50,7 @@ void lib_sem_initialize(FAR struct file_struct *stream)
    * to private data sets.
    */
 
-  _SEM_INIT(&stream->fs_sem, 0, 1);
-
-  stream->fs_holder = -1;
-  stream->fs_counts = 0;
+  nxrmutex_init(&stream->fs_lock);
 }
 
 /****************************************************************************
@@ -62,37 +59,7 @@ void lib_sem_initialize(FAR struct file_struct *stream)
 
 void lib_take_semaphore(FAR struct file_struct *stream)
 {
-  pid_t my_pid = getpid();
-  int ret;
-
-  /* Do I already have the semaphore? */
-
-  if (stream->fs_holder == my_pid)
-    {
-      /* Yes, just increment the number of references that I have */
-
-      stream->fs_counts++;
-    }
-  else
-    {
-      /* Take the semaphore (perhaps waiting) */
-
-      while ((ret = _SEM_WAIT(&stream->fs_sem)) < 0)
-        {
-          /* The only case that an error should occr here is if the wait
-           * was awakened by a signal.
-           */
-
-          DEBUGASSERT(_SEM_ERRNO(ret) == EINTR ||
-                      _SEM_ERRNO(ret) == ECANCELED);
-          UNUSED(ret);
-        }
-
-      /* We have it.  Claim the stak and return */
-
-      stream->fs_holder = my_pid;
-      stream->fs_counts = 1;
-    }
+  nxrmutex_lock(&stream->fs_lock);
 }
 
 /****************************************************************************
@@ -101,26 +68,7 @@ void lib_take_semaphore(FAR struct file_struct *stream)
 
 void lib_give_semaphore(FAR struct file_struct *stream)
 {
-  /* I better be holding at least one reference to the semaphore */
-
-  DEBUGASSERT(stream->fs_holder == getpid());
-
-  /* Do I hold multiple references to the semphore */
-
-  if (stream->fs_counts > 1)
-    {
-      /* Yes, just release one count and return */
-
-      stream->fs_counts--;
-    }
-  else
-    {
-      /* Nope, this is the last reference I have */
-
-      stream->fs_holder = -1;
-      stream->fs_counts = 0;
-      DEBUGVERIFY(_SEM_POST(&stream->fs_sem));
-    }
+  nxrmutex_unlock(&stream->fs_lock);
 }
 
 #endif /* CONFIG_STDIO_DISABLE_BUFFERING */
diff --git a/libs/libc/stdio/lib_libstream.c b/libs/libc/stdio/lib_libstream.c
index b59bf3dca5..3a25734287 100644
--- a/libs/libc/stdio/lib_libstream.c
+++ b/libs/libc/stdio/lib_libstream.c
@@ -118,7 +118,7 @@ void lib_stream_release(FAR struct task_group_s *group)
 #ifndef CONFIG_STDIO_DISABLE_BUFFERING
       /* Destroy the semaphore that protects the IO buffer */
 
-      _SEM_DESTROY(&stream->fs_sem);
+      nxrmutex_destroy(&stream->fs_lock);
 #endif
 
       /* Release the stream */
@@ -142,9 +142,9 @@ void lib_stream_release(FAR struct task_group_s *group)
   /* Destroy stdin, stdout and stderr stream */
 
 #ifndef CONFIG_STDIO_DISABLE_BUFFERING
-  _SEM_DESTROY(&list->sl_std[0].fs_sem);
-  _SEM_DESTROY(&list->sl_std[1].fs_sem);
-  _SEM_DESTROY(&list->sl_std[2].fs_sem);
+  nxrmutex_destroy(&list->sl_std[0].fs_lock);
+  nxrmutex_destroy(&list->sl_std[1].fs_lock);
+  nxrmutex_destroy(&list->sl_std[2].fs_lock);
 #endif
 }
 
diff --git a/net/route/net_fileroute.c b/net/route/net_fileroute.c
index 5349979b53..1b35179ff6 100644
--- a/net/route/net_fileroute.c
+++ b/net/route/net_fileroute.c
@@ -31,7 +31,7 @@
 #include <assert.h>
 #include <debug.h>
 
-#include <nuttx/semaphore.h>
+#include <nuttx/mutex.h>
 #include <nuttx/fs/fs.h>
 
 #include "route/fileroute.h"
@@ -54,19 +54,15 @@
  ****************************************************************************/
 
 #ifdef CONFIG_ROUTE_IPv4_FILEROUTE
-/* Semaphore used to lock a routing table for exclusive write-only access */
+/* Used to lock a routing table for exclusive write-only access */
 
-static sem_t g_ipv4_exclsem = SEM_INITIALIZER(1);
-static pid_t g_ipv4_holder = NO_HOLDER;
-static int g_ipv4_count;
+static rmutex_t g_ipv4_lock = RMUTEX_INITIALIZER;
 #endif
 
 #ifdef CONFIG_ROUTE_IPv6_FILEROUTE
-/* Semaphore used to lock a routing table for exclusive write-only access */
+/* Used to lock a routing table for exclusive write-only access */
 
-static sem_t g_ipv6_exclsem = SEM_INITIALIZER(1);
-static pid_t g_ipv6_holder = NO_HOLDER;
-static int g_ipv6_count;
+static rmutex_t g_ipv6_lock = RMUTEX_INITIALIZER;
 #endif
 
 /****************************************************************************
@@ -597,36 +593,10 @@ int net_routesize_ipv6(void)
 #ifdef CONFIG_ROUTE_IPv4_FILEROUTE
 int net_lockroute_ipv4(void)
 {
-  pid_t me = getpid();
-  int ret;
-
-  /* Are we already the holder of the lock? */
-
-  if (g_ipv4_holder == me)
+  int ret = nxrmutex_lock(&g_ipv4_lock);
+  if (ret < 0)
     {
-      /* Yes.. just increment the count of locks held */
-
-      g_ipv4_count++;
-      ret = OK;
-    }
-  else
-    {
-      /* No.. wait to get the lock */
-
-      ret = nxsem_wait(&g_ipv4_exclsem);
-      if (ret < 0)
-        {
-          nerr("ERROR: nxsem_wait() failed: %d\n", ret);
-        }
-      else
-        {
-          DEBUGASSERT(g_ipv4_holder == NO_HOLDER && g_ipv4_count == 0);
-
-          /* We are now the holder with one count */
-
-          g_ipv4_holder = me;
-          g_ipv4_count  = 1;
-        }
+      nerr("ERROR: nxrmutex_lock() failed: %d\n", ret);
     }
 
   return ret;
@@ -636,36 +606,10 @@ int net_lockroute_ipv4(void)
 #ifdef CONFIG_ROUTE_IPv6_FILEROUTE
 int net_lockroute_ipv6(void)
 {
-  pid_t me = getpid();
-  int ret;
-
-  /* Are we already the holder of the lock? */
-
-  if (g_ipv6_holder == me)
-    {
-      /* Yes.. just increment the count of locks held */
-
-      g_ipv6_count++;
-      ret = OK;
-    }
-  else
+  int ret = nxrmutex_lock(&g_ipv6_lock);
+  if (ret < 0)
     {
-      /* No.. wait to get the lock */
-
-      ret = nxsem_wait(&g_ipv6_exclsem);
-      if (ret < 0)
-        {
-          nerr("ERROR: nxsem_wait() failed: %d\n", ret);
-        }
-      else
-        {
-          DEBUGASSERT(g_ipv6_holder == NO_HOLDER && g_ipv6_count == 0);
-
-          /* We are now the holder with one count */
-
-          g_ipv6_holder = me;
-          g_ipv6_count  = 1;
-        }
+      nerr("ERROR: nxrmutex_lock() failed: %d\n", ret);
     }
 
   return ret;
@@ -690,38 +634,10 @@ int net_lockroute_ipv6(void)
 #ifdef CONFIG_ROUTE_IPv4_FILEROUTE
 int net_unlockroute_ipv4(void)
 {
-  pid_t me = getpid();
-  int ret;
-
-  /* If would be an error if we are called with on a thread that does not
-   * hold the lock.
-   */
-
-  DEBUGASSERT(me == g_ipv4_holder && g_ipv4_count > 0);
-
-  /* Release the count on the lock.  If this is the last count, then release
-   * the lock.
-   */
-
-  if (g_ipv4_count > 1)
-    {
-      /* Not the last count... just decrement the count and return success */
-
-      g_ipv4_count--;
-      ret = OK;
-    }
-  else
+  int ret = nxrmutex_unlock(&g_ipv4_lock);
+  if (ret < 0)
     {
-      /* This is the last count.  Release the lock */
-
-      g_ipv4_holder = NO_HOLDER;
-      g_ipv4_count  = 0;
-
-      ret = nxsem_post(&g_ipv4_exclsem);
-      if (ret < 0)
-        {
-          nerr("ERROR: nxsem_post() failed: %d\n", ret);
-        }
+      nerr("ERROR: nxrmutex_unlock() failed: %d\n", ret);
     }
 
   return ret;
@@ -731,38 +647,10 @@ int net_unlockroute_ipv4(void)
 #ifdef CONFIG_ROUTE_IPv6_FILEROUTE
 int net_unlockroute_ipv6(void)
 {
-  pid_t me = getpid();
-  int ret;
-
-  /* If would be an error if we are called with on a thread that does not
-   * hold the lock.
-   */
-
-  DEBUGASSERT(me == g_ipv6_holder && g_ipv6_count > 0);
-
-  /* Release the count on the lock.  If this is the last count, then release
-   * the lock.
-   */
-
-  if (g_ipv6_count > 1)
-    {
-      /* Not the last count... just decrement the count and return success */
-
-      g_ipv6_count--;
-      ret = OK;
-    }
-  else
+  int ret = nxrmutex_unlock(&g_ipv6_lock);
+  if (ret < 0)
     {
-      /* This is the last count.  Release the lock */
-
-      g_ipv6_holder = NO_HOLDER;
-      g_ipv6_count  = 0;
-
-      ret = nxsem_post(&g_ipv6_exclsem);
-      if (ret < 0)
-        {
-          nerr("ERROR: nxsem_post() failed: %d\n", ret);
-        }
+      nerr("ERROR: nxrmutex_unlock() failed: %d\n", ret);
     }
 
   return ret;