posix: Use interal mutex for once implementation

Enable pthread_once() for all configurations.  The pthread_once()
function is one means to initialize POSIX keys.  Another use case is the
C++ support.
This commit is contained in:
Sebastian Huber
2014-03-18 08:28:14 +01:00
parent fa3993d92d
commit 51f823c932
10 changed files with 43 additions and 155 deletions

View File

@@ -36,7 +36,6 @@ include_rtems_posix_HEADERS += include/rtems/posix/mqueue.h
include_rtems_posix_HEADERS += include/rtems/posix/mqueueimpl.h
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/priorityimpl.h
include_rtems_posix_HEADERS += include/rtems/posix/psignal.h
include_rtems_posix_HEADERS += include/rtems/posix/psignalimpl.h
@@ -113,9 +112,6 @@ libposix_a_SOURCES += src/mutexattrdestroy.c src/mutexattrgetprioceiling.c \
src/mutexlocksupp.c src/mutexsetprioceiling.c src/mutextimedlock.c \
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 \
src/pthreadattrgetdetachstate.c src/pthreadattrgetinheritsched.c \
@@ -160,6 +156,9 @@ libposix_a_SOURCES += src/key.c src/keycreate.c src/keydelete.c \
src/keygetspecific.c src/keyfreememory.c src/keyrundestructors.c \
src/keysetspecific.c
## ONCE_C_FILES
libposix_a_SOURCES += src/pthreadonce.c
libposix_a_SOURCES += src/sigaddset.c src/sigdelset.c src/sigfillset.c \
src/sigemptyset.c src/sigismember.c

View File

@@ -1,57 +0,0 @@
/**
* @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_ONCEIMPL_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 */

View File

@@ -88,10 +88,6 @@ $(PROJECT_INCLUDE)/rtems/posix/muteximpl.h: include/rtems/posix/muteximpl.h $(PR
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/muteximpl.h
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/priorityimpl.h: include/rtems/posix/priorityimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h

View File

@@ -1,46 +0,0 @@
/**
* @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/posixapi.h>
#include <rtems/posix/onceimpl.h>
void _POSIX_Once_Manager_initialization(void)
{
pthread_mutexattr_t mattr;
int eno;
_POSIX_Once_Lock = PTHREAD_MUTEX_INITIALIZER;
eno = pthread_mutexattr_init( &mattr );
_Assert( eno == 0 );
eno = pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_RECURSIVE );
_Assert( eno == 0 );
eno = pthread_mutex_init( &_POSIX_Once_Lock, &mattr );
if ( eno != 0 )
_POSIX_Fatal_error( POSIX_FD_PTHREAD_ONCE, eno );
eno = pthread_mutexattr_destroy( &mattr );
_Assert( eno == 0 );
}

View File

@@ -23,9 +23,7 @@
#include <pthread.h>
#include <errno.h>
#include <rtems.h>
#include <rtems/system.h>
#include <rtems/posix/onceimpl.h>
#include <rtems/score/apimutex.h>
#define PTHREAD_ONCE_INIT_NOT_RUN 0
#define PTHREAD_ONCE_INIT_RUNNING 1
@@ -45,34 +43,30 @@ int pthread_once(
return EINVAL;
if ( once_control->init_executed != PTHREAD_ONCE_INIT_COMPLETE ) {
r = pthread_mutex_lock( &_POSIX_Once_Lock );
if ( r == 0 ) {
int rr;
_Once_Lock();
/*
* 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.
*/
/*
* 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_COMPLETE;
break;
case PTHREAD_ONCE_INIT_RUNNING:
r = EINVAL;
break;
default:
break;
}
rr = pthread_mutex_unlock( &_POSIX_Once_Lock );
if ( r == 0 )
r = rr;
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_COMPLETE;
break;
case PTHREAD_ONCE_INIT_RUNNING:
r = EINVAL;
break;
default:
break;
}
_Once_Unlock();
}
return r;