[PATCH 8/8] score: Implement fine-grained locking for events
Sebastian Huber
sebastian.huber at embedded-brains.de
Wed Mar 4 15:07:08 UTC 2015
Use the ISR lock of the thread object to protect the event state and
use the Giant lock only for the blocking operations.
Update #2273.
---
cpukit/rtems/Makefile.am | 1 -
cpukit/rtems/include/rtems/rtems/eventimpl.h | 49 +++-------
cpukit/rtems/src/event.c | 3 -
cpukit/rtems/src/eventdata.c | 23 -----
cpukit/rtems/src/eventreceive.c | 13 +--
cpukit/rtems/src/eventseize.c | 77 +++++++--------
cpukit/rtems/src/eventsend.c | 8 +-
cpukit/rtems/src/eventsurrender.c | 139 ++++++++++++++++-----------
cpukit/rtems/src/eventtimeout.c | 90 +++++++++--------
cpukit/rtems/src/systemeventreceive.c | 13 +--
cpukit/rtems/src/systemeventsend.c | 8 +-
cpukit/rtems/src/tasks.c | 2 -
testsuites/sptests/spintrcritical10/init.c | 64 ++++++------
testsuites/sptests/spintrcritical21/init.c | 14 ++-
testsuites/sptests/spsize/size.c | 2 -
15 files changed, 254 insertions(+), 252 deletions(-)
delete mode 100644 cpukit/rtems/src/eventdata.c
diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am
index a1fafb1..5e6f2ea 100644
--- a/cpukit/rtems/Makefile.am
+++ b/cpukit/rtems/Makefile.am
@@ -211,7 +211,6 @@ librtems_a_SOURCES += src/eventseize.c
librtems_a_SOURCES += src/eventsend.c
librtems_a_SOURCES += src/eventsurrender.c
librtems_a_SOURCES += src/eventtimeout.c
-librtems_a_SOURCES += src/eventdata.c
librtems_a_SOURCES += src/systemeventsend.c
librtems_a_SOURCES += src/systemeventreceive.c
diff --git a/cpukit/rtems/include/rtems/rtems/eventimpl.h b/cpukit/rtems/include/rtems/rtems/eventimpl.h
index 60b6b51..460b7ce 100644
--- a/cpukit/rtems/include/rtems/rtems/eventimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/eventimpl.h
@@ -33,16 +33,6 @@ extern "C" {
*/
/**
- * This constant is defined to extern most of the time when using
- * this header file. However by defining it to nothing, the data
- * declared in this header file can be instantiated. This is done
- * in a single per manager file.
- */
-#ifndef RTEMS_EVENT_EXTERN
-#define RTEMS_EVENT_EXTERN extern
-#endif
-
-/**
* This constant is passed as the event_in to the
* rtems_event_receive directive to determine which events are pending.
*/
@@ -54,10 +44,6 @@ extern "C" {
*/
#define EVENT_SETS_NONE_PENDING 0
-RTEMS_EVENT_EXTERN Thread_blocking_operation_States _Event_Sync_state;
-
-RTEMS_EVENT_EXTERN Thread_blocking_operation_States _System_event_Sync_state;
-
/**
* @brief Event Manager Initialization
*
@@ -71,30 +57,23 @@ RTEMS_EVENT_EXTERN Thread_blocking_operation_States _System_event_Sync_state;
void _Event_Manager_initialization( void );
void _Event_Seize(
- rtems_event_set event_in,
- rtems_option option_set,
- rtems_interval ticks,
- rtems_event_set *event_out,
- Thread_Control *executing,
- Event_Control *event,
- Thread_blocking_operation_States *sync_state,
- States_Control wait_state
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out,
+ Thread_Control *executing,
+ Event_Control *event,
+ Thread_Wait_flags wait_class,
+ States_Control block_state,
+ ISR_lock_Context *lock_context
);
-/**
- * @brief Surrender Event
- *
- * - INTERRUPT LATENCY:
- * + before flash
- * + after flash
- * + check sync
- */
void _Event_Surrender(
- Thread_Control *the_thread,
- rtems_event_set event_in,
- Event_Control *event,
- Thread_blocking_operation_States *sync_state,
- States_Control wait_state
+ Thread_Control *the_thread,
+ rtems_event_set event_in,
+ Event_Control *event,
+ Thread_Wait_flags wait_class,
+ ISR_lock_Context *lock_context
);
/**
diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c
index 3a1359e..7ec44d7 100644
--- a/cpukit/rtems/src/event.c
+++ b/cpukit/rtems/src/event.c
@@ -22,9 +22,6 @@
void _Event_Manager_initialization( void )
{
- _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
- _System_event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
-
/*
* Register the MP Process Packet routine.
*/
diff --git a/cpukit/rtems/src/eventdata.c b/cpukit/rtems/src/eventdata.c
deleted file mode 100644
index 93fa473..0000000
--- a/cpukit/rtems/src/eventdata.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * @file
- *
- * @brief Instantiate RTEMS Event Data
- * @ingroup ClassicEvent
- */
-
-/*
- * COPYRIGHT (c) 1989-2007.
- * 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.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define RTEMS_EVENT_EXTERN
-
-#include <rtems/rtems/eventimpl.h>
diff --git a/cpukit/rtems/src/eventreceive.c b/cpukit/rtems/src/eventreceive.c
index 49fdb2a..07e1c57 100644
--- a/cpukit/rtems/src/eventreceive.c
+++ b/cpukit/rtems/src/eventreceive.c
@@ -21,7 +21,7 @@
#include <rtems/rtems/eventimpl.h>
#include <rtems/rtems/tasks.h>
#include <rtems/score/statesimpl.h>
-#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadimpl.h>
rtems_status_code rtems_event_receive(
rtems_event_set event_in,
@@ -33,12 +33,12 @@ rtems_status_code rtems_event_receive(
rtems_status_code sc;
if ( event_out != NULL ) {
- Thread_Control *executing = _Thread_Get_executing();
+ ISR_lock_Context lock_context;
+ Thread_Control *executing = _Thread_Acquire_executing( &lock_context );
RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
Event_Control *event = &api->Event;
if ( !_Event_sets_Is_empty( event_in ) ) {
- _Thread_Disable_dispatch();
_Event_Seize(
event_in,
option_set,
@@ -46,14 +46,15 @@ rtems_status_code rtems_event_receive(
event_out,
executing,
event,
- &_Event_Sync_state,
- STATES_WAITING_FOR_EVENT
+ THREAD_WAIT_CLASS_EVENT,
+ STATES_WAITING_FOR_EVENT,
+ &lock_context
);
- _Thread_Enable_dispatch();
sc = executing->Wait.return_code;
} else {
*event_out = event->pending_events;
+ _Objects_Release_and_ISR_enable( &executing->Object, &lock_context );
sc = RTEMS_SUCCESSFUL;
}
} else {
diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c
index ca7c111..59a2b62 100644
--- a/cpukit/rtems/src/eventseize.c
+++ b/cpukit/rtems/src/eventseize.c
@@ -31,24 +31,25 @@
*/
void _Event_Seize(
- rtems_event_set event_in,
- rtems_option option_set,
- rtems_interval ticks,
- rtems_event_set *event_out,
- Thread_Control *executing,
- Event_Control *event,
- Thread_blocking_operation_States *sync_state,
- States_Control wait_state
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out,
+ Thread_Control *executing,
+ Event_Control *event,
+ Thread_Wait_flags wait_class,
+ States_Control block_state,
+ ISR_lock_Context *lock_context
)
{
- rtems_event_set seized_events;
- rtems_event_set pending_events;
- ISR_Level level;
- Thread_blocking_operation_States current_sync_state;
+ rtems_event_set seized_events;
+ rtems_event_set pending_events;
+ bool success;
+ Thread_Wait_flags intend_to_block;
+ Per_CPU_Control *cpu_self;
executing->Wait.return_code = RTEMS_SUCCESSFUL;
- _ISR_Disable( level );
pending_events = event->pending_events;
seized_events = _Event_sets_Get( pending_events, event_in );
@@ -56,18 +57,20 @@ void _Event_Seize(
(seized_events == event_in || _Options_Is_any( option_set )) ) {
event->pending_events =
_Event_sets_Clear( pending_events, seized_events );
- _ISR_Enable( level );
+ _Objects_Release_and_ISR_enable( &executing->Object, lock_context );
*event_out = seized_events;
return;
}
if ( _Options_Is_no_wait( option_set ) ) {
- _ISR_Enable( level );
+ _Objects_Release_and_ISR_enable( &executing->Object, lock_context );
executing->Wait.return_code = RTEMS_UNSATISFIED;
*event_out = seized_events;
return;
}
+ intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+
/*
* Note what we are waiting for BEFORE we enter the critical section.
* The interrupt critical section management code needs this to be
@@ -76,41 +79,39 @@ void _Event_Seize(
* NOTE: Since interrupts are disabled, this isn't that much of an
* issue but better safe than sorry.
*/
- executing->Wait.option = option_set;
- executing->Wait.count = event_in;
- executing->Wait.return_argument = event_out;
-
- *sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
+ executing->Wait.option = option_set;
+ executing->Wait.count = event_in;
+ executing->Wait.return_argument = event_out;
+ _Thread_Wait_flags_set( executing, intend_to_block );
- _ISR_Enable( level );
+ cpu_self = _Objects_Release_and_thread_dispatch_disable(
+ &executing->Object,
+ lock_context
+ );
+ _Giant_Acquire( cpu_self );
if ( ticks ) {
_Watchdog_Initialize(
&executing->Timer,
_Event_Timeout,
executing->Object.id,
- sync_state
+ NULL
);
_Watchdog_Insert_ticks( &executing->Timer, ticks );
}
- _Thread_Set_state( executing, wait_state );
+ _Thread_Set_state( executing, block_state );
- _ISR_Disable( level );
-
- current_sync_state = *sync_state;
- *sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
- if ( current_sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
- _ISR_Enable( level );
- return;
+ success = _Thread_Wait_flags_try_change(
+ executing,
+ intend_to_block,
+ wait_class | THREAD_WAIT_STATE_BLOCKED
+ );
+ if ( !success ) {
+ _Watchdog_Remove( &executing->Timer );
+ _Thread_Unblock( executing );
}
- /*
- * An interrupt completed the thread's blocking request.
- * The blocking thread was satisfied by an ISR or timed out.
- *
- * WARNING! Entering with interrupts disabled and returning with interrupts
- * enabled!
- */
- _Thread_blocking_operation_Cancel( current_sync_state, executing, level );
+ _Giant_Release( cpu_self );
+ _Thread_Dispatch_enable( cpu_self );
}
diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c
index 89bc3e1..bb9ca33 100644
--- a/cpukit/rtems/src/eventsend.c
+++ b/cpukit/rtems/src/eventsend.c
@@ -31,8 +31,9 @@ rtems_status_code rtems_event_send(
Thread_Control *thread;
Objects_Locations location;
RTEMS_API_Control *api;
+ ISR_lock_Context lock_context;
- thread = _Thread_Get( id, &location );
+ thread = _Thread_Acquire( id, &location, &lock_context );
switch ( location ) {
case OBJECTS_LOCAL:
api = thread->API_Extensions[ THREAD_API_RTEMS ];
@@ -40,10 +41,9 @@ rtems_status_code rtems_event_send(
thread,
event_in,
&api->Event,
- &_Event_Sync_state,
- STATES_WAITING_FOR_EVENT
+ THREAD_WAIT_CLASS_EVENT,
+ &lock_context
);
- _Objects_Put( &thread->Object );
sc = RTEMS_SUCCESSFUL;
break;
#ifdef RTEMS_MULTIPROCESSING
diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c
index cc33501..824912b 100644
--- a/cpukit/rtems/src/eventsurrender.c
+++ b/cpukit/rtems/src/eventsurrender.c
@@ -23,75 +23,100 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/watchdogimpl.h>
-void _Event_Surrender(
- Thread_Control *the_thread,
- rtems_event_set event_in,
- Event_Control *event,
- Thread_blocking_operation_States *sync_state,
- States_Control wait_state
+static void _Event_Satisfy(
+ Thread_Control *the_thread,
+ Event_Control *event,
+ rtems_event_set pending_events,
+ rtems_event_set seized_events
+)
+{
+ event->pending_events = _Event_sets_Clear( pending_events, seized_events );
+ *(rtems_event_set *) the_thread->Wait.return_argument = seized_events;
+}
+
+static bool _Event_Is_satisfied(
+ const Thread_Control *the_thread,
+ rtems_event_set pending_events,
+ rtems_event_set *seized_events
)
{
- ISR_Level level;
- rtems_event_set pending_events;
- rtems_event_set event_condition;
- rtems_event_set seized_events;
rtems_option option_set;
+ rtems_event_set event_condition;
option_set = the_thread->Wait.option;
+ event_condition = the_thread->Wait.count;
+ *seized_events = _Event_sets_Get( pending_events, event_condition );
- _ISR_Disable( level );
- _Event_sets_Post( event_in, &event->pending_events );
- pending_events = event->pending_events;
+ return !_Event_sets_Is_empty( *seized_events )
+ && ( *seized_events == event_condition || _Options_Is_any( option_set ) );
+}
- /*
- * At this point the event condition is a speculative quantity. Later state
- * checks will show if the thread actually waits for an event.
- */
- event_condition = the_thread->Wait.count;
+void _Event_Surrender(
+ Thread_Control *the_thread,
+ rtems_event_set event_in,
+ Event_Control *event,
+ Thread_Wait_flags wait_class,
+ ISR_lock_Context *lock_context
+)
+{
+ rtems_event_set pending_events;
+ rtems_event_set seized_events;
+ Thread_Wait_flags wait_flags;
+ bool unblock;
+
+ _Event_sets_Post( event_in, &event->pending_events );
+ pending_events = event->pending_events;
- seized_events = _Event_sets_Get( pending_events, event_condition );
+ wait_flags = _Thread_Wait_flags_get( the_thread );
if (
- !_Event_sets_Is_empty( seized_events )
- && ( seized_events == event_condition || _Options_Is_any( option_set ) )
+ ( wait_flags & THREAD_WAIT_CLASS_MASK ) == wait_class
+ && _Event_Is_satisfied( the_thread, pending_events, &seized_events )
) {
- /*
- * If we are sending to the executing thread, then we have a critical
- * section issue to deal with. The entity sending to the executing thread
- * can be either the executing thread or an ISR. In case it is the
- * executing thread, then the blocking operation state is not equal to
- * THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED.
- */
- if ( _Thread_Is_executing( the_thread ) &&
- *sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
- event->pending_events = _Event_sets_Clear(
- pending_events,
- seized_events
- );
- the_thread->Wait.count = 0;
- *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
- *sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
- } else if ( _States_Are_set( the_thread->current_state, wait_state ) ) {
- event->pending_events = _Event_sets_Clear(
- pending_events,
- seized_events
+ Thread_Wait_flags intend_to_block;
+ Thread_Wait_flags blocked;
+ bool success;
+
+ intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+ blocked = wait_class | THREAD_WAIT_STATE_BLOCKED;
+
+ success = _Thread_Wait_flags_try_change_critical(
+ the_thread,
+ intend_to_block,
+ wait_class | THREAD_WAIT_STATE_INTERRUPT_SATISFIED
+ );
+ if ( success ) {
+ _Event_Satisfy( the_thread, event, pending_events, seized_events );
+ unblock = false;
+ } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) {
+ _Event_Satisfy( the_thread, event, pending_events, seized_events );
+ _Thread_Wait_flags_set(
+ the_thread,
+ wait_class | THREAD_WAIT_STATE_SATISFIED
);
- the_thread->Wait.count = 0;
- *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
-
- _ISR_Flash( level );
-
- if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
- _ISR_Enable( level );
- _Thread_Unblock( the_thread );
- } else {
- _Watchdog_Deactivate( &the_thread->Timer );
- _ISR_Enable( level );
- (void) _Watchdog_Remove( &the_thread->Timer );
- _Thread_Unblock( the_thread );
- }
- return;
+ unblock = true;
+ } else {
+ unblock = false;
}
+ } else {
+ unblock = false;
+ }
+
+ if ( unblock ) {
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Objects_Release_and_thread_dispatch_disable(
+ &the_thread->Object,
+ lock_context
+ );
+ _Giant_Acquire( cpu_self );
+
+ _Watchdog_Remove( &the_thread->Timer );
+ _Thread_Unblock( the_thread );
+
+ _Giant_Release( cpu_self );
+ _Thread_Dispatch_enable( cpu_self );
+ } else {
+ _Objects_Release_and_ISR_enable( &the_thread->Object, lock_context );
}
- _ISR_Enable( level );
}
diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c
index 11d2f11..295f0c5 100644
--- a/cpukit/rtems/src/eventtimeout.c
+++ b/cpukit/rtems/src/eventtimeout.c
@@ -26,55 +26,61 @@ void _Event_Timeout(
void *arg
)
{
- Thread_Control *the_thread;
- Objects_Locations location;
- ISR_Level level;
- Thread_blocking_operation_States *sync_state;
+ Thread_Control *the_thread;
+ Objects_Locations location;
+ ISR_lock_Context lock_context;
+ Thread_Wait_flags wait_flags;
+ Thread_Wait_flags wait_class;
+ Thread_Wait_flags intend_to_block;
+ Thread_Wait_flags blocked;
+ bool success;
+ bool unblock;
- sync_state = arg;
-
- the_thread = _Thread_Get( id, &location );
+ the_thread = _Thread_Acquire( id, &location, &lock_context );
switch ( location ) {
-
case OBJECTS_LOCAL:
+ wait_flags = _Thread_Wait_flags_get( the_thread );
+ wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
+ intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+ blocked = wait_class | THREAD_WAIT_STATE_BLOCKED;
+ success = _Thread_Wait_flags_try_change_critical(
+ the_thread,
+ intend_to_block,
+ wait_class | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT
+ );
- /*
- * If the event manager is not synchronized, then it is either
- * "nothing happened", "timeout", or "satisfied". If the_thread
- * is the executing thread, then it is in the process of blocking
- * and it is the thread which is responsible for the synchronization
- * process.
- *
- * If it is not satisfied, then it is "nothing happened" and
- * this is the "timeout" transition. After a request is satisfied,
- * a timeout is not allowed to occur.
- */
- _ISR_Disable( level );
- /*
- * Verify that the thread is still waiting for the event condition.
- * This test is necessary to avoid state corruption if the timeout
- * happens after the event condition is satisfied in
- * _Event_Surrender(). A satisfied event condition is indicated with
- * count set to zero.
- */
- if ( !the_thread->Wait.count ) {
- _ISR_Enable( level );
- _Objects_Put_without_thread_dispatch( &the_thread->Object );
- return;
- }
+ if ( success ) {
+ the_thread->Wait.return_code = RTEMS_TIMEOUT;
+ unblock = false;
+ } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) {
+ the_thread->Wait.return_code = RTEMS_TIMEOUT;
+ _Thread_Wait_flags_set(
+ the_thread,
+ wait_class | THREAD_WAIT_STATE_TIMEOUT
+ );
+ unblock = true;
+ } else {
+ unblock = false;
+ }
- the_thread->Wait.count = 0;
- if ( _Thread_Is_executing( the_thread ) ) {
- if ( *sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
- *sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
- }
+ if ( unblock ) {
+ Per_CPU_Control *cpu_self;
- the_thread->Wait.return_code = RTEMS_TIMEOUT;
- _ISR_Enable( level );
- _Thread_Unblock( the_thread );
- _Objects_Put_without_thread_dispatch( &the_thread->Object );
- break;
+ cpu_self = _Objects_Release_and_thread_dispatch_disable(
+ &the_thread->Object,
+ &lock_context
+ );
+ _Giant_Acquire( cpu_self );
+
+ _Thread_Unblock( the_thread );
+ _Giant_Release( cpu_self );
+ _Thread_Dispatch_enable( cpu_self );
+ } else {
+ _Objects_Release_and_ISR_enable( &the_thread->Object, &lock_context );
+ }
+
+ break;
#if defined(RTEMS_MULTIPROCESSING)
case OBJECTS_REMOTE: /* impossible */
#endif
diff --git a/cpukit/rtems/src/systemeventreceive.c b/cpukit/rtems/src/systemeventreceive.c
index c24e19a..394b26e 100644
--- a/cpukit/rtems/src/systemeventreceive.c
+++ b/cpukit/rtems/src/systemeventreceive.c
@@ -27,7 +27,7 @@
#include <rtems/rtems/eventimpl.h>
#include <rtems/rtems/tasks.h>
#include <rtems/score/statesimpl.h>
-#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadimpl.h>
rtems_status_code rtems_event_system_receive(
rtems_event_set event_in,
@@ -39,12 +39,12 @@ rtems_status_code rtems_event_system_receive(
rtems_status_code sc;
if ( event_out != NULL ) {
- Thread_Control *executing = _Thread_Get_executing();
+ ISR_lock_Context lock_context;
+ Thread_Control *executing = _Thread_Acquire_executing( &lock_context );
RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
Event_Control *event = &api->System_event;
if ( !_Event_sets_Is_empty( event_in ) ) {
- _Thread_Disable_dispatch();
_Event_Seize(
event_in,
option_set,
@@ -52,14 +52,15 @@ rtems_status_code rtems_event_system_receive(
event_out,
executing,
event,
- &_System_event_Sync_state,
- STATES_WAITING_FOR_SYSTEM_EVENT
+ THREAD_WAIT_CLASS_SYSTEM_EVENT,
+ STATES_WAITING_FOR_SYSTEM_EVENT,
+ &lock_context
);
- _Thread_Enable_dispatch();
sc = executing->Wait.return_code;
} else {
*event_out = event->pending_events;
+ _Objects_Release_and_ISR_enable( &executing->Object, &lock_context );
sc = RTEMS_SUCCESSFUL;
}
} else {
diff --git a/cpukit/rtems/src/systemeventsend.c b/cpukit/rtems/src/systemeventsend.c
index b2d5552..d35127d 100644
--- a/cpukit/rtems/src/systemeventsend.c
+++ b/cpukit/rtems/src/systemeventsend.c
@@ -37,8 +37,9 @@ rtems_status_code rtems_event_system_send(
Thread_Control *thread;
Objects_Locations location;
RTEMS_API_Control *api;
+ ISR_lock_Context lock_context;
- thread = _Thread_Get( id, &location );
+ thread = _Thread_Acquire( id, &location, &lock_context );
switch ( location ) {
case OBJECTS_LOCAL:
api = thread->API_Extensions[ THREAD_API_RTEMS ];
@@ -46,10 +47,9 @@ rtems_status_code rtems_event_system_send(
thread,
event_in,
&api->System_event,
- &_System_event_Sync_state,
- STATES_WAITING_FOR_SYSTEM_EVENT
+ THREAD_WAIT_CLASS_SYSTEM_EVENT,
+ &lock_context
);
- _Objects_Put( &thread->Object );
sc = RTEMS_SUCCESSFUL;
break;
#ifdef RTEMS_MULTIPROCESSING
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
index c8c0acc..237a313 100644
--- a/cpukit/rtems/src/tasks.c
+++ b/cpukit/rtems/src/tasks.c
@@ -54,8 +54,6 @@ static bool _RTEMS_tasks_Create_extension(
api = created->API_Extensions[ THREAD_API_RTEMS ];
- _Event_Initialize( &api->Event );
- _Event_Initialize( &api->System_event );
_ASR_Create( &api->Signal );
_Thread_Action_initialize( &api->Signal_action, _Signal_Action_handler );
#if !defined(RTEMS_SMP)
diff --git a/testsuites/sptests/spintrcritical10/init.c b/testsuites/sptests/spintrcritical10/init.c
index 1d6720c..4d25ce6 100644
--- a/testsuites/sptests/spintrcritical10/init.c
+++ b/testsuites/sptests/spintrcritical10/init.c
@@ -16,6 +16,7 @@
#include <tmacros.h>
#include <intrcritical.h>
+#include <rtems/score/threadimpl.h>
#include <rtems/rtems/eventimpl.h>
const char rtems_test_name[] = "SPINTRCRITICAL 10";
@@ -34,16 +35,28 @@ typedef struct {
bool hit;
} test_context;
+static bool blocks_for_event(Thread_Wait_flags flags)
+{
+ return flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK)
+ || flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_BLOCKED);
+}
+
+static bool interrupts_blocking_op(Thread_Wait_flags flags)
+{
+ return
+ flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK);
+}
+
static void any_satisfy_before_timeout(rtems_id timer, void *arg)
{
rtems_status_code sc;
test_context *ctx = arg;
const Thread_Control *thread = ctx->thread;
+ Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
- if (thread->Wait.count != 0) {
- ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
+ if (blocks_for_event(flags)) {
+ ctx->hit = interrupts_blocking_op(flags);
- rtems_test_assert(thread->Wait.count == EVENTS);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
);
@@ -52,7 +65,6 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg)
sc = rtems_event_send(thread->Object.id, GREEN);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(thread->Wait.count == 0);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == GREEN
);
@@ -61,15 +73,13 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg)
sc = rtems_event_send(thread->Object.id, RED);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(thread->Wait.count == 0);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == GREEN
);
rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
- _Event_Timeout(thread->Object.id, &_Event_Sync_state);
+ _Event_Timeout(thread->Object.id, NULL);
- rtems_test_assert(thread->Wait.count == 0);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == GREEN
);
@@ -77,9 +87,12 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg)
if (ctx->hit) {
rtems_test_assert(
- _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED
+ _Thread_Wait_flags_get(thread)
+ == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_SATISFIED)
);
}
+
+ rtems_test_assert(thread->Wait.count == EVENTS);
}
sc = rtems_timer_reset(timer);
@@ -115,7 +128,6 @@ static void test_any_satisfy_before_timeout(test_context *ctx)
);
ctx->hit = false;
- ctx->thread->Wait.count = 0;
sc = rtems_timer_fire_after(ctx->timer, 1, any_satisfy_before_timeout, ctx);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
@@ -137,11 +149,11 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg)
rtems_status_code sc;
test_context *ctx = arg;
const Thread_Control *thread = ctx->thread;
+ Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
- if (thread->Wait.count != 0) {
- ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
+ if (blocks_for_event(flags)) {
+ ctx->hit = interrupts_blocking_op(flags);
- rtems_test_assert(thread->Wait.count == EVENTS);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
);
@@ -150,7 +162,6 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg)
sc = rtems_event_send(thread->Object.id, GREEN);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(thread->Wait.count == EVENTS);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
);
@@ -159,15 +170,13 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg)
sc = rtems_event_send(thread->Object.id, RED);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(thread->Wait.count == 0);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == EVENTS
);
rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
- _Event_Timeout(thread->Object.id, &_Event_Sync_state);
+ _Event_Timeout(thread->Object.id, NULL);
- rtems_test_assert(thread->Wait.count == 0);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == EVENTS
);
@@ -175,9 +184,12 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg)
if (ctx->hit) {
rtems_test_assert(
- _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED
+ _Thread_Wait_flags_get(thread)
+ == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_SATISFIED)
);
}
+
+ rtems_test_assert(thread->Wait.count == EVENTS);
}
sc = rtems_timer_reset(timer);
@@ -208,7 +220,6 @@ static void test_all_satisfy_before_timeout(test_context *ctx)
);
ctx->hit = false;
- ctx->thread->Wait.count = 0;
sc = rtems_timer_fire_after(ctx->timer, 1, all_satisfy_before_timeout, ctx);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
@@ -230,20 +241,18 @@ static void timeout_before_satisfied(rtems_id timer, void *arg)
rtems_status_code sc;
test_context *ctx = arg;
const Thread_Control *thread = ctx->thread;
+ Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
- if (thread->Wait.count != 0) {
- ctx->hit =
- _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
+ if (blocks_for_event(flags)) {
+ ctx->hit = interrupts_blocking_op(flags);
- rtems_test_assert(thread->Wait.count == EVENTS);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
);
rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
- _Event_Timeout(thread->Object.id, &_Event_Sync_state);
+ _Event_Timeout(thread->Object.id, NULL);
- rtems_test_assert(thread->Wait.count == 0);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
);
@@ -252,7 +261,6 @@ static void timeout_before_satisfied(rtems_id timer, void *arg)
sc = rtems_event_send(thread->Object.id, EVENTS);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(thread->Wait.count == 0);
rtems_test_assert(
*(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
);
@@ -260,9 +268,12 @@ static void timeout_before_satisfied(rtems_id timer, void *arg)
if (ctx->hit) {
rtems_test_assert(
- _Event_Sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT
+ _Thread_Wait_flags_get(thread)
+ == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT)
);
}
+
+ rtems_test_assert(thread->Wait.count == EVENTS);
}
sc = rtems_timer_reset(timer);
@@ -298,7 +309,6 @@ static void test_timeout_before_all_satisfy(test_context *ctx)
);
ctx->hit = false;
- ctx->thread->Wait.count = 0;
sc = rtems_timer_fire_after(ctx->timer, 1, timeout_before_satisfied, ctx);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
diff --git a/testsuites/sptests/spintrcritical21/init.c b/testsuites/sptests/spintrcritical21/init.c
index 8b1ddcf..faa48f7 100644
--- a/testsuites/sptests/spintrcritical21/init.c
+++ b/testsuites/sptests/spintrcritical21/init.c
@@ -18,6 +18,7 @@
#include <intrcritical.h>
+#include <rtems/score/threadimpl.h>
#include <rtems/rtems/eventimpl.h>
const char rtems_test_name[] = "SPINTRCRITICAL 21";
@@ -34,8 +35,16 @@ static volatile bool case_hit;
static rtems_id main_task;
+static Thread_Control *main_thread;
+
static rtems_id other_task;
+static bool is_case_hit( void )
+{
+ return _Thread_Wait_flags_get( main_thread)
+ == ( THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK );
+}
+
static rtems_timer_service_routine test_event_from_isr(
rtems_id timer,
void *arg
@@ -43,7 +52,7 @@ static rtems_timer_service_routine test_event_from_isr(
{
rtems_status_code status;
- if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
+ if ( is_case_hit() ) {
/*
* This event send hits the critical section but sends to
* another task so doesn't impact this critical section.
@@ -84,7 +93,7 @@ static rtems_timer_service_routine test_event_with_timeout_from_isr(
{
rtems_status_code status;
- if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
+ if ( is_case_hit() ) {
/*
* We want to catch the task while it is blocking. Otherwise
* just send and make it happy.
@@ -117,6 +126,7 @@ rtems_task Init(
TEST_BEGIN();
main_task = rtems_task_self();
+ main_thread = _Thread_Get_executing();
status = rtems_task_create(
0xa5a5a5a5,
diff --git a/testsuites/sptests/spsize/size.c b/testsuites/sptests/spsize/size.c
index c68199d..f427bd2 100644
--- a/testsuites/sptests/spsize/size.c
+++ b/testsuites/sptests/spsize/size.c
@@ -268,8 +268,6 @@ uninitialized =
/*dpmemimpl.h*/ (sizeof _Dual_ported_memory_Information) +
-/*eventimpl.h*/ (sizeof _Event_Sync_state) +
-
#if defined(RTEMS_MULTIPROCESSING)
/*eventmp.h*/ 0 +
#endif
--
1.8.4.5
More information about the devel
mailing list