diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html
index 4c3f3ff79d2aa6771f454785838f53c6c81f1e9f..a381c6a6732b93e59389bca24369dc26c2025a3b 100644
--- a/Documentation/NuttxPortingGuide.html
+++ b/Documentation/NuttxPortingGuide.html
@@ -1627,9 +1627,18 @@ The system can be re-made subsequently by just typing <code>make</code>.
     errorcheck mutexes.  Enables <code>pthread_mutexattr_settype()</code>.
   </li>
   <li>
-    <code>CONFIG_PRIORITY_INHERITANCE </code>: Set to enable support for
+    <code>CONFIG_PRIORITY_INHERITANCE</code>: Set to enable support for
     priority inheritance on mutexes and semaphores.
   </li>
+  <li>
+    <code>CONFIG_SEM_PREALLOCHOLDERS: </code>: This setting is only used
+    if priority inheritance is enabled.
+    It defines the maximum number of different threads (minus one) that
+    can take counts on a semaphore with priority inheritance support.
+    This may be set to zero if priority inheritance is disabled OR if you
+    are only using semaphores as mutexes (only one holder) OR if no more
+    than two threads participate using a counting semaphore.
+  </li>
 </ul>
 
 <p>
diff --git a/configs/README.txt b/configs/README.txt
index cfd20b3b960e1778a0b0332df3a9e0d700befbfd..e6b656dc8c2ba48a5abfdd7bf25d9989b46d5c47 100644
--- a/configs/README.txt
+++ b/configs/README.txt
@@ -199,6 +199,14 @@ defconfig -- This is a configuration file similar to the Linux
 		  errorcheck mutexes.  Enables pthread_mutexattr_settype().
 		CONFIG_PRIORITY_INHERITANCE - Set to enable support for
 		  priority inheritance on mutexes and semaphores.
+		CONFIG_SEM_PREALLOCHOLDERS: This setting is only used if priority
+		  inheritance is enabled.  It defines the maximum number of
+		  different threads (minus one) that can take counts on a
+		  semaphore with priority inheritance support.  This may be 
+		  set to zero if priority inheritance is disabled OR if you
+		  are only using semaphores as mutexes (only one holder) OR
+		  if no more than two threads participate using a counting
+		  semaphore.
 
 	The following can be used to disable categories of APIs supported
 	by the OS.  If the compiler supports weak functions, then it
diff --git a/configs/sim/ostest/defconfig b/configs/sim/ostest/defconfig
index e9beee06bbad252cbd1f0ab8129678f1cf13c6e3..32823d716df9964778d5f631818e377940be5336 100644
--- a/configs/sim/ostest/defconfig
+++ b/configs/sim/ostest/defconfig
@@ -85,7 +85,14 @@ CONFIG_ARCH_BOARD_SIM=y
 # CONFIG_MUTEX_TYPES: Set to enable support for recursive and
 #   errorcheck mutexes. Enables pthread_mutexattr_settype().
 # CONFIG_PRIORITY_INHERITANCE : Set to enable support for priority
-#   inheritance on mutexes and semaphores. 
+#   inheritance on mutexes and semaphores.
+# CONFIG_SEM_PREALLOCHOLDERS: This setting is only used if priority
+#   inheritance is enabled.  It defines the maximum number of different
+#   threads (minus one) that can take counts on a semaphore with priority
+#   inheritance support.  This may be set to zero if priority inheritance
+#   is disabled OR if you are only using semaphores as mutexes (only
+#   one holder) OR if no more than two threads participate using a
+#   counting semaphore.
 #
 CONFIG_EXAMPLE=ostest
 CONFIG_DEBUG=y
@@ -103,6 +110,7 @@ CONFIG_DEV_CONSOLE=y
 CONFIG_DEV_LOWCONSOLE=n
 CONFIG_MUTEX_TYPES=y
 CONFIG_PRIORITY_INHERITANCE=n
+CONFIG_SEM_PREALLOCHOLDERS=3
 
 #
 # The following can be used to disable categories of
