Index: cpukit/libblock/include/rtems/bdbuf.h
===================================================================
--- cpukit/libblock/include/rtems/bdbuf.h	(revision d8ac087a8c092472abc688e2b4607c97a4b91707)
+++ cpukit/libblock/include/rtems/bdbuf.h	(revision 1fc2e960cea37e8d78e142c71faec18262f356d2)
@@ -175,4 +175,13 @@
 /**@{**/
 
+#if defined(RTEMS_POSIX_API)
+  /*
+   * Use the PTHREAD mutexes and condition variables if available.  This helps
+   * on SMP configurations to avoid the home grown condition variables via
+   * disabled preemption.
+   */
+  #define RTEMS_BDBUF_USE_PTHREAD
+#endif
+
 /**
  * @brief State of a buffer of the cache.
Index: cpukit/libblock/src/bdbuf.c
===================================================================
--- cpukit/libblock/src/bdbuf.c	(revision d8ac087a8c092472abc688e2b4607c97a4b91707)
+++ cpukit/libblock/src/bdbuf.c	(revision 1fc2e960cea37e8d78e142c71faec18262f356d2)
@@ -78,10 +78,20 @@
 } rtems_bdbuf_swapout_worker;
 
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+typedef pthread_mutex_t rtems_bdbuf_lock_type;
+#else
+typedef rtems_id rtems_bdbuf_lock_type;
+#endif
+
 /**
  * Buffer waiters synchronization.
  */
 typedef struct rtems_bdbuf_waiters {
-  unsigned count;
-  rtems_id sema;
+  unsigned       count;
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  pthread_cond_t cond_var;
+#else
+  rtems_id       sema;
+#endif
 } rtems_bdbuf_waiters;
 
@@ -107,7 +117,7 @@
   uint32_t            flags;             /**< Configuration flags. */
 
-  rtems_id            lock;              /**< The cache lock. It locks all
+  rtems_bdbuf_lock_type lock;            /**< The cache lock. It locks all
                                           * cache data, BD and lists. */
-  rtems_id            sync_lock;         /**< Sync calls block writes. */
+  rtems_bdbuf_lock_type sync_lock;       /**< Sync calls block writes. */
   bool                sync_active;       /**< True if a sync is active. */
   rtems_id            sync_requester;    /**< The sync requester. */
@@ -170,5 +180,10 @@
   RTEMS_BDBUF_FATAL_WAIT_EVNT,
   RTEMS_BDBUF_FATAL_WAIT_TRANS_EVNT,
-  RTEMS_BDBUF_FATAL_ONCE
+  RTEMS_BDBUF_FATAL_ONCE,
+  RTEMS_BDBUF_FATAL_MTX_ATTR_INIT,
+  RTEMS_BDBUF_FATAL_MTX_ATTR_SETPROTO,
+  RTEMS_BDBUF_FATAL_MTX_ATTR_SETTYPE,
+  RTEMS_BDBUF_FATAL_CV_WAIT,
+  RTEMS_BDBUF_FATAL_CV_BROADCAST
 } rtems_bdbuf_fatal_code;
 
