[PATCH 2/3] score: Add Beacon Handler
Sebastian Huber
sebastian.huber at embedded-brains.de
Tue Oct 16 14:45:28 UTC 2012
A Beacon is a synchronization primitive which helps to solve simple
request handling by asynchronous mechanisms like interrupts or other
tasks. The Beacon is available for every task similar to the Events.
---
cpukit/rtems/Makefile.am | 4 +
cpukit/rtems/include/rtems.h | 2 +-
cpukit/rtems/include/rtems/rtems/beacon.h | 182 ++++++++++++++++++++++++
cpukit/rtems/include/rtems/rtems/tasks.h | 3 +
cpukit/rtems/preinstall.am | 4 +
cpukit/rtems/src/beacon.c | 105 ++++++++++++++
cpukit/rtems/src/tasks.c | 2 +
cpukit/score/Makefile.am | 5 +
cpukit/score/include/rtems/score/beacon-impl.h | 145 +++++++++++++++++++
cpukit/score/include/rtems/score/beacon.h | 50 +++++++
cpukit/score/include/rtems/score/states.h | 3 +
cpukit/score/inline/rtems/score/states.inl | 15 ++
cpukit/score/preinstall.am | 8 +
cpukit/score/src/beacon.c | 53 +++++++
doc/ada_user/ada_user.texi | 2 +
doc/user/Makefile.am | 12 ++-
doc/user/beacon.t | 107 ++++++++++++++
doc/user/c_user.texi | 2 +
testsuites/sptests/Makefile.am | 1 +
testsuites/sptests/configure.ac | 1 +
testsuites/sptests/spbeacon01/Makefile.am | 19 +++
testsuites/sptests/spbeacon01/init.c | 111 ++++++++++++++
testsuites/sptests/spbeacon01/spbeacon01.doc | 13 ++
testsuites/sptests/spbeacon01/spbeacon01.scn | 2 +
24 files changed, 847 insertions(+), 4 deletions(-)
create mode 100644 cpukit/rtems/include/rtems/rtems/beacon.h
create mode 100644 cpukit/rtems/src/beacon.c
create mode 100644 cpukit/score/include/rtems/score/beacon-impl.h
create mode 100644 cpukit/score/include/rtems/score/beacon.h
create mode 100644 cpukit/score/src/beacon.c
create mode 100644 doc/user/beacon.t
create mode 100644 testsuites/sptests/spbeacon01/Makefile.am
create mode 100644 testsuites/sptests/spbeacon01/init.c
create mode 100644 testsuites/sptests/spbeacon01/spbeacon01.doc
create mode 100644 testsuites/sptests/spbeacon01/spbeacon01.scn
diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am
index bbf8611..6fc398c 100644
--- a/cpukit/rtems/Makefile.am
+++ b/cpukit/rtems/Makefile.am
@@ -17,6 +17,7 @@ include_rtems_rtems_HEADERS =
include_rtems_rtems_HEADERS += include/rtems/rtems/asr.h
include_rtems_rtems_HEADERS += include/rtems/rtems/attr.h
include_rtems_rtems_HEADERS += include/rtems/rtems/barrier.h
+include_rtems_rtems_HEADERS += include/rtems/rtems/beacon.h
include_rtems_rtems_HEADERS += include/rtems/rtems/cache.h
include_rtems_rtems_HEADERS += include/rtems/rtems/clock.h
include_rtems_rtems_HEADERS += include/rtems/rtems/config.h
@@ -136,6 +137,9 @@ librtems_a_SOURCES += src/ratemondata.c
librtems_a_SOURCES += src/intrbody.c
librtems_a_SOURCES += src/intrcatch.c
+## BEACON_C_FILES
+librtems_a_SOURCES += src/beacon.c
+
## BARRIER_C_FILES
librtems_a_SOURCES += src/barrier.c
librtems_a_SOURCES += src/barriercreate.c
diff --git a/cpukit/rtems/include/rtems.h b/cpukit/rtems/include/rtems.h
index 68c6a0b..653160d 100644
--- a/cpukit/rtems/include/rtems.h
+++ b/cpukit/rtems/include/rtems.h
@@ -60,8 +60,8 @@ extern "C" {
#include <rtems/rtems/sem.h>
#include <rtems/rtems/message.h>
#include <rtems/rtems/event.h>
+#include <rtems/rtems/beacon.h>
#include <rtems/rtems/signal.h>
-#include <rtems/rtems/event.h>
#include <rtems/rtems/object.h>
#include <rtems/rtems/part.h>
#include <rtems/rtems/region.h>
diff --git a/cpukit/rtems/include/rtems/rtems/beacon.h b/cpukit/rtems/include/rtems/rtems/beacon.h
new file mode 100644
index 0000000..3e8e07c
--- /dev/null
+++ b/cpukit/rtems/include/rtems/rtems/beacon.h
@@ -0,0 +1,182 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicBeacon
+ *
+ * @brief Classic Beacon API.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_RTEMS_BEACON_H
+#define _RTEMS_RTEMS_BEACON_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ClassicBeacon Beacon
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * A Beacon is a synchronization primitive which helps to solve simple request
+ * handling by asynchronous mechanisms like interrupts or other tasks. The
+ * Beacon is available for every task similar to the Events.
+ *
+ * @msc
+ * hscale="1.6";
+ * M [label="Main Task"], IDLE [label="Idle Task"], IRQ [label="Interrupt Handler"], TIME [label="System Tick Handler"];
+ * |||;
+ * --- [label="sequence with request completion"];
+ * M box M [label="prepare request\nissue request\ncall rtems_beacon_watch()"];
+ * M=>>IDLE [label="blocking operation"];
+ * IDLE=>>IRQ [label="request completion event"];
+ * IRQ box IRQ [label="finish request\ncall rtems_beacon_signal()"];
+ * IRQ=>>M [label="task is ready again"];
+ * M box M [label="clean up request\ncall rtems_beacon_clear()"];
+ * |||;
+ * --- [label="sequence with early request completion"];
+ * M box M [label="prepare request\nissue request"];
+ * M=>>IRQ [label="request completion event"];
+ * IRQ box IRQ [label="finish request\ncall rtems_beacon_signal()"];
+ * IRQ=>>M [label="beacon is now signalled"];
+ * M box M [label="call rtems_beacon_watch()\nclean up request\ncall rtems_beacon_clear()"];
+ * |||;
+ * --- [label="sequence with timeout event"];
+ * M box M [label="prepare request\nissue request\ncall rtems_beacon_watch()"];
+ * M=>>IDLE [label="blocking operation"];
+ * IDLE=>>TIME [label="timeout expired"];
+ * TIME box TIME [label="cancel blocking operation"];
+ * TIME=>>M [label="task is ready again"];
+ * M box M [label="cancel request\ncall rtems_beacon_clear()"];
+ * @endmsc
+ *
+ * Suppose you have a task that wants to issue a certain request and then waits
+ * for request completion. It can create a request structure and store its
+ * task identifier there. Now it can place the request on a work queue of
+ * another task (or interrupt handler). Afterwards the task watches for the
+ * beacon to get signalled. Once the worker task is finished with the request
+ * it can signal the beacon.
+ *
+ * @code
+ * #include <assert.h>
+ * #include <rtems.h>
+ *
+ * typedef struct {
+ * rtems_id task_id;
+ * bool work_done;
+ * } request;
+ *
+ * void worker_task(rtems_task_argument arg)
+ * {
+ * rtems_status_code sc;
+ * request *req = (request *) arg;
+ *
+ * req->work_done = true;
+ *
+ * sc = rtems_beacon_signal(req->task_id);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_task_delete(RTEMS_SELF);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ * }
+ *
+ * void issue_request_and_wait_for_completion(void)
+ * {
+ * rtems_status_code sc;
+ * rtems_id id;
+ * request req;
+ *
+ * req.task_id = rtems_task_self();
+ * req.work_done = false;
+ *
+ * sc = rtems_task_create(
+ * rtems_build_name('W', 'O', 'R', 'K'),
+ * 1,
+ * RTEMS_MINIMUM_STACK_SIZE,
+ * RTEMS_DEFAULT_MODES,
+ * RTEMS_DEFAULT_ATTRIBUTES,
+ * &id
+ * );
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_task_start(id, worker_task, (rtems_task_argument) &req);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_beacon_watch(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * assert(req.work_done);
+ *
+ * sc = rtems_beacon_clear();
+ * assert(sc == RTEMS_SUCCESSFUL);
+ * }
+ * @endcode
+ *
+ * @{
+ */
+
+/**
+ * @brief Clears the beacon of the executing task.
+ *
+ * @retval RTEMS_SUCCESSFUL Operation successful.
+ */
+rtems_status_code rtems_beacon_clear( void );
+
+/**
+ * @brief Signals the beacon of the corresponding task.
+ *
+ * @param[in] task_id Task identifier selecting the beacon.
+ *
+ * @retval RTEMS_SUCCESSFUL Operation successful.
+ * @retval RTEMS_INVALID_ID Invalid task identifier.
+ * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Not implemented on remote objects.
+ */
+rtems_status_code rtems_beacon_signal( rtems_id task_id );
+
+/**
+ * @brief Watches the beacon of the executing task to get signalled.
+ *
+ * After a timeout the request must be cancelled. The request handler must not
+ * call rtems_beacon_signal() afterwards.
+ *
+ * The beacon must be cleared with rtems_beacon_clear() after request
+ * completion or cancellation. It is a fatal program error to leave the beacon
+ * in a potentially signalled state.
+ *
+ * @param[in] option_set Supported options are RTEMS_NO_WAIT to not wait for
+ * the signal and RTEMS_WAIT to wait for the signal.
+ * @param[in] ticks If the RTEMS_WAIT option is set, then this is the timeout
+ * in ticks. Use RTEMS_NO_TIMEOUT to wait forever.
+ *
+ * @retval RTEMS_SUCCESSFUL Operation successful.
+ * @retval RTEMS_UNSATISFIED The beacon is not signalled.
+ * @retval RTEMS_TIMEOUT Operation timed out. The beacon state is undefined.
+ */
+rtems_status_code rtems_beacon_watch(
+ rtems_option option_set,
+ rtems_interval ticks
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_RTEMS_BEACON_H */
diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
index b6f51a1..b14ca92 100644
--- a/cpukit/rtems/include/rtems/rtems/tasks.h
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -37,6 +37,7 @@
#include <rtems/score/object.h>
#include <rtems/score/states.h>
#include <rtems/score/thread.h>
+#include <rtems/score/beacon.h>
#include <rtems/rtems/types.h>
#include <rtems/rtems/eventset.h>
#include <rtems/rtems/asr.h>
@@ -216,6 +217,8 @@ typedef struct {
rtems_event_set event_condition;
/** This field contains the Classic API Signal information for this task. */
ASR_Information Signal;
+ /** This field contains the Classic API Beacon control for this task. */
+ Beacon_Control Beacon;
/**
* This field contains the notepads for this task.
*
diff --git a/cpukit/rtems/preinstall.am b/cpukit/rtems/preinstall.am
index c91e508..be266b7 100644
--- a/cpukit/rtems/preinstall.am
+++ b/cpukit/rtems/preinstall.am
@@ -39,6 +39,10 @@ $(PROJECT_INCLUDE)/rtems/rtems/barrier.h: include/rtems/rtems/barrier.h $(PROJEC
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/barrier.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/barrier.h
+$(PROJECT_INCLUDE)/rtems/rtems/beacon.h: include/rtems/rtems/beacon.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/beacon.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/beacon.h
+
$(PROJECT_INCLUDE)/rtems/rtems/cache.h: include/rtems/rtems/cache.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/cache.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/cache.h
diff --git a/cpukit/rtems/src/beacon.c b/cpukit/rtems/src/beacon.c
new file mode 100644
index 0000000..ed6a7c9
--- /dev/null
+++ b/cpukit/rtems/src/beacon.c
@@ -0,0 +1,105 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicBeacon
+ *
+ * @brief Classic Beacon implementation.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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.com/license/LICENSE.
+ */
+
+#include <rtems/rtems/beacon.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/beacon-impl.h>
+
+RTEMS_STATIC_ASSERT(
+ (uint32_t) RTEMS_SUCCESSFUL == (uint32_t) BEACON_STATUS_SUCCESSFUL,
+ beacon_status_successful
+);
+
+RTEMS_STATIC_ASSERT(
+ (uint32_t) RTEMS_TIMEOUT == (uint32_t) BEACON_STATUS_TIMEOUT,
+ beacon_status_timeout
+);
+
+RTEMS_STATIC_ASSERT(
+ (uint32_t) RTEMS_UNSATISFIED == (uint32_t) BEACON_STATUS_UNSATISFIED,
+ beacon_status_unsatisfied
+);
+
+static rtems_status_code translate_beacon_status_code( Beacon_Status status )
+{
+ return (rtems_status_code) status;
+}
+
+rtems_status_code rtems_beacon_clear( void )
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ Thread_Control *executing = _Thread_Executing;
+ RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
+
+ _Beacon_Initialize( &api->Beacon );
+
+ return sc;
+}
+
+rtems_status_code rtems_beacon_signal( rtems_id task_id )
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ Objects_Locations location;
+ Thread_Control *thread;
+ RTEMS_API_Control *api;
+
+ thread = _Thread_Get( task_id, &location );
+
+ switch ( location ) {
+ case OBJECTS_LOCAL:
+ api = thread->API_Extensions[ THREAD_API_RTEMS ];
+ _Beacon_Signal( thread, &api->Beacon );
+ break;
+#ifdef RTEMS_MULTIPROCESSING
+ case OBJECTS_REMOTE:
+ sc = RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+ break;
+#endif
+ default:
+ sc = RTEMS_INVALID_ID;
+ break;
+ }
+
+ _Thread_Enable_dispatch();
+
+ return sc;
+}
+
+rtems_status_code rtems_beacon_watch(
+ rtems_option option_set,
+ rtems_interval ticks
+)
+{
+ Thread_Control *executing = _Thread_Executing;
+ RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
+
+ _Thread_Disable_dispatch();
+ _Beacon_Watch(
+ !_Options_Is_no_wait( option_set ),
+ ticks,
+ executing,
+ &api->Beacon
+ );
+ _Thread_Enable_dispatch();
+
+ return translate_beacon_status_code( executing->Wait.return_code );
+}
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
index 663a02c..0fb2102 100644
--- a/cpukit/rtems/src/tasks.c
+++ b/cpukit/rtems/src/tasks.c
@@ -29,6 +29,7 @@
#include <rtems/score/wkspace.h>
#include <rtems/score/apiext.h>
#include <rtems/score/sysstate.h>
+#include <rtems/score/beacon-impl.h>
/*
* _RTEMS_tasks_Create_extension
@@ -67,6 +68,7 @@ static bool _RTEMS_tasks_Create_extension(
api->pending_events = EVENT_SETS_NONE_PENDING;
api->event_condition = 0;
_ASR_Initialize( &api->Signal );
+ _Beacon_Initialize( &api->Beacon );
created->task_variables = NULL;
if ( rtems_configuration_get_notepads_enabled() ) {
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 6f9f94f..282a3c6 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -17,6 +17,8 @@ include_rtems_scoredir = $(includedir)/rtems/score
include_rtems_score_HEADERS = include/rtems/score/address.h
include_rtems_score_HEADERS += include/rtems/score/apiext.h
include_rtems_score_HEADERS += include/rtems/score/apimutex.h
+include_rtems_score_HEADERS += include/rtems/score/beacon.h
+include_rtems_score_HEADERS += include/rtems/score/beacon-impl.h
include_rtems_score_HEADERS += include/rtems/score/bitfield.h
include_rtems_score_HEADERS += include/rtems/score/chain.h
include_rtems_score_HEADERS += include/rtems/score/context.h
@@ -144,6 +146,9 @@ libscore_a_SOURCES += src/apimutex.c src/apimutexallocate.c \
libscore_a_SOURCES += src/corebarrier.c src/corebarrierrelease.c \
src/corebarrierwait.c
+## BEACON_C_FILES
+libscore_a_SOURCES += src/beacon.c
+
## CORE_MESSAGE_QUEUE_C_FILES
libscore_a_SOURCES += src/coremsg.c src/coremsgbroadcast.c \
src/coremsgclose.c src/coremsgflush.c src/coremsgflushwait.c \
diff --git a/cpukit/score/include/rtems/score/beacon-impl.h b/cpukit/score/include/rtems/score/beacon-impl.h
new file mode 100644
index 0000000..d60800b
--- /dev/null
+++ b/cpukit/score/include/rtems/score/beacon-impl.h
@@ -0,0 +1,145 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreBeacon
+ *
+ * @brief Beacon Handler implementation API.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_BEACON_IMPL_H
+#define _RTEMS_SCORE_BEACON_IMPL_H
+
+#include <rtems/score/beacon.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreBeacon
+ *
+ * @{
+ */
+
+typedef enum {
+ BEACON_STATUS_SUCCESSFUL = 0,
+ BEACON_STATUS_TIMEOUT = 6,
+ BEACON_STATUS_UNSATISFIED = 13
+} Beacon_Status;
+
+extern Thread_blocking_operation_States _Beacon_Sync_state;
+
+RTEMS_INLINE_ROUTINE void _Beacon_Handler_initialization( void )
+{
+ /* Do nothing */
+}
+
+RTEMS_INLINE_ROUTINE void _Beacon_Initialize( Beacon_Control *beacon )
+{
+ beacon->on_fire = false;
+}
+
+RTEMS_INLINE_ROUTINE void _Beacon_Signal(
+ Thread_Control *thread,
+ Beacon_Control *beacon
+)
+{
+ ISR_Level level;
+
+ beacon->on_fire = true;
+
+ _ISR_Disable( level );
+ if (
+ _Thread_blocking_operation_Is_critical( thread, _Beacon_Sync_state )
+ ) {
+ _Beacon_Sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
+ _ISR_Enable( level );
+ } else if ( _States_Is_waiting_for_beacon( thread->current_state ) ) {
+ _ISR_Flash( level );
+
+ if ( !_Watchdog_Is_active( &thread->Timer ) ) {
+ _ISR_Enable( level );
+ } else {
+ _Watchdog_Deactivate( &thread->Timer );
+ _ISR_Enable( level );
+ _Watchdog_Remove( &thread->Timer );
+ }
+
+ _Thread_Unblock( thread );
+ } else {
+ _ISR_Enable( level );
+ }
+}
+
+void _Beacon_Timeout( Objects_Id task_id, void *arg );
+
+RTEMS_INLINE_ROUTINE void _Beacon_Watch(
+ bool wait,
+ Watchdog_Interval ticks,
+ Thread_Control *thread,
+ const Beacon_Control *beacon
+)
+{
+ ISR_Level level;
+
+ thread->Wait.return_code = BEACON_STATUS_SUCCESSFUL;
+
+ _ISR_Disable( level );
+ if ( beacon->on_fire ) {
+ _ISR_Enable( level );
+ } else {
+ if ( wait ) {
+ Thread_blocking_operation_States sync_state;
+
+ _Beacon_Sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
+ _ISR_Enable( level );
+
+ if ( ticks > 0) {
+ _Watchdog_Initialize(
+ &thread->Timer,
+ _Beacon_Timeout,
+ thread->Object.id,
+ NULL
+ );
+ _Watchdog_Insert_ticks( &thread->Timer, ticks );
+ }
+
+ _Thread_Set_state( thread, STATES_WAITING_FOR_BEACON );
+
+ _ISR_Disable( level );
+ sync_state = _Beacon_Sync_state;
+ _Beacon_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
+ if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
+ _ISR_Enable( level );
+ } else {
+ _Thread_blocking_operation_Cancel( sync_state, thread, level );
+ }
+ } else {
+ _ISR_Enable( level );
+ thread->Wait.return_code = BEACON_STATUS_UNSATISFIED;
+ }
+ }
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_BEACON_IMPL_H */
diff --git a/cpukit/score/include/rtems/score/beacon.h b/cpukit/score/include/rtems/score/beacon.h
new file mode 100644
index 0000000..3aaa9c0
--- /dev/null
+++ b/cpukit/score/include/rtems/score/beacon.h
@@ -0,0 +1,50 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreBeacon
+ *
+ * @brief Beacon Handler API.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_BEACON_H
+#define _RTEMS_SCORE_BEACON_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreBeacon Beacon Handler
+ *
+ * @ingroup Score
+ *
+ * @{
+ */
+
+typedef struct {
+ bool on_fire;
+} Beacon_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_BEACON_H */
diff --git a/cpukit/score/include/rtems/score/states.h b/cpukit/score/include/rtems/score/states.h
index eb4658e..8167356 100644
--- a/cpukit/score/include/rtems/score/states.h
+++ b/cpukit/score/include/rtems/score/states.h
@@ -81,6 +81,8 @@ typedef uint32_t States_Control;
#define STATES_WAITING_FOR_BARRIER 0x10000
/** This macro corresponds to a task waiting for a RWLock. */
#define STATES_WAITING_FOR_RWLOCK 0x20000
+/** This macro corresponds to a task waiting for a beacon. */
+#define STATES_WAITING_FOR_BEACON 0x40000
/** This macro corresponds to a task which is in an interruptible
* blocking state.
@@ -110,6 +112,7 @@ typedef uint32_t States_Control;
STATES_WAITING_FOR_TIME | \
STATES_WAITING_FOR_PERIOD | \
STATES_WAITING_FOR_EVENT | \
+ STATES_WAITING_FOR_BEACON | \
STATES_WAITING_ON_THREAD_QUEUE | \
STATES_INTERRUPTIBLE_BY_SIGNAL )
diff --git a/cpukit/score/inline/rtems/score/states.inl b/cpukit/score/inline/rtems/score/states.inl
index 7bad0c9..e916308 100644
--- a/cpukit/score/inline/rtems/score/states.inl
+++ b/cpukit/score/inline/rtems/score/states.inl
@@ -213,6 +213,21 @@ RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_event (
}
/**
+ * This function returns true if the WAITING_FOR_BEACON state is set in
+ * the_states, and false otherwise.
+ *
+ * @param[in] the_states is the task state set to test
+ *
+ * @return This method returns true if the desired state condition is set.
+ */
+RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_beacon (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_BEACON);
+}
+
+/**
* This function returns true if the WAITING_FOR_MUTEX state
* is set in the_states, and false otherwise.
*
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 09c6fa9..e4fa185 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -51,6 +51,14 @@ $(PROJECT_INCLUDE)/rtems/score/apimutex.h: include/rtems/score/apimutex.h $(PROJ
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/apimutex.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/apimutex.h
+$(PROJECT_INCLUDE)/rtems/score/beacon.h: include/rtems/score/beacon.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/beacon.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/beacon.h
+
+$(PROJECT_INCLUDE)/rtems/score/beacon-impl.h: include/rtems/score/beacon-impl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/beacon-impl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/beacon-impl.h
+
$(PROJECT_INCLUDE)/rtems/score/bitfield.h: include/rtems/score/bitfield.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/bitfield.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/bitfield.h
diff --git a/cpukit/score/src/beacon.c b/cpukit/score/src/beacon.c
new file mode 100644
index 0000000..530861a
--- /dev/null
+++ b/cpukit/score/src/beacon.c
@@ -0,0 +1,53 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreBeacon
+ *
+ * @brief Beacon Handler implementation.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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.com/license/LICENSE.
+ */
+
+#include <rtems/score/beacon-impl.h>
+
+Thread_blocking_operation_States _Beacon_Sync_state;
+
+void _Beacon_Timeout( Objects_Id task_id, void *arg )
+{
+ Objects_Locations location;
+ Thread_Control *thread;
+ ISR_Level level;
+
+ thread = _Thread_Get( task_id, &location );
+
+ switch ( location ) {
+ case OBJECTS_LOCAL:
+ _ISR_Disable( level );
+ if (
+ _Thread_Is_executing( thread )
+ && _Beacon_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED
+ ) {
+ _Beacon_Sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
+ }
+ thread->Wait.return_code = BEACON_STATUS_TIMEOUT;
+ _ISR_Enable( level );
+ _Thread_Unblock( thread );
+ break;
+ default:
+ break;
+ }
+
+ _Thread_Unnest_dispatch();
+}
diff --git a/doc/ada_user/ada_user.texi b/doc/ada_user/ada_user.texi
index c86b595..028156f 100644
--- a/doc/ada_user/ada_user.texi
+++ b/doc/ada_user/ada_user.texi
@@ -92,6 +92,7 @@
@include user/sem.texi
@include user/msg.texi
@include user/event.texi
+ at include user/beacon.texi
@include user/signal.texi
@include user/part.texi
@include user/region.texi
@@ -131,6 +132,7 @@
* Semaphore Manager::
* Message Manager::
* Event Manager::
+* Beacon Manager::
* Signal Manager::
* Partition Manager::
* Region Manager::
diff --git a/doc/user/Makefile.am b/doc/user/Makefile.am
index ddf2f07..f312b53 100644
--- a/doc/user/Makefile.am
+++ b/doc/user/Makefile.am
@@ -15,7 +15,7 @@ GENERATED_FILES = overview.texi concepts.texi datatypes.texi init.texi \
signal.texi part.texi region.texi dpmem.texi io.texi fatal.texi \
schedule.texi rtmon.texi barrier.texi bsp.texi userext.texi conf.texi \
mp.texi stackchk.texi cpuuse.texi object.texi chains.texi timespec.texi \
- cbs.texi
+ cbs.texi beacon.texi
COMMON_FILES += $(top_srcdir)/common/cpright.texi
@@ -109,10 +109,16 @@ event.texi: event.t
$(BMENU2) \
-p "Message Manager MESSAGE_QUEUE_FLUSH - Flush all messages on a queue" \
-u "Top" \
+ -n "Beacon Manager" < $< > $@
+
+beacon.texi: beacon.t
+ $(BMENU2) \
+ -p "Event Manager EVENT_RECEIVE - Receive event condition" \
+ -u "Top" \
-n "Signal Manager" < $< > $@
signal.texi: signal.t
- $(BMENU2) -p "Event Manager EVENT_RECEIVE - Receive event condition" \
+ $(BMENU2) -p "Beacon Manager BEACON_WATCH - Watch a beacon" \
-u "Top" \
-n "Partition Manager" < $< > $@
@@ -196,7 +202,7 @@ cbs.texi: cbs.t
EXTRA_DIST = bsp.t cbs.t clock.t chains.t concepts.t cpuuse.t datatypes.t conf.t \
dpmem.t event.t fatal.t init.t intr.t io.t mp.t msg.t overview.t \
part.t region.t rtmon.t sem.t schedule.t signal.t stackchk.t \
- task.t timer.t userext.t $(TXT_FILES) $(PNG_FILES) $(EPS_IMAGES) \
+ task.t timer.t userext.t beacon.t $(TXT_FILES) $(PNG_FILES) $(EPS_IMAGES) \
$(noinst_DATA)
CLEANFILES += c_user.info c_user.info-? c_user.info-??
diff --git a/doc/user/beacon.t b/doc/user/beacon.t
new file mode 100644
index 0000000..8afd9cf
--- /dev/null
+++ b/doc/user/beacon.t
@@ -0,0 +1,107 @@
+ at c Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+
+ at chapter Beacon Manager
+
+ at cindex beacon
+
+ at section Introduction
+
+A beacon is a synchronization primitive which helps to solve simple request
+handling by asynchronous mechanisms like interrupts or other tasks. The beacon
+is available for every task similar to the event manager. The directives provided by
+the beacon manager are:
+
+ at itemize @bullet
+ at item @code{@value{DIRPREFIX}beacon_clear} - Clear a beacon
+ at item @code{@value{DIRPREFIX}beacon_signal} - Signal a beacon
+ at item @code{@value{DIRPREFIX}beacon_watch} - Watch a beacon
+ at end itemize
+
+ at section Directives
+
+This section details the beacon manager's directives.
+A subsection is dedicated to each of this manager's directives
+and describes the calling sequence, related constants, usage,
+and status codes.
+
+ at c
+ at c
+ at c
+ at page
+ at subsection BEACON_CLEAR - Clear a beacon
+
+ at cindex clear a beacon
+
+ at subheading CALLING SEQUENCE:
+
+ at ifset is-C
+ at findex rtems_beacon_clear
+ at example
+rtems_status_code rtems_beacon_clear( void );
+ at end example
+ at end ifset
+
+ at subheading DIRECTIVE STATUS CODES:
+
+ at code{@value{RPREFIX}SUCCESSFUL} - Operation successful.
+
+ at subheading DESCRIPTION:
+
+This directive clears a beacon.
+
+ at c
+ at c
+ at c
+ at page
+ at subsection BEACON_SIGNAL - Signal a beacon
+
+ at cindex signal a beacon
+
+ at subheading CALLING SEQUENCE:
+
+ at ifset is-C
+ at findex rtems_beacon_signal
+ at example
+rtems_status_code rtems_beacon_signal( rtems_id task_id );
+ at end example
+ at end ifset
+
+ at subheading DIRECTIVE STATUS CODES:
+
+ at code{@value{RPREFIX}SUCCESSFUL} - Operation successful.@*
+ at code{@value{RPREFIX}INVALID_ID} - Invalid task identifier.@*
+ at code{@value{RPREFIX}ILLEGAL_ON_REMOTE_OBJECT} - Not implemented on remote objects.
+
+ at subheading DESCRIPTION:
+
+This directive signals a beacon.
+
+ at c
+ at c
+ at c
+ at page
+ at subsection BEACON_WATCH - Watch a beacon
+
+ at cindex watch a beacon
+
+ at subheading CALLING SEQUENCE:
+
+ at ifset is-C
+ at findex rtems_beacon_watch
+ at example
+rtems_status_code rtems_beacon_watch(
+ rtems_option option_set,
+ rtems_interval ticks
+);
+ at end example
+ at end ifset
+
+ at subheading DIRECTIVE STATUS CODES:
+
+ at code{@value{RPREFIX}SUCCESSFUL} - Operation successful.@*
+ at code{@value{RPREFIX}UNSATISFIED} - The beacon is not signalled.@*
+ at code{@value{RPREFIX}TIMEOUT} - Operation timed out. The beacon state is undefined.
+
+ at subheading DESCRIPTION:
+
+This directive watches a beacon.
diff --git a/doc/user/c_user.texi b/doc/user/c_user.texi
index 123ade2..4d8aa81 100644
--- a/doc/user/c_user.texi
+++ b/doc/user/c_user.texi
@@ -94,6 +94,7 @@
@include barrier.texi
@include msg.texi
@include event.texi
+ at include beacon.texi
@include signal.texi
@include part.texi
@include region.texi
@@ -133,6 +134,7 @@
* Barrier Manager::
* Message Manager::
* Event Manager::
+* Beacon Manager::
* Signal Manager::
* Partition Manager::
* Region Manager::
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index 479cdf6..cd06657 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -28,6 +28,7 @@ SUBDIRS = \
spsimplesched01 spsimplesched02 spsimplesched03 spnsext01 \
spedfsched01 spedfsched02 spedfsched03 \
spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01
+SUBDIRS += spbeacon01
include $(top_srcdir)/../automake/subdirs.am
include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index 33a0755..e9a1acf 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -27,6 +27,7 @@ AC_CHECK_SIZEOF([time_t])
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile
+spbeacon01/Makefile
spintrcritical18/Makefile
sp01/Makefile
sp02/Makefile
diff --git a/testsuites/sptests/spbeacon01/Makefile.am b/testsuites/sptests/spbeacon01/Makefile.am
new file mode 100644
index 0000000..55b2cf8
--- /dev/null
+++ b/testsuites/sptests/spbeacon01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = spbeacon01
+spbeacon01_SOURCES = init.c
+
+dist_rtems_tests_DATA = spbeacon01.scn spbeacon01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(spbeacon01_OBJECTS)
+LINK_LIBS = $(spbeacon01_LDLIBS)
+
+spbeacon01$(EXEEXT): $(spbeacon01_OBJECTS) $(spbeacon01_DEPENDENCIES)
+ @rm -f spbeacon01$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/spbeacon01/init.c b/testsuites/sptests/spbeacon01/init.c
new file mode 100644
index 0000000..9ee06f1
--- /dev/null
+++ b/testsuites/sptests/spbeacon01/init.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tmacros.h"
+
+typedef struct {
+ rtems_id client;
+ bool complete;
+} request;
+
+static void request_handler_task(rtems_task_argument arg)
+{
+ rtems_status_code sc;
+ request *req = (request *) arg;
+
+ req->complete = true;
+
+ sc = rtems_beacon_signal(req->client);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_delete(RTEMS_SELF);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_with_request_handler_task(void)
+{
+ rtems_status_code sc;
+ rtems_id id;
+ request req;
+
+ sc = rtems_beacon_watch(RTEMS_NO_WAIT, 0);
+ rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+ req.client = rtems_task_self();
+ req.complete = false;
+
+ sc = rtems_task_create(
+ rtems_build_name('B', 'E', 'A', 'C'),
+ 1,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(id, request_handler_task, (rtems_task_argument) &req);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_beacon_watch(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ rtems_test_assert(req.complete);
+
+ sc = rtems_beacon_clear();
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_with_timeout(void)
+{
+ rtems_status_code sc;
+
+ sc = rtems_beacon_watch(RTEMS_NO_WAIT, 0);
+ rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+ sc = rtems_beacon_watch(RTEMS_WAIT, 1);
+ rtems_test_assert(sc == RTEMS_TIMEOUT);
+
+ sc = rtems_beacon_watch(RTEMS_NO_WAIT, 0);
+ rtems_test_assert(sc == RTEMS_UNSATISFIED);
+}
+
+static void Init(rtems_task_argument arg)
+{
+ puts("\n\n*** TEST SPBEACON 1 ***");
+
+ test_with_request_handler_task();
+ test_with_timeout();
+
+ puts("*** END OF TEST SPBEACON 1 ***");
+
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/spbeacon01/spbeacon01.doc b/testsuites/sptests/spbeacon01/spbeacon01.doc
new file mode 100644
index 0000000..3e0288a
--- /dev/null
+++ b/testsuites/sptests/spbeacon01/spbeacon01.doc
@@ -0,0 +1,13 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: spbeacon01
+
+directives:
+
+ - rtems_beacon_signal()
+ - rtems_beacon_watch()
+ - rtems_beacon_clear()
+
+concepts:
+
+ Ensure that the Classic Beacon works.
diff --git a/testsuites/sptests/spbeacon01/spbeacon01.scn b/testsuites/sptests/spbeacon01/spbeacon01.scn
new file mode 100644
index 0000000..368d959
--- /dev/null
+++ b/testsuites/sptests/spbeacon01/spbeacon01.scn
@@ -0,0 +1,2 @@
+*** TEST SPBEACON 1 ***
+*** END OF TEST SPBEACON 1 ***
--
1.7.7
More information about the devel
mailing list