diff --git a/examples/ostest/prioinherit.c b/examples/ostest/prioinherit.c
index 7754ca587921fbfcadf7dd9eade30f49c2e0c148..850c2fc303395bbccba83f91c0d73a269bc08561 100644
--- a/examples/ostest/prioinherit.c
+++ b/examples/ostest/prioinherit.c
@@ -42,6 +42,7 @@
 #include <unistd.h>
 #include <semaphore.h>
 #include <pthread.h>
+#include <errno.h>
 
 #ifdef CONFIG_ARCH_SIM
 #  include <nuttx/arch.h>
@@ -55,6 +56,12 @@
  * Definitions
  ****************************************************************************/
 
+#ifndef CONFIG_SEM_PREALLOCHOLDERS
+#  define CONFIG_SEM_PREALLOCHOLDERS 0
+#endif
+#define NLOWPRI_THREADS  (CONFIG_SEM_PREALLOCHOLDERS+1)
+#define NHIGHPRI_THREADS 1
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -72,43 +79,82 @@ enum thstate_e
 };
 
 static sem_t g_sem;
-static volatile enum thstate_e g_middlestate = NOTSTARTED;
-static volatile enum thstate_e g_highstate   = NOTSTARTED;
-static volatile enum thstate_e g_lowstate    = NOTSTARTED;
+static volatile enum thstate_e g_middlestate;
+static volatile enum thstate_e g_highstate[NHIGHPRI_THREADS];
+static volatile enum thstate_e g_lowstate[NLOWPRI_THREADS];
 static int g_highpri;
 static int g_medpri;
 static int g_lowpri;
 
+/****************************************************************************
+ * Name: nhighpri_started
+ ****************************************************************************/
+
+static int nhighpri_started(void)
+{
+   int n = 0;
+   int i;
+ 
+   for (i = 0; i < NHIGHPRI_THREADS; i++)
+     {
+       if (g_highstate[i] != NOTSTARTED)
+         {
+           n++;
+         }
+     }
+   return n;
+}
+
+/****************************************************************************
+ * Name: nhighpri_running
+ ****************************************************************************/
+
+static int nhighpri_running(void)
+{
+   int n = 0;
+   int i;
+ 
+   for (i = 0; i < NHIGHPRI_THREADS; i++)
+     {
+       if (g_highstate[i] != DONE)
+         {
+           n++;
+         }
+     }
+   return n;
+}
+
 /****************************************************************************
  * Name: highpri_thread
  ****************************************************************************/
 
 static void *highpri_thread(void *parameter)
 {
+  int threadno = (int)parameter;
   int ret;
 
-  printf("highpri_thread: Started\n");
+  printf("highpri_thread-%d: Started\n", threadno);
   fflush(stdout);
 
-  g_highstate = WAITING;
-  ret = sem_wait(&g_sem);
-  g_highstate = DONE;
+  g_highstate[threadno-1] = WAITING;
+  ret                     = sem_wait(&g_sem);
+  g_highstate[threadno-1] = DONE;
 
   if (ret != 0)
     {
-      printf("highpri_thread: sem_take failed: %d\n", ret);
+      printf("highpri_thread-%d: sem_take failed: %d\n", threadno, ret);
     }
   else if (g_middlestate == RUNNING)
     {
-      printf("highpri_thread: SUCCESS midpri_thread is still running!\n");
+      printf("highpri_thread-%d: SUCCESS midpri_thread is still running!\n", threadno);
     }
   else
     {
-      printf("highpri_thread: ERROR --  midpri_thread has already exited!\n");
+      printf("highpri_thread-%d: ERROR --  midpri_thread has already exited!\n", threadno);
     }
 
   sem_post(&g_sem);
-  printf("medpri_thread: Okay... I'm done!\n");
+  printf("highpri_thread-%d: Okay... I'm done!\n", threadno);
   fflush(stdout);
   return NULL;
 }
@@ -156,7 +202,7 @@ static void *medpri_thread(void *parameter)
    * will be boosted.
    */
 
-  while (g_highstate != DONE)
+  while (nhighpri_running() > 0)
     {
       hog_cpu();
     }