@@ -318,4 +333,84 @@
 {
   rtems_bdbuf_fatal ((((uint32_t) state) << 16) | error);
+}
+
+static rtems_status_code
+rtems_bdbuf_lock_create (rtems_name name, rtems_bdbuf_lock_type *lock)
+{
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  int                 eno;
+  pthread_mutexattr_t attr;
+
+  (void) name;
+
+  eno = pthread_mutexattr_init (&attr);
+  if (eno != 0)
+    rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_MTX_ATTR_INIT);
+
+  eno = pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT);
+  if (eno != 0)
+    rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_MTX_ATTR_SETPROTO);
+
+  eno = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+  if (eno != 0)
+    rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_MTX_ATTR_SETTYPE);
+
+  eno = pthread_mutex_init (lock, &attr);
+
+  pthread_mutexattr_destroy (&attr);
+
+  if (eno != 0)
+    return RTEMS_UNSATISFIED;
+
+  return RTEMS_SUCCESSFUL;
+#else
+  return rtems_semaphore_create(
+    name,
+    1,
+    RTEMS_BDBUF_CACHE_LOCK_ATTRIBS,
+    0,
+    lock
+  );
+#endif
+}
+
+static void
+rtems_bdbuf_lock_delete (rtems_bdbuf_lock_type *lock)
+{
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  pthread_mutex_destroy (lock);
+#else
+  rtems_semaphore_delete (*lock);
+#endif
+}
+
+static rtems_status_code
+rtems_bdbuf_waiter_create (rtems_name name, rtems_bdbuf_waiters *waiter)
+{
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  int eno = pthread_cond_init (&waiter->cond_var, NULL);
+  if (eno != 0)
+    return RTEMS_UNSATISFIED;
+
+  return RTEMS_SUCCESSFUL;
+#else
+  return rtems_semaphore_create(
+    name,
+    0,
+    RTEMS_BDBUF_CACHE_WAITER_ATTRIBS,
+    0,
+    &waiter->sema
+  );
+#endif
+}
+
+static void
+rtems_bdbuf_waiter_delete (rtems_bdbuf_waiters *waiter)
+{
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  pthread_cond_destroy (&waiter->cond_var);
+#else
+  rtems_semaphore_delete (waiter->sema);
+#endif
 }
 
@@ -836,11 +931,17 @@
  */
 static void
