Index: cpukit/posix/Makefile.am
===================================================================
--- cpukit/posix/Makefile.am	(revision 40398c45dcd9734b41f37ae4c5af124d58b59b32)
+++ cpukit/posix/Makefile.am	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
@@ -34,4 +34,5 @@
 include_rtems_posix_HEADERS += include/rtems/posix/mutex.h
 include_rtems_posix_HEADERS += include/rtems/posix/muteximpl.h
+include_rtems_posix_HEADERS += include/rtems/posix/onceimpl.h
 include_rtems_posix_HEADERS += include/rtems/posix/posixapi.h
 include_rtems_posix_HEADERS += include/rtems/posix/priorityimpl.h
@@ -116,4 +117,7 @@
     src/mutextranslatereturncode.c src/mutextrylock.c src/mutexunlock.c
 
+## ONCE_C_FILES
+libposix_a_SOURCES += src/once.c src/pthreadonce.c
+
 ## PTHREAD_C_FILES
 libposix_a_SOURCES += src/pthreadatfork.c src/pthreadattrdestroy.c \
@@ -132,5 +136,5 @@
     src/pthreadgetschedparam.c \
     src/pthreadinitthreads.c src/pthreadjoin.c src/pthreadkill.c \
-    src/pthreadonce.c src/pthreadself.c \
+    src/pthreadself.c \
     src/pthreadsetschedparam.c src/pthreadsigmask.c \
     src/psxpriorityisvalid.c src/psxtransschedparam.c
Index: cpukit/posix/include/rtems/posix/onceimpl.h
===================================================================
--- cpukit/posix/include/rtems/posix/onceimpl.h	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
+++ cpukit/posix/include/rtems/posix/onceimpl.h	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
@@ -0,0 +1,57 @@
+/**
+ * @file
+ *
+ * @brief Private Inlined Routines for POSIX Once
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX once.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  COPYRIGHT (c) 2013.
+ *  Chris Johns <chrisj@rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/percpu.h>
+
+#ifndef _RTEMS_POSIX_ONCEIMPL_H
+#define _RTEMS_POSIX_ONCEMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup POSIX_ONCE
+ *
+ * @{
+ */
+
+/**
+ * @brief Lock to allow once mutex's to be initialized.
+ */
+POSIX_EXTERN pthread_mutex_t _POSIX_Once_Lock;
+
+/**
+ * @brief POSIX once manager initialization.
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+void _POSIX_Once_Manager_initialization(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*  end of include file */
Index: cpukit/posix/preinstall.am
===================================================================
--- cpukit/posix/preinstall.am	(revision 40398c45dcd9734b41f37ae4c5af124d58b59b32)
+++ cpukit/posix/preinstall.am	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
@@ -85,4 +85,8 @@
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/muteximpl.h
 
+$(PROJECT_INCLUDE)/rtems/posix/onceimpl.h: include/rtems/posix/onceimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/onceimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/onceimpl.h
+
 $(PROJECT_INCLUDE)/rtems/posix/posixapi.h: include/rtems/posix/posixapi.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/posixapi.h