@@ -175,87 +221,125 @@ static void *lowpri_thread(void *parameter)
 {
   void *retval = (void*)-1;
   struct sched_param sparam;
+  int threadno = (int)parameter;
+  int expected;
+  int count;
   int policy;
   int ret;
+  int nrunning;
+  int i;
 
-  g_lowstate = RUNNING;
-  printf("lowpri_thread: Started\n");
+  g_lowstate[threadno-1] = RUNNING;
+  printf("lowpri_thread-%d: Started\n", threadno);
 
   ret = pthread_getschedparam(pthread_self(), &policy, &sparam);
   if (ret != 0)
     {
-      printf("lowpri_thread: ERROR pthread_getschedparam failed: %d\n", ret);
+      printf("lowpri_thread-%d: ERROR pthread_getschedparam failed: %d\n", threadno, ret);
     }
   else
     {
-      printf("lowpri_thread: initial priority: %d\n", sparam.sched_priority);
+      printf("lowpri_thread-%d: initial priority: %d\n", threadno, sparam.sched_priority);
       if (sparam.sched_priority != g_lowpri)
         {
           printf("               ERROR should have been %d\n", g_lowpri);
         } 
     }
 
-  g_lowstate = WAITING;
+  g_lowstate[threadno-1] = WAITING;
   ret = sem_wait(&g_sem);
   if (ret != 0)
     {
-      printf("lowpri_thread: sem_take failed: %d\n", ret);
+      printf("lowpri_thread-%d: sem_take failed: %d\n", threadno, ret);
     }
   else
     {
       /* Hang on to the thread until the middle priority thread runs */
 
-      while (g_middlestate == NOTSTARTED && g_highstate != WAITING)
+      while (g_middlestate == NOTSTARTED && nhighpri_started() < NHIGHPRI_THREADS)
         {
-          printf("lowpri_thread: Waiting for the midle pri task to run\n");
-          printf("               g_middlestate=%d g_highstate=%d\n", (int)g_middlestate, (int)g_highstate);
-          printf("               I still have the semaphore\n");
+          printf("lowpri_thread-%d: Waiting for the midle pri task to run\n", threadno);
+          printf("    g_middlestate:  %d\n", (int)g_middlestate);
+          for (i = 0; i < NHIGHPRI_THREADS; i++)
+            {
+              printf("    g_highstate[%d]: %d\n", i, (int)g_highstate[i]);
+            }
+          printf("    I still have a count on the semaphore\n");
           fflush(stdout);
           sleep(1);
         }
 
+      /* Account for all of the semaphore counts.  At any given time if there are 'n'
+       * running hight prioity tasks, then the semaphore count should be '-n'
+       */
+
+      sched_lock(); /* Needs to be atomic */
+      ret      = sem_getvalue(&g_sem, &count);
+      nrunning = nhighpri_running();
+      sched_unlock();
+
+      if (ret < 0)
+        {
+          printf("lowpri_thread-%d: ERROR sem_getvalue failed: %d\n", threadno, errno);
+        }
+      printf("lowpri_thread-%d: Sem count: %d, No. highpri thread: %d\n", threadno, count, nrunning);
+
       /* The middle priority task is running, let go of the semaphore */
 
-     if (g_middlestate == RUNNING && g_highstate == WAITING)
-       {
-         /* Good.. the middle priority task is still running but we got priority! */
-
-         retval = NULL;
-       }
-     else
-       {
-         printf("lowpri_thread: ERROR the middle priority task has already exitted!\n");
-         printf("               g_middlestate=%d g_highstate=%d\n", (int)g_middlestate, (int)g_highstate);
-       }
+      if (g_middlestate == RUNNING && nrunning == -count)
+        {
+          /* Good.. the middle priority task is still running and the counts are okay. */
+
+          retval = NULL;
+        }
+      else
+        {
+          printf("lowpri_thread-%d: ERROR the middle priority task has already exitted!\n", threadno);
+          printf("               g_middlestate:  %d sem count=%d\n", (int)g_middlestate, count);
+          for (i = 0; i < NHIGHPRI_THREADS; i++)
+            {
+              printf("               g_highstate[%d]: %d\n", i, (int)g_highstate[i]);
+            }
+        }
     }
 
   ret = pthread_getschedparam(pthread_self(), &policy, &sparam);
   sem_post(&g_sem);
   if (ret != 0)
     {
-      printf("lowpri_thread: ERROR pthread_getschedparam failed: %d\n", ret);
+      printf("lowpri_thread-%d: ERROR pthread_getschedparam failed: %d\n", threadno, ret);
     }
   else
     {
-      printf("lowpri_thread: %s priority before sem_post: %d\n",
-             sparam.sched_priority != g_highpri ? "ERROR" : "SUCCESS",
+      if (nhighpri_running() > 0)
+        {
+          expected = g_highpri;
+        }
+      else
+        {
+          expected = g_lowpri;
+        }
+
+      printf("lowpri_thread-%d: %s priority before sem_post: %d\n",
+             threadno,
+             sparam.sched_priority != expected ? "ERROR" : "SUCCESS",
              sparam.sched_priority);
 
-      if (sparam.sched_priority != g_highpri)
+      if (sparam.sched_priority != expected)
         {
-          printf("               ERROR should have been %d\n", g_highpri);
-        } 
+          printf("               ERROR should have been %d\n", expected);
+        }
     }
 
-
   ret = pthread_getschedparam(pthread_self(), &policy, &sparam);
   if (ret != 0)
     {
-      printf("lowpri_thread: ERROR pthread_getschedparam failed: %d\n", ret);
+      printf("lowpri_thread-%d: ERROR pthread_getschedparam failed: %d\n", threadno, ret);
     }
   else
     {
-      printf("lowpri_thread: %s final priority: %d\n",
+      printf("lowpri_thread-%d: %s final priority: %d\n",
+             threadno,
              sparam.sched_priority != g_lowpri ? "ERROR" : "SUCCESS",
              sparam.sched_priority);
 
@@ -265,9 +349,9 @@ static void *lowpri_thread(void *parameter)
         } 
     }
 
-  printf("lowpri_thread: Okay... I'm done!\n");
+  printf("lowpri_thread-%d: Okay... I'm done!\n", threadno);
   fflush(stdout);
-  g_lowstate = DONE;
+  g_lowstate[threadno-1] = DONE;
   return retval;  
 }
 #endif /* CONFIG_PRIORITY_INHERITANCE && !CONFIG_DISABLE_SIGNALS && !CONFIG_DISABLE_PTHREAD */