-rtems_bdbuf_lock (rtems_id lock, uint32_t fatal_error_code)
-{
-  rtems_status_code sc = rtems_semaphore_obtain (lock,
+rtems_bdbuf_lock (rtems_bdbuf_lock_type *lock, uint32_t fatal_error_code)
+{
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  int eno = pthread_mutex_lock (lock);
+  if (eno != 0)
+    rtems_bdbuf_fatal (fatal_error_code);
+#else
+  rtems_status_code sc = rtems_semaphore_obtain (*lock,
                                                  RTEMS_WAIT,
                                                  RTEMS_NO_TIMEOUT);
   if (sc != RTEMS_SUCCESSFUL)
     rtems_bdbuf_fatal (fatal_error_code);
+#endif
 }
 
@@ -852,9 +953,15 @@
  */
 static void
-rtems_bdbuf_unlock (rtems_id lock, uint32_t fatal_error_code)
-{
-  rtems_status_code sc = rtems_semaphore_release (lock);
+rtems_bdbuf_unlock (rtems_bdbuf_lock_type *lock, uint32_t fatal_error_code)
+{
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  int eno = pthread_mutex_unlock (lock);
+  if (eno != 0)
+    rtems_bdbuf_fatal (fatal_error_code);
+#else
+  rtems_status_code sc = rtems_semaphore_release (*lock);
   if (sc != RTEMS_SUCCESSFUL)
     rtems_bdbuf_fatal (fatal_error_code);
+#endif
 }
 
@@ -865,5 +972,5 @@
 rtems_bdbuf_lock_cache (void)
 {
-  rtems_bdbuf_lock (bdbuf_cache.lock, RTEMS_BDBUF_FATAL_CACHE_LOCK);
+  rtems_bdbuf_lock (&bdbuf_cache.lock, RTEMS_BDBUF_FATAL_CACHE_LOCK);
 }
 
@@ -874,5 +981,5 @@
 rtems_bdbuf_unlock_cache (void)
 {
-  rtems_bdbuf_unlock (bdbuf_cache.lock, RTEMS_BDBUF_FATAL_CACHE_UNLOCK);
+  rtems_bdbuf_unlock (&bdbuf_cache.lock, RTEMS_BDBUF_FATAL_CACHE_UNLOCK);
 }
 
@@ -883,5 +990,5 @@
 rtems_bdbuf_lock_sync (void)
 {
-  rtems_bdbuf_lock (bdbuf_cache.sync_lock, RTEMS_BDBUF_FATAL_SYNC_LOCK);
+  rtems_bdbuf_lock (&bdbuf_cache.sync_lock, RTEMS_BDBUF_FATAL_SYNC_LOCK);
 }
 
@@ -892,5 +999,5 @@
 rtems_bdbuf_unlock_sync (void)
 {
-  rtems_bdbuf_unlock (bdbuf_cache.sync_lock,
+  rtems_bdbuf_unlock (&bdbuf_cache.sync_lock,
                       RTEMS_BDBUF_FATAL_SYNC_UNLOCK);
 }
@@ -908,4 +1015,5 @@
 }
 
+#if !defined(RTEMS_BDBUF_USE_PTHREAD)
 static rtems_mode
 rtems_bdbuf_disable_preemption (void)
@@ -930,4 +1038,5 @@
     rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_PREEMPT_RST);
 }
+#endif
 
 /**
@@ -949,7 +1058,4 @@
 rtems_bdbuf_anonymous_wait (rtems_bdbuf_waiters *waiters)
 {
-  rtems_status_code sc;
-  rtems_mode        prev_mode;
-
   /*
    * Indicate we are waiting.
@@ -957,32 +1063,45 @@
   ++waiters->count;
 
-  /*
-   * Disable preemption then unlock the cache and block.  There is no POSIX
-   * condition variable in the core API so this is a work around.
-   *
-   * The issue is a task could preempt after the cache is unlocked because it is
-   * blocking or just hits that window, and before this task has blocked on the
-   * semaphore. If the preempting task flushes the queue this task will not see
-   * the flush and may block for ever or until another transaction flushes this
-   * semaphore.
-   */
-  prev_mode = rtems_bdbuf_disable_preemption ();
-
-  /*
-   * Unlock the cache, wait, and lock the cache when we return.
-   */
-  rtems_bdbuf_unlock_cache ();
-
-  sc = rtems_semaphore_obtain (waiters->sema, RTEMS_WAIT, RTEMS_BDBUF_WAIT_TIMEOUT);
-
-  if (sc == RTEMS_TIMEOUT)
-    rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_CACHE_WAIT_TO);
-
-  if (sc != RTEMS_UNSATISFIED)
-    rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_CACHE_WAIT_2);
-
-  rtems_bdbuf_lock_cache ();
-
-  rtems_bdbuf_restore_preemption (prev_mode);
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+  {
+    int eno = pthread_cond_wait (&waiters->cond_var, &bdbuf_cache.lock);
+    if (eno != 0)
+      rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_CV_WAIT);
+  }
+#else
+  {
+    rtems_status_code sc;
+    rtems_mode        prev_mode;
+
+    /*
+     * Disable preemption then unlock the cache and block.  There is no POSIX
+     * condition variable in the core API so this is a work around.
+     *
+     * The issue is a task could preempt after the cache is unlocked because it is
+     * blocking or just hits that window, and before this task has blocked on the
+     * semaphore. If the preempting task flushes the queue this task will not see
+     * the flush and may block for ever or until another transaction flushes this
+     * semaphore.
+     */
+    prev_mode = rtems_bdbuf_disable_preemption();
+
+    /*
+     * Unlock the cache, wait, and lock the cache when we return.
+     */
+    rtems_bdbuf_unlock_cache ();
+
+    sc = rtems_semaphore_obtain (waiters->sema, RTEMS_WAIT, RTEMS_BDBUF_WAIT_TIMEOUT);
+
+    if (sc == RTEMS_TIMEOUT)
+      rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_CACHE_WAIT_TO);
+
+    if (sc != RTEMS_UNSATISFIED)
+      rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_CACHE_WAIT_2);
+
+    rtems_bdbuf_lock_cache ();
+
+    rtems_bdbuf_restore_preemption (prev_mode);
+  }
+#endif
 
   --waiters->count;
@@ -1004,13 +1123,17 @@
  */
 static void
