diff options
Diffstat (limited to 'cpukit/score')
-rw-r--r-- | cpukit/score/Makefile.am | 2 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/onceimpl.h | 48 | ||||
-rw-r--r-- | cpukit/score/preinstall.am | 4 | ||||
-rw-r--r-- | cpukit/score/src/once.c | 56 |
4 files changed, 110 insertions, 0 deletions
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 + * <rtems@embedded-brains.de> + * + * 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 <rtems/score/onceimpl.h> +#include <rtems/score/apimutex.h> + +#include <errno.h> + +#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; +} |