Index: cpukit/posix/src/once.c
===================================================================
--- cpukit/posix/src/once.c	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
+++ cpukit/posix/src/once.c	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
@@ -0,0 +1,49 @@
+/**
+ * @file
+ *
+ * @brief POSIX Once Manager Initialization
+ * @ingroup POSIX_ONCE POSIX Once Support
+ */
+
+/*
+ *  COPYRIGHT (c) 2013
+ *  Chris Johns <chrisj@rtems.org>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/posix/onceimpl.h>
+
+pthread_mutex_t _POSIX_Once_Lock;
+
+void _POSIX_Once_Manager_initialization(void)
+{
+  pthread_mutexattr_t mattr;
+  int r;
+
+  _POSIX_Once_Lock = PTHREAD_MUTEX_INITIALIZER;
+
+  r = pthread_mutexattr_init( &mattr );
+  if ( r != 0 )
+    rtems_fatal( RTEMS_FATAL_SOURCE_ASSERT, 0x80aa0000 | r );
+
+  r = pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_RECURSIVE );
+   if ( r != 0 )
+    rtems_fatal( RTEMS_FATAL_SOURCE_ASSERT, 0x80aa1000 | r );
+
+  r = pthread_mutex_init( &_POSIX_Once_Lock, &mattr );
+  if ( r != 0 )
+    rtems_fatal( RTEMS_FATAL_SOURCE_ASSERT, 0x80aa2000 | r );
+
+  pthread_mutexattr_destroy( &mattr );
+}
Index: cpukit/posix/src/pthreadonce.c
===================================================================
--- cpukit/posix/src/pthreadonce.c	(revision 40398c45dcd9734b41f37ae4c5af124d58b59b32)
+++ cpukit/posix/src/pthreadonce.c	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
@@ -26,5 +26,9 @@
 #include <rtems.h>
 #include <rtems/system.h>
-#include <rtems/score/thread.h>
+#include <rtems/posix/onceimpl.h>
+
+#define PTHREAD_ONCE_INIT_NOT_RUN  0
+#define PTHREAD_ONCE_INIT_RUNNING  1
+#define PTHREAD_ONCE_INIT_RUN      2
 
 int pthread_once(
@@ -33,17 +37,43 @@
 )
 {
+  int r = 0;
+
   if ( !once_control || !init_routine )
     return EINVAL;
 
-  if ( !once_control->init_executed ) {
-    rtems_mode saveMode;
-    rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode);
-    if ( !once_control->init_executed ) {
-      once_control->is_initialized = true;
-      once_control->init_executed = true;
-      (*init_routine)();
+  if ( once_control->is_initialized != 1 )
+    return EINVAL;
+
+  if ( once_control->init_executed != PTHREAD_ONCE_INIT_RUN ) {
+    r = pthread_mutex_lock( &_POSIX_Once_Lock );
+    if ( r == 0 ) {
+      int rr;
+
+      /*
+       * Getting to here means the once_control is locked so we have:
+       *  1. The init has not run and the state is PTHREAD_ONCE_INIT_NOT_RUN.
+       *  2. The init has finished and the state is PTHREAD_ONCE_INIT_RUN.
+       *  3. The init is being run by this thread and the state
+       *     PTHREAD_ONCE_INIT_RUNNING so we are nesting. This is an error.
+       */
+
+      switch ( once_control->init_executed ) {
+        case PTHREAD_ONCE_INIT_NOT_RUN:
+          once_control->init_executed = PTHREAD_ONCE_INIT_RUNNING;
+          (*init_routine)();
+          once_control->init_executed = PTHREAD_ONCE_INIT_RUN;
+          break;
+        case PTHREAD_ONCE_INIT_RUNNING:
+          r = EINVAL;
+          break;
+        default:
+          break;
+      }
+      rr = pthread_mutex_unlock( &_POSIX_Once_Lock );
+      if ( r == 0 )
+        r = rr;
     }
-    rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode);
   }
-  return 0;
+
+  return r;
 }
Index: cpukit/sapi/include/confdefs.h
===================================================================
--- cpukit/sapi/include/confdefs.h	(revision 40398c45dcd9734b41f37ae4c5af124d58b59b32)
+++ cpukit/sapi/include/confdefs.h	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
@@ -1696,4 +1696,9 @@
 
   /**
+   * POSIX Once support uses a single mutex.
+   */
+  #define CONFIGURE_MAXIMUM_POSIX_INTERNAL_MUTEXES 1
+
+  /**
    * Account for the object control structures plus the name
    * of the object to be duplicated.
@@ -1857,4 +1862,5 @@
   #define CONFIGURE_MEMORY_FOR_POSIX \
     ( CONFIGURE_MEMORY_FOR_POSIX_MUTEXES( CONFIGURE_MAXIMUM_POSIX_MUTEXES + \
+          CONFIGURE_MAXIMUM_POSIX_INTERNAL_MUTEXES + \
           CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_MUTEXES) + \
       CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES( \
@@ -2305,4 +2311,5 @@
         CONFIGURE_MAXIMUM_GOROUTINES,
       CONFIGURE_MAXIMUM_POSIX_MUTEXES + CONFIGURE_GNAT_MUTEXES +
+        CONFIGURE_MAXIMUM_POSIX_INTERNAL_MUTEXES +
         CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS +
         CONFIGURE_GO_INIT_MUTEXES + CONFIGURE_MAXIMUM_GO_CHANNELS,
Index: cpukit/sapi/src/posixapi.c
===================================================================
--- cpukit/sapi/src/posixapi.c	(revision 40398c45dcd9734b41f37ae4c5af124d58b59b32)
+++ cpukit/sapi/src/posixapi.c	(revision 03acc5915e002f0b03eee9e86212209705cca6d6)
@@ -34,4 +34,5 @@
 #include <rtems/posix/mqueueimpl.h>
 #include <rtems/posix/muteximpl.h>
+#include <rtems/posix/onceimpl.h>
 #include <rtems/posix/posixapi.h>
 #include <rtems/posix/priorityimpl.h>
@@ -67,4 +68,5 @@
   _POSIX_Mutex_Manager_initialization();
   _POSIX_Message_queue_Manager_initialization();
+  _POSIX_Once_Manager_initialization();
   _POSIX_Semaphore_Manager_initialization();
   _POSIX_Timer_Manager_initialization();