-rtems_bdbuf_wake (const rtems_bdbuf_waiters *waiters)
-{
-  rtems_status_code sc = RTEMS_SUCCESSFUL;
-
+rtems_bdbuf_wake (rtems_bdbuf_waiters *waiters)
+{
   if (waiters->count > 0)
   {
-    sc = rtems_semaphore_flush (waiters->sema);
+#if defined(RTEMS_BDBUF_USE_PTHREAD)
+    int eno = pthread_cond_broadcast (&waiters->cond_var);
+    if (eno != 0)
+      rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_CV_BROADCAST);
+#else
+    rtems_status_code sc = rtems_semaphore_flush (waiters->sema);
     if (sc != RTEMS_SUCCESSFUL)
       rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_CACHE_WAKE);
+#endif
   }
 }
@@ -1434,7 +1557,7 @@
    * Create the locks for the cache.
    */
-  sc = rtems_semaphore_create (rtems_build_name ('B', 'D', 'C', 'l'),
-                               1, RTEMS_BDBUF_CACHE_LOCK_ATTRIBS, 0,
-                               &bdbuf_cache.lock);
+
+  sc = rtems_bdbuf_lock_create (rtems_build_name ('B', 'D', 'C', 'l'),
+                                &bdbuf_cache.lock);
   if (sc != RTEMS_SUCCESSFUL)
     goto error;
@@ -1442,25 +1565,21 @@
   rtems_bdbuf_lock_cache ();
 
-  sc = rtems_semaphore_create (rtems_build_name ('B', 'D', 'C', 's'),
-                               1, RTEMS_BDBUF_CACHE_LOCK_ATTRIBS, 0,
-                               &bdbuf_cache.sync_lock);
+  sc = rtems_bdbuf_lock_create (rtems_build_name ('B', 'D', 'C', 's'),
+                                &bdbuf_cache.sync_lock);
   if (sc != RTEMS_SUCCESSFUL)
     goto error;
 
-  sc = rtems_semaphore_create (rtems_build_name ('B', 'D', 'C', 'a'),
-                               0, RTEMS_BDBUF_CACHE_WAITER_ATTRIBS, 0,
-                               &bdbuf_cache.access_waiters.sema);
+  sc = rtems_bdbuf_waiter_create (rtems_build_name ('B', 'D', 'C', 'a'),
+                                  &bdbuf_cache.access_waiters);
   if (sc != RTEMS_SUCCESSFUL)
     goto error;
 
-  sc = rtems_semaphore_create (rtems_build_name ('B', 'D', 'C', 't'),
-                               0, RTEMS_BDBUF_CACHE_WAITER_ATTRIBS, 0,
-                               &bdbuf_cache.transfer_waiters.sema);
+  sc = rtems_bdbuf_waiter_create (rtems_build_name ('B', 'D', 'C', 't'),
+                                  &bdbuf_cache.transfer_waiters);
   if (sc != RTEMS_SUCCESSFUL)
     goto error;
 
-  sc = rtems_semaphore_create (rtems_build_name ('B', 'D', 'C', 'b'),
-                               0, RTEMS_BDBUF_CACHE_WAITER_ATTRIBS, 0,
-                               &bdbuf_cache.buffer_waiters.sema);
+  sc = rtems_bdbuf_waiter_create (rtems_build_name ('B', 'D', 'C', 'b'),
+                                  &bdbuf_cache.buffer_waiters);
   if (sc != RTEMS_SUCCESSFUL)
     goto error;
@@ -1621,13 +1740,13 @@
   free (bdbuf_cache.swapout_workers);
 
