From a5385b1f729cf671f458c0b2128a0d64b0c307a6 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Thu, 20 Mar 2014 09:22:00 +0100 Subject: score: Unify pthread and gxx_wrapper once and move to score. --- cpukit/libcsupport/src/gxx_wrappers.c | 15 ++------ cpukit/posix/src/pthreadonce.c | 37 ++----------------- cpukit/score/Makefile.am | 2 ++ cpukit/score/include/rtems/score/onceimpl.h | 48 +++++++++++++++++++++++++ cpukit/score/preinstall.am | 4 +++ cpukit/score/src/once.c | 56 +++++++++++++++++++++++++++++ 6 files changed, 114 insertions(+), 48 deletions(-) create mode 100644 cpukit/score/include/rtems/score/onceimpl.h create mode 100644 cpukit/score/src/once.c diff --git a/cpukit/libcsupport/src/gxx_wrappers.c b/cpukit/libcsupport/src/gxx_wrappers.c index 31f6254063..711daa495a 100644 --- a/cpukit/libcsupport/src/gxx_wrappers.c +++ b/cpukit/libcsupport/src/gxx_wrappers.c @@ -29,6 +29,7 @@ #endif #include +#include #include @@ -43,19 +44,7 @@ int rtems_gxx_once(__gthread_once_t *once, void (*func) (void)) printk( "gxx_wrappers: once=%x, func=%x\n", *once, func ); #endif - if ( *(volatile __gthread_once_t *)once == 0 ) { - rtems_mode saveMode; - __gthread_once_t o; - - rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode); - if ( (o = *(volatile __gthread_once_t *)once) == 0 ) { - *(volatile __gthread_once_t *)once = 1; - } - rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode); - if ( o == 0 ) - (*func)(); - } - return 0; + return _Once( once, func ); } int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *)) diff --git a/cpukit/posix/src/pthreadonce.c b/cpukit/posix/src/pthreadonce.c index 87a3b53ef6..dc8a449a87 100644 --- a/cpukit/posix/src/pthreadonce.c +++ b/cpukit/posix/src/pthreadonce.c @@ -23,51 +23,18 @@ #include #include -#include - -#define PTHREAD_ONCE_INIT_NOT_RUN 0 -#define PTHREAD_ONCE_INIT_RUNNING 1 -#define PTHREAD_ONCE_INIT_COMPLETE 2 +#include int pthread_once( pthread_once_t *once_control, void (*init_routine)(void) ) { - int r = 0; - if ( !once_control || !init_routine ) return EINVAL; if ( once_control->is_initialized != 1 ) return EINVAL; - if ( once_control->init_executed != PTHREAD_ONCE_INIT_COMPLETE ) { - _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. - */ - - 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; + return _Once( &once_control->init_executed, init_routine ); } diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 6c4293ab83..aeee4b6b32 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -41,6 +41,7 @@ include_rtems_score_HEADERS += include/rtems/score/isrlock.h include_rtems_score_HEADERS += include/rtems/score/freechain.h include_rtems_score_HEADERS += include/rtems/score/object.h include_rtems_score_HEADERS += include/rtems/score/objectimpl.h +include_rtems_score_HEADERS += include/rtems/score/onceimpl.h include_rtems_score_HEADERS += include/rtems/score/percpu.h include_rtems_score_HEADERS += include/rtems/score/priority.h include_rtems_score_HEADERS += include/rtems/score/prioritybitmap.h @@ -335,6 +336,7 @@ libscore_a_SOURCES += src/apiext.c src/chain.c src/chainappend.c \ src/interr.c src/isr.c src/wkspace.c src/wkstringduplicate.c libscore_a_SOURCES += src/debugisownerofallocator.c libscore_a_SOURCES += src/profilingisrentryexit.c +libscore_a_SOURCES += src/once.c EXTRA_DIST = src/Unlimited.txt diff --git a/cpukit/score/include/rtems/score/onceimpl.h b/cpukit/score/include/rtems/score/onceimpl.h new file mode 100644 index 0000000000..d81f1d0b31 --- /dev/null +++ b/cpukit/score/include/rtems/score/onceimpl.h @@ -0,0 +1,48 @@ +/** + * @file + * + * @ingroup ScoreOnce + * + * @brief Once API + */ + +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_ONCE_H +#define _RTEMS_ONCE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup ScoreOnce Once Functions. + * + * @ingroup Score + * + * @brief The _Once() function for pthread_once() and rtems_gxx_once(). + * + * @{ + */ + +int _Once( int *once_state, void (*init_routine)(void) ); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_ONCE_H */ diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index bb6508c7d3..68ded43c0b 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -147,6 +147,10 @@ $(PROJECT_INCLUDE)/rtems/score/objectimpl.h: include/rtems/score/objectimpl.h $( $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/objectimpl.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/objectimpl.h +$(PROJECT_INCLUDE)/rtems/score/onceimpl.h: include/rtems/score/onceimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/onceimpl.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/onceimpl.h + $(PROJECT_INCLUDE)/rtems/score/percpu.h: include/rtems/score/percpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/percpu.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/percpu.h diff --git a/cpukit/score/src/once.c b/cpukit/score/src/once.c new file mode 100644 index 0000000000..60ae7a78c4 --- /dev/null +++ b/cpukit/score/src/once.c @@ -0,0 +1,56 @@ +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +#include + +#define ONCE_STATE_NOT_RUN 0 +#define ONCE_STATE_RUNNING 1 +#define ONCE_STATE_COMPLETE 2 + +int _Once( int *once_state, void ( *init_routine )( void ) ) +{ + int eno = 0; + + if ( *once_state != ONCE_STATE_COMPLETE ) { + _Once_Lock(); + + /* + * Getting to here means the once_control is locked so we have: + * 1. The init has not run and the state is ONCE_STATE_NOT_RUN. + * 2. The init has finished and the state is ONCE_STATE_COMPLETE (already + * caught by the previous if). + * 3. The init is being run by this thread and the state + * ONCE_STATE_RUNNING so we are nesting. This is an error. + */ + + switch ( *once_state ) { + case ONCE_STATE_NOT_RUN: + *once_state = ONCE_STATE_RUNNING; + ( *init_routine )(); + *once_state = ONCE_STATE_COMPLETE; + break; + case ONCE_STATE_RUNNING: + eno = EINVAL; + break; + default: + break; + } + + _Once_Unlock(); + } + + return eno; +} -- cgit v1.2.3