From 107ce47b4b7be469696406948d2d2c1b01357b6b Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 9 Feb 1996 14:30:42 +0000 Subject: new isr synchronization algorithm using a single enumerated set of states. --- cpukit/rtems/inline/rtems/rtems/event.inl | 2 +- cpukit/rtems/macros/rtems/rtems/event.inl | 2 +- cpukit/rtems/src/event.c | 37 +++++++--- cpukit/score/include/rtems/score/tqdata.h | 6 +- cpukit/score/inline/rtems/score/tqdata.inl | 1 - cpukit/score/macros/rtems/score/tqdata.inl | 1 - cpukit/score/src/threadq.c | 115 ++++++++++++++++++----------- 7 files changed, 105 insertions(+), 59 deletions(-) (limited to 'cpukit') diff --git a/cpukit/rtems/inline/rtems/rtems/event.inl b/cpukit/rtems/inline/rtems/rtems/event.inl index 5377144f98..0e2a1691ed 100644 --- a/cpukit/rtems/inline/rtems/rtems/event.inl +++ b/cpukit/rtems/inline/rtems/rtems/event.inl @@ -23,7 +23,7 @@ STATIC INLINE void _Event_Manager_initialization( void ) { - _Event_Sync = FALSE; + _Event_Sync_state = EVENT_SYNC_SYNCHRONIZED; /* * Register the MP Process Packet routine. diff --git a/cpukit/rtems/macros/rtems/rtems/event.inl b/cpukit/rtems/macros/rtems/rtems/event.inl index 0d2f2e47c7..eb956e7639 100644 --- a/cpukit/rtems/macros/rtems/rtems/event.inl +++ b/cpukit/rtems/macros/rtems/rtems/event.inl @@ -24,7 +24,7 @@ #define _Event_Manager_initialization() \ do { \ \ - _Event_Sync = FALSE; \ + _Event_Sync_state = EVENT_SYNC_SYNCHRONIZED; \ \ /* \ * Register the MP Process Packet routine. \ diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c index 9bea949647..3042de2676 100644 --- a/cpukit/rtems/src/event.c +++ b/cpukit/rtems/src/event.c @@ -144,6 +144,7 @@ void _Event_Seize( rtems_event_set pending_events; ISR_Level level; RTEMS_API_Control *api; + Event_Sync_states sync_state; executing = _Thread_Executing; executing->Wait.return_code = RTEMS_SUCCESSFUL; @@ -170,7 +171,6 @@ void _Event_Seize( return; } - _Event_Sync = TRUE; _Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED; executing->Wait.option = (unsigned32) option_set; @@ -192,9 +192,13 @@ void _Event_Seize( _Thread_Set_state( executing, STATES_WAITING_FOR_EVENT ); _ISR_Disable( level ); - switch ( _Event_Sync_state ) { + + sync_state = _Event_Sync_state; + _Event_Sync_state = EVENT_SYNC_SYNCHRONIZED; + + switch ( sync_state ) { + case EVENT_SYNC_SYNCHRONIZED: case EVENT_SYNC_NOTHING_HAPPENED: - _Event_Sync = FALSE; _ISR_Enable( level ); return; case EVENT_SYNC_TIMEOUT: @@ -274,12 +278,24 @@ void _Event_Surrender( return; } } - else if ( _Event_Sync == TRUE && _Thread_Is_executing( the_thread ) ) { - if ( seized_events == event_condition || _Options_Is_any( option_set ) ) { - api->pending_events = _Event_sets_Clear( pending_events,seized_events ); - *(rtems_event_set *)the_thread->Wait.return_argument = seized_events; - _Event_Sync_state = EVENT_SYNC_SATISFIED; - } + + switch ( _Event_Sync_state ) { + case EVENT_SYNC_SYNCHRONIZED: + case EVENT_SYNC_SATISFIED: + break; + + case EVENT_SYNC_NOTHING_HAPPENED: + case EVENT_SYNC_TIMEOUT: + if ( !_Thread_Is_executing( the_thread ) ) + break; + + if ( seized_events == event_condition || _Options_Is_any(option_set) ) { + api->pending_events = + _Event_sets_Clear( pending_events,seized_events ); + *(rtems_event_set *)the_thread->Wait.return_argument = seized_events; + _Event_Sync_state = EVENT_SYNC_SATISFIED; + } + break; } } _ISR_Enable( level ); @@ -312,7 +328,8 @@ void _Event_Timeout( case OBJECTS_REMOTE: /* impossible */ break; case OBJECTS_LOCAL: - if ( _Event_Sync == TRUE && _Thread_Is_executing( the_thread ) ) { + if ( _Event_Sync_state != EVENT_SYNC_SYNCHRONIZED && + _Thread_Is_executing( the_thread ) ) { if ( _Event_Sync_state != EVENT_SYNC_SATISFIED ) _Event_Sync_state = EVENT_SYNC_TIMEOUT; } else { diff --git a/cpukit/score/include/rtems/score/tqdata.h b/cpukit/score/include/rtems/score/tqdata.h index 872a29beb0..a4a5551dfd 100644 --- a/cpukit/score/include/rtems/score/tqdata.h +++ b/cpukit/score/include/rtems/score/tqdata.h @@ -41,10 +41,11 @@ typedef enum { */ typedef enum { + THREAD_QUEUE_SYNCHRONIZED, THREAD_QUEUE_NOTHING_HAPPENED, THREAD_QUEUE_TIMEOUT, THREAD_QUEUE_SATISFIED -} Thread_queue_states; +} Thread_queue_States; /* * The following record defines the control block used @@ -59,8 +60,7 @@ typedef struct { Chain_Control Priority[TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS]; /* priority discipline list */ } Queues; - boolean sync; /* alloc/dealloc critical section */ - Thread_queue_states sync_state; /* what happened while in sync */ + Thread_queue_States sync_state; /* alloc/dealloc critical section */ Thread_queue_Disciplines discipline; /* queue discipline */ States_Control state; /* state of threads on Thread_q */ unsigned32 timeout_status; diff --git a/cpukit/score/inline/rtems/score/tqdata.inl b/cpukit/score/inline/rtems/score/tqdata.inl index 3cf9c51ef6..b16b3a1ca1 100644 --- a/cpukit/score/inline/rtems/score/tqdata.inl +++ b/cpukit/score/inline/rtems/score/tqdata.inl @@ -66,7 +66,6 @@ STATIC INLINE void _Thread_queue_Enter_critical_section ( Thread_queue_Control *the_thread_queue ) { - the_thread_queue->sync = TRUE; the_thread_queue->sync_state = THREAD_QUEUE_NOTHING_HAPPENED; } diff --git a/cpukit/score/macros/rtems/score/tqdata.inl b/cpukit/score/macros/rtems/score/tqdata.inl index 1df3cd5270..df1508104c 100644 --- a/cpukit/score/macros/rtems/score/tqdata.inl +++ b/cpukit/score/macros/rtems/score/tqdata.inl @@ -52,7 +52,6 @@ #define _Thread_queue_Enter_critical_section( _the_thread_queue ) \ do { \ - (_the_thread_queue)->sync = TRUE; \ (_the_thread_queue)->sync_state = THREAD_QUEUE_NOTHING_HAPPENED; \ } while ( 0 ) diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c index dc52efa954..682a0362bc 100644 --- a/cpukit/score/src/threadq.c +++ b/cpukit/score/src/threadq.c @@ -55,6 +55,7 @@ void _Thread_queue_Initialize( the_thread_queue->state = state; the_thread_queue->discipline = the_discipline; the_thread_queue->timeout_status = timeout_status; + the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED; switch ( the_discipline ) { case THREAD_QUEUE_DISCIPLINE_FIFO: @@ -326,7 +327,8 @@ void _Thread_queue_Timeout( case OBJECTS_LOCAL: the_thread_queue = the_thread->Wait.queue; - if ( the_thread_queue->sync == TRUE && _Thread_Is_executing(the_thread)) { + if ( the_thread_queue->sync_state != THREAD_QUEUE_SYNCHRONIZED && + _Thread_Is_executing( the_thread ) ) { if ( the_thread_queue->sync_state != THREAD_QUEUE_SATISFIED ) the_thread_queue->sync_state = THREAD_QUEUE_TIMEOUT; } else { @@ -362,13 +364,22 @@ void _Thread_queue_Enqueue_fifo ( Watchdog_Interval timeout ) { - ISR_Level level; + ISR_Level level; + Thread_queue_States sync_state; _ISR_Disable( level ); - the_thread_queue->sync = FALSE; + sync_state = the_thread_queue->sync_state; + the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED; + + switch ( sync_state ) { + case THREAD_QUEUE_SYNCHRONIZED: + /* + * This should never happen. It indicates that someone did not + * enter a thread queue critical section. + */ + break; - switch ( the_thread_queue->sync_state ) { case THREAD_QUEUE_NOTHING_HAPPENED: _Chain_Append_unprotected( &the_thread_queue->Queues.Fifo, @@ -449,15 +460,21 @@ Thread_Control *_Thread_queue_Dequeue_fifo( _Thread_MP_Free_proxy( the_thread ); return the_thread; - } else if ( the_thread_queue->sync && - the_thread_queue->sync_state != THREAD_QUEUE_SATISFIED ) { - the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED; - _ISR_Enable( level ); - return _Thread_Executing; - } else { - _ISR_Enable( level ); - return NULL; + } + + switch ( the_thread_queue->sync_state ) { + case THREAD_QUEUE_SYNCHRONIZED: + case THREAD_QUEUE_SATISFIED: + _ISR_Enable( level ); + return NULL; + + case THREAD_QUEUE_NOTHING_HAPPENED: + case THREAD_QUEUE_TIMEOUT: + the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED; + _ISR_Enable( level ); + return _Thread_Executing; } + return NULL; /* this is only to prevent warnings */ } /*PAGE @@ -557,17 +574,18 @@ void _Thread_queue_Enqueue_priority( Watchdog_Interval timeout ) { - Priority_Control search_priority; - Thread_Control *search_thread; - ISR_Level level; - Chain_Control *header; - unsigned32 header_index; - Chain_Node *the_node; - Chain_Node *next_node; - Chain_Node *previous_node; - Chain_Node *search_node; - Priority_Control priority; - States_Control block_state; + Priority_Control search_priority; + Thread_Control *search_thread; + ISR_Level level; + Chain_Control *header; + unsigned32 header_index; + Chain_Node *the_node; + Chain_Node *next_node; + Chain_Node *previous_node; + Chain_Node *search_node; + Priority_Control priority; + States_Control block_state; + Thread_queue_States sync_state; _Chain_Initialize_empty( &the_thread->Wait.Block2n ); @@ -605,10 +623,10 @@ restart_forward_search: (Thread_Control *)search_thread->Object.Node.next; } - the_thread_queue->sync = FALSE; - if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED ) - goto syncronize; + goto synchronize; + + the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED; if ( priority == search_priority ) goto equal_priority; @@ -650,10 +668,10 @@ restart_reverse_search: search_thread->Object.Node.previous; } - the_thread_queue->sync = FALSE; - if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED ) - goto syncronize; + goto synchronize; + + the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED; if ( priority == search_priority ) goto equal_priority; @@ -681,9 +699,19 @@ equal_priority: /* add at end of priority group */ _ISR_Enable( level ); return; -syncronize: +synchronize: - switch ( the_thread_queue->sync_state ) { + sync_state = the_thread_queue->sync_state; + the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED; + + switch ( sync_state ) { + case THREAD_QUEUE_SYNCHRONIZED: + /* + * This should never happen. It indicates that someone did not + * enter a thread queue critical section. + */ + break; + case THREAD_QUEUE_NOTHING_HAPPENED: /* * All of this was dealt with above. This should never happen. @@ -738,9 +766,9 @@ Thread_Control *_Thread_queue_Dequeue_priority( Thread_queue_Control *the_thread_queue ) { - unsigned32 index; - ISR_Level level; - Thread_Control *the_thread; + unsigned32 index; + ISR_Level level; + Thread_Control *the_thread = NULL; /* just to remove warnings */ Thread_Control *new_first_thread; Chain_Node *new_first_node; Chain_Node *new_second_node; @@ -759,15 +787,18 @@ Thread_Control *_Thread_queue_Dequeue_priority( } } - if ( the_thread_queue->sync && - the_thread_queue->sync_state != THREAD_QUEUE_SATISFIED ) { - the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED; - _ISR_Enable( level ); - return _Thread_Executing; - } + switch ( the_thread_queue->sync_state ) { + case THREAD_QUEUE_SYNCHRONIZED: + case THREAD_QUEUE_SATISFIED: + _ISR_Enable( level ); + return NULL; - _ISR_Enable( level ); - return NULL; + case THREAD_QUEUE_NOTHING_HAPPENED: + case THREAD_QUEUE_TIMEOUT: + the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED; + _ISR_Enable( level ); + return _Thread_Executing; + } dequeue: new_first_node = the_thread->Wait.Block2n.first; -- cgit v1.2.3