-  rtems_semaphore_delete (bdbuf_cache.buffer_waiters.sema);
-  rtems_semaphore_delete (bdbuf_cache.access_waiters.sema);
-  rtems_semaphore_delete (bdbuf_cache.transfer_waiters.sema);
-  rtems_semaphore_delete (bdbuf_cache.sync_lock);
+  rtems_bdbuf_waiter_delete (&bdbuf_cache.buffer_waiters);
+  rtems_bdbuf_waiter_delete (&bdbuf_cache.access_waiters);
+  rtems_bdbuf_waiter_delete (&bdbuf_cache.transfer_waiters);
+  rtems_bdbuf_lock_delete (&bdbuf_cache.sync_lock);
 
   if (bdbuf_cache.lock != 0)
   {
     rtems_bdbuf_unlock_cache ();
-    rtems_semaphore_delete (bdbuf_cache.lock);
+    rtems_bdbuf_lock_delete (&bdbuf_cache.lock);
   }
 
Index: cpukit/sapi/include/confdefs.h
===================================================================
--- cpukit/sapi/include/confdefs.h	(revision d8ac087a8c092472abc688e2b4607c97a4b91707)
+++ cpukit/sapi/include/confdefs.h	(revision 1fc2e960cea37e8d78e142c71faec18262f356d2)
@@ -1521,14 +1521,40 @@
     0 : CONFIGURE_BDBUF_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE))
 
-  /*
-   *  Semaphores:
-   *    o disk lock
-   *    o bdbuf lock
-   *    o bdbuf sync lock
-   *    o bdbuf access condition
-   *    o bdbuf transfer condition
-   *    o bdbuf buffer condition
-   */
-  #define CONFIGURE_LIBBLOCK_SEMAPHORES 6
+  #ifdef RTEMS_BDBUF_USE_PTHREAD
+    /*
+     * Semaphores:
+     *   o disk lock
+     */
+    #define CONFIGURE_LIBBLOCK_SEMAPHORES 1
+
+    /*
+     * POSIX Mutexes:
+     *  o bdbuf lock
+     *  o bdbuf sync lock
+     */
+    #define CONFIGURE_LIBBLOCK_POSIX_MUTEXES 2
+
+    /*
+     * POSIX Condition Variables:
+     *  o bdbuf access condition
+     *  o bdbuf transfer condition
+     *  o bdbuf buffer condition
+     */
+    #define CONFIGURE_LIBBLOCK_POSIX_CONDITION_VARIABLES 3
+  #else
+    /*
+     * Semaphores:
+     *   o disk lock
+     *   o bdbuf lock
+     *   o bdbuf sync lock
+     *   o bdbuf access condition
+     *   o bdbuf transfer condition
+     *   o bdbuf buffer condition
+     */
+    #define CONFIGURE_LIBBLOCK_SEMAPHORES 6
+
+    #define CONFIGURE_LIBBLOCK_POSIX_MUTEXES 0
+    #define CONFIGURE_LIBBLOCK_POSIX_CONDITION_VARIABLES 0
+  #endif
 
   #if defined(CONFIGURE_HAS_OWN_BDBUF_TABLE) || \
@@ -1541,4 +1567,6 @@
   #define CONFIGURE_LIBBLOCK_TASK_EXTRA_STACKS 0
   #define CONFIGURE_LIBBLOCK_SEMAPHORES 0
+  #define CONFIGURE_LIBBLOCK_POSIX_MUTEXES 0
+  #define CONFIGURE_LIBBLOCK_POSIX_CONDITION_VARIABLES 0
 #endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */
 
@@ -2210,4 +2238,5 @@
   #define CONFIGURE_POSIX_MUTEXES \
     (CONFIGURE_MAXIMUM_POSIX_MUTEXES + \
+      CONFIGURE_LIBBLOCK_POSIX_MUTEXES + \
       CONFIGURE_GNAT_MUTEXES + \
       CONFIGURE_MAXIMUM_ADA_TASKS + \
@@ -2221,4 +2250,5 @@
   #define CONFIGURE_POSIX_CONDITION_VARIABLES \
     (CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + \
+      CONFIGURE_LIBBLOCK_POSIX_CONDITION_VARIABLES + \
       CONFIGURE_MAXIMUM_ADA_TASKS + \
       CONFIGURE_MAXIMUM_FAKE_ADA_TASKS + \
