forked from Imagelibrary/rtems
new isr synchronization algorithm using a single enumerated set of states.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define _Event_Manager_initialization() \
|
||||
do { \
|
||||
\
|
||||
_Event_Sync = FALSE; \
|
||||
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED; \
|
||||
\
|
||||
/* \
|
||||
* Register the MP Process Packet routine. \
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define _Event_Manager_initialization() \
|
||||
do { \
|
||||
\
|
||||
_Event_Sync = FALSE; \
|
||||
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED; \
|
||||
\
|
||||
/* \
|
||||
* Register the MP Process Packet routine. \
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define _Event_Manager_initialization() \
|
||||
do { \
|
||||
\
|
||||
_Event_Sync = FALSE; \
|
||||
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED; \
|
||||
\
|
||||
/* \
|
||||
* Register the MP Process Packet routine. \
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user