@@ -283,14 +367,15 @@ static void *lowpri_thread(void *parameter)
 void priority_inheritance(void)
 {
 #if defined(CONFIG_PRIORITY_INHERITANCE) && !defined(CONFIG_DISABLE_SIGNALS) && !defined(CONFIG_DISABLE_PTHREAD)
-  pthread_t lowpri;
+  pthread_t lowpri[NLOWPRI_THREADS];
   pthread_t medpri;
-  pthread_t highpri;
+  pthread_t highpri[NHIGHPRI_THREADS];
   pthread_addr_t result;
   pthread_attr_t attr;
   struct sched_param sparam;
   int my_pri;
   int status;
+  int i;
 
   printf("priority_inheritance: Started\n");
 
@@ -306,37 +391,42 @@ void priority_inheritance(void)
   g_lowpri = sched_get_priority_min(SCHED_FIFO);
   g_medpri = my_pri - 1;
 
-  sem_init(&g_sem, 0, 1);
+  sem_init(&g_sem, 0, NLOWPRI_THREADS);
 
-  /* Start the low priority task */
+  /* Start the low priority threads */
 
-  printf("priority_inheritance: Starting lowpri_thread at %d\n", g_lowpri);
-  status = pthread_attr_init(&attr);
-  if (status != 0)
+  for (i = 0; i < NLOWPRI_THREADS; i++)
     {
-      printf("priority_inheritance: pthread_attr_init failed, status=%d\n", status);
-    }
-  sparam.sched_priority = g_lowpri;
-  status = pthread_attr_setschedparam(&attr,& sparam);
-  if (status != OK)
-    {
-      printf("priority_inheritance: pthread_attr_setschedparam failed, status=%d\n", status);
-    }
-  else
-    {
-      printf("priority_inheritance: Set lowpri_thread priority to %d\n", sparam.sched_priority);
-    }
+      int threadno = i+1;
+      printf("priority_inheritance: Starting lowpri_thread-%d (of %d) at %d\n",
+             threadno, NLOWPRI_THREADS, g_lowpri);
+      status = pthread_attr_init(&attr);
+      if (status != 0)
+        {
+          printf("priority_inheritance: pthread_attr_init failed, status=%d\n", status);
+        }
+      sparam.sched_priority = g_lowpri;
+      status = pthread_attr_setschedparam(&attr,& sparam);
+      if (status != OK)
+        {
+          printf("priority_inheritance: pthread_attr_setschedparam failed, status=%d\n", status);
+        }
+      else
+        {
+          printf("priority_inheritance: Set lowpri_thread-%d priority to %d\n",
+                 threadno, sparam.sched_priority);
+        }
 
-  status = pthread_create(&lowpri, &attr, lowpri_thread, NULL);
-  if (status != 0)
-    {
-      printf("priority_inheritance: pthread_create failed, status=%d\n", status);
+      status = pthread_create(&lowpri[i], &attr, lowpri_thread, (void*)threadno);
+      if (status != 0)
+        {
+          printf("priority_inheritance: pthread_create failed, status=%d\n", status);
+        }
     }
-
   printf("priority_inheritance: Waiting...\n");
   sleep(2);
 
-  /* Start the medium priority task */
+  /* Start the medium priority thread */
 
   printf("priority_inheritance: Starting medpri_thread at %d\n", g_medpri);
   status = pthread_attr_init(&attr);
@@ -365,44 +455,56 @@ void priority_inheritance(void)
   printf("priority_inheritance: Waiting...\n");
   sleep(1);
 
-  /* Start the high priority task */
+  /* Start the high priority threads */
 
-  printf("priority_inheritance: Starting highpri_thread at %d\n", g_highpri);
-  status = pthread_attr_init(&attr);
-  if (status != 0)
+  for (i = 0; i < NHIGHPRI_THREADS; i++)
     {
-      printf("priority_inheritance: pthread_attr_init failed, status=%d\n", status);
-    }
+      int threadno = i+1;
+      printf("priority_inheritance: Starting highpri_thread-%d (of %d) at %d\n",
+             threadno, NHIGHPRI_THREADS, g_highpri);
+      status = pthread_attr_init(&attr);
+      if (status != 0)
+        {
+          printf("priority_inheritance: pthread_attr_init failed, status=%d\n", status);
+        }
 
-  sparam.sched_priority = g_highpri;
-  status = pthread_attr_setschedparam(&attr,& sparam);
-  if (status != OK)
-    {
-      printf("priority_inheritance: pthread_attr_setschedparam failed, status=%d\n", status);
-    }
-  else
-    {
-      printf("priority_inheritance: Set highpri_thread priority to %d\n", sparam.sched_priority);
-    }
-  fflush(stdout);
+      sparam.sched_priority = g_highpri;
+      status = pthread_attr_setschedparam(&attr,& sparam);
+      if (status != OK)
+        {
+          printf("priority_inheritance: pthread_attr_setschedparam failed, status=%d\n", status);
+        }
+      else
+        {
+          printf("priority_inheritance: Set highpri_thread-%d priority to %d\n",
+                 threadno, sparam.sched_priority);
+        }
+      fflush(stdout);
 
-  status = pthread_create(&medpri, &attr, highpri_thread, NULL);
-  if (status != 0)
-    {
-      printf("priority_inheritance: pthread_create failed, status=%d\n", status);
+      status = pthread_create(&highpri[i], &attr, highpri_thread, (void*)threadno);
+      if (status != 0)
+        {
+          printf("priority_inheritance: pthread_create failed, status=%d\n", status);
+        }
     }
 
   /* Wait for all thread instances to complete */
 
-  printf("priority_inheritance: Waiting for highpri_thread to complete\n");
-  fflush(stdout);
-  (void)pthread_join(highpri, &result);
+  for (i = 0; i < NLOWPRI_THREADS; i++)
+    {
+      printf("priority_inheritance: Waiting for highpri_thread-%d to complete\n", i+1);
+      fflush(stdout);
+      (void)pthread_join(highpri[i], &result);
+  }
   printf("priority_inheritance: Waiting for medpri_thread to complete\n");
   fflush(stdout);
   (void)pthread_join(medpri, &result);
-  printf("priority_inheritance: Waiting for lowpri_thread to complete\n");
-  fflush(stdout);
-  (void)pthread_join(lowpri, &result);
+  for (i = 0; i < NLOWPRI_THREADS; i++)
+    {
+      printf("priority_inheritance: Waiting for lowpri_thread-%d to complete\n", i+1);
+      fflush(stdout);
+      (void)pthread_join(lowpri[i], &result);
+    }
 
   printf("priority_inheritance: Finished\n");
   sem_destroy(&g_sem);
diff --git a/include/semaphore.h b/include/semaphore.h
index 8061d3d5d32bc9e011615ff65352f12f103d0764..9f38667c18db8086ddf792c308c54ac6549c2ebc 100644
--- a/include/semaphore.h
+++ b/include/semaphore.h
@@ -63,7 +63,7 @@ extern "C" {
 #ifdef CONFIG_PRIORITY_INHERITANCE
 struct semholder_s
 {
-#if !defined(CONFIG_SEM_PREALLOCHOLDERS) || CONFIG_SEM_PREALLOCHOLDERS > 0
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
   struct semholder_s *flink;    /* Implements singly linked list */
 #endif
   void  *holder;                /* Holder TCB (actual type is _TCB) */
diff --git a/sched/sem_holder.c b/sched/sem_holder.c
index 0477a67e2a1341c2d05f9dcf4e61683d65dc373e..3806bfdc9f1d0265cc18836857ab32833270000e 100644
--- a/sched/sem_holder.c
+++ b/sched/sem_holder.c
@@ -218,6 +218,9 @@ static inline void sem_freeholder(sem_t *sem, FAR struct semholder_s *pholder)
 static int sem_foreachholder(FAR sem_t *sem, holderhandler_t handler, FAR void *arg)
 {
   struct semholder_s *pholder = &sem->hlist;
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+  struct semholder_s *next;
+#endif
   int ret = 0;
 
 #if CONFIG_SEM_PREALLOCHOLDERS > 0
diff --git a/sched/sem_init.c b/sched/sem_init.c
index 05485a600a4dec55b37cd40577f130bb0443f3f6..65707949fed864d2b479c1b3a26f553d0218b301 100644
--- a/sched/sem_init.c
+++ b/sched/sem_init.c
@@ -99,7 +99,9 @@ int sem_init (FAR sem_t *sem, int pshared, unsigned int value)
     {
       sem->semcount     = (sint16)value;
 #ifdef CONFIG_PRIORITY_INHERITANCE
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
       sem->hlist.flink  = NULL;
+#endif
       sem->hlist.holder = NULL;
       sem->hlist.counts = 0;
 #endif
diff --git a/tools/mkconfig.c b/tools/mkconfig.c
index 82cff503bf9e53268b9372ac59b3563004652716..6b2299e7be491a237055d23063e8b9b6c5dd0e41 100644
--- a/tools/mkconfig.c
+++ b/tools/mkconfig.c
@@ -243,11 +243,11 @@ int main(int argc, char **argv, char **envp)
   printf("/* If priority inheritance is disabled, then do not allocate any\n");
   printf(" * associated resources.\n");
   printf(" */\n\n");
-  printf("#if !defined(CONFIG_PROIRITY_INHERITANCE) || !defined(CONFIG_SEM_PREALLOCHOLDERSS)\n");
+  printf("#if !defined(CONFIG_PRIORITY_INHERITANCE) || !defined(CONFIG_SEM_PREALLOCHOLDERS)\n");
   printf("# undef CONFIG_SEM_PREALLOCHOLDERS\n");
-  printf("# define CONFIG_SEM_PREALLOCHOLDERSS 0\n");
+  printf("# define CONFIG_SEM_PREALLOCHOLDERS 0\n");
   printf("#endif\n\n");
-  printf("#if !defined(CONFIG_PROIRITY_INHERITANCE) || !defined(CONFIG_SEM_NNESTPRIO)\n");
+  printf("#if !defined(CONFIG_PRIORITY_INHERITANCE) || !defined(CONFIG_SEM_NNESTPRIO)\n");
   printf("# undef CONFIG_SEM_NNESTPRIO\n");
   printf("# define CONFIG_SEM_NNESTPRIO 0\n");
   printf("#endif\n\n");