2008-01-22 Joel Sherrill <joel.sherrill@oarcorp.com>

* rtems/include/rtems/rtems/event.h,
	rtems/inline/rtems/rtems/eventset.inl, rtems/src/event.c,
	rtems/src/eventseize.c, rtems/src/eventsurrender.c,
	rtems/src/eventtimeout.c, score/Makefile.am, score/preinstall.am,
	score/include/rtems/score/interr.h,
	score/include/rtems/score/thread.h,
	score/include/rtems/score/threadq.h,
	score/include/rtems/score/tqdata.h,
	score/inline/rtems/score/threadq.inl,
	score/inline/rtems/score/tqdata.inl, score/src/threadq.c,
	score/src/threadqdequeue.c, score/src/threadqdequeuefifo.c,
	score/src/threadqdequeuepriority.c, score/src/threadqenqueue.c,
	score/src/threadqenqueuefifo.c, score/src/threadqenqueuepriority.c,
	score/src/threadqextract.c, score/src/threadqextractfifo.c,
	score/src/threadqextractpriority.c,
	score/src/threadqextractwithproxy.c, score/src/threadqfirst.c,
	score/src/threadqfirstfifo.c, score/src/threadqfirstpriority.c,
	score/src/threadqflush.c, score/src/threadqrequeue.c,
	score/src/threadqtimeout.c: Refactor thread queue enqueue and event
	blocking synchronization critical sections. This resulted in three
	copies of essentially the same hard to test critical section code
	becoming the one shared routine _Thread_blocking_operation_Cancel. In
	addition, the thread queue and event code now share a common
	synchronization enumerated type. Along the way, switches were
	reworked to eliminate dead code generated by gcc and comments and
	copyrights were updated.
	* score/include/rtems/score/threadsync.h,
	score/src/threadblockingoperationcancel.c: New files.
This commit is contained in:
Joel Sherrill
2008-01-22 18:28:53 +00:00
parent b89f64cc41
commit 3168deaa10
34 changed files with 437 additions and 328 deletions
+31
View File
@@ -1,3 +1,34 @@
2008-01-22 Joel Sherrill <joel.sherrill@oarcorp.com>
* rtems/include/rtems/rtems/event.h,
rtems/inline/rtems/rtems/eventset.inl, rtems/src/event.c,
rtems/src/eventseize.c, rtems/src/eventsurrender.c,
rtems/src/eventtimeout.c, score/Makefile.am, score/preinstall.am,
score/include/rtems/score/interr.h,
score/include/rtems/score/thread.h,
score/include/rtems/score/threadq.h,
score/include/rtems/score/tqdata.h,
score/inline/rtems/score/threadq.inl,
score/inline/rtems/score/tqdata.inl, score/src/threadq.c,
score/src/threadqdequeue.c, score/src/threadqdequeuefifo.c,
score/src/threadqdequeuepriority.c, score/src/threadqenqueue.c,
score/src/threadqenqueuefifo.c, score/src/threadqenqueuepriority.c,
score/src/threadqextract.c, score/src/threadqextractfifo.c,
score/src/threadqextractpriority.c,
score/src/threadqextractwithproxy.c, score/src/threadqfirst.c,
score/src/threadqfirstfifo.c, score/src/threadqfirstpriority.c,
score/src/threadqflush.c, score/src/threadqrequeue.c,
score/src/threadqtimeout.c: Refactor thread queue enqueue and event
blocking synchronization critical sections. This resulted in three
copies of essentially the same hard to test critical section code
becoming the one shared routine _Thread_blocking_operation_Cancel. In
addition, the thread queue and event code now share a common
synchronization enumerated type. Along the way, switches were
reworked to eliminate dead code generated by gcc and comments and
copyrights were updated.
* score/include/rtems/score/threadsync.h,
score/src/threadblockingoperationcancel.c: New files.
2008-01-22 Joel Sherrill <joel.sherrill@OARcorp.com>
* libi2c/README_libi2c: Correct spelling error.
+3 -14
View File
@@ -13,7 +13,7 @@
* + receive event condition
*
*
* COPYRIGHT (c) 1989-2007.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -39,6 +39,7 @@ extern "C" {
#include <rtems/rtems/types.h>
#include <rtems/rtems/options.h>
#include <rtems/score/thread.h>
#include <rtems/score/threadsync.h>
#include <rtems/score/watchdog.h>
#include <rtems/rtems/eventset.h>
@@ -49,18 +50,6 @@ extern "C" {
#define EVENT_CURRENT 0
/*
* The following enumerated types indicate what happened while the event
* manager was in the synchronization window.
*/
typedef enum {
EVENT_SYNC_SYNCHRONIZED,
EVENT_SYNC_NOTHING_HAPPENED,
EVENT_SYNC_TIMEOUT,
EVENT_SYNC_SATISFIED
} Event_Sync_states;
/*
* Event_Manager_initialization
*
@@ -166,7 +155,7 @@ void _Event_Timeout (
* executing thread are received properly.
*/
RTEMS_EVENT_EXTERN volatile Event_Sync_states _Event_Sync_state;
RTEMS_EVENT_EXTERN volatile Thread_blocking_operation_States _Event_Sync_state;
#if defined(RTEMS_MULTIPROCESSING)
#include <rtems/rtems/eventmp.h>
+1 -1
View File
@@ -5,7 +5,7 @@
/*
* This include file contains the information pertaining to event sets.
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Event Manager
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -36,7 +36,7 @@
void _Event_Manager_initialization( void )
{
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
_Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
/*
* Register the MP Process Packet routine.
+20 -37
View File
@@ -1,7 +1,7 @@
/*
* Event Manager
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -54,12 +54,12 @@ void _Event_Seize(
rtems_event_set *event_out
)
{
Thread_Control *executing;
rtems_event_set seized_events;
rtems_event_set pending_events;
ISR_Level level;
RTEMS_API_Control *api;
Event_Sync_states sync_state;
Thread_Control *executing;
rtems_event_set seized_events;
rtems_event_set pending_events;
ISR_Level level;
RTEMS_API_Control *api;
Thread_blocking_operation_States sync_state;
executing = _Thread_Executing;
executing->Wait.return_code = RTEMS_SUCCESSFUL;
@@ -86,7 +86,7 @@ void _Event_Seize(
return;
}
_Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
_Event_Sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
executing->Wait.option = (uint32_t) option_set;
executing->Wait.count = (uint32_t) event_in;
@@ -109,34 +109,17 @@ void _Event_Seize(
_ISR_Disable( level );
sync_state = _Event_Sync_state;
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
switch ( sync_state ) {
case EVENT_SYNC_SYNCHRONIZED:
/*
* This cannot happen. It indicates that this routine did not
* enter the synchronization states above.
*/
break;
case EVENT_SYNC_NOTHING_HAPPENED:
_ISR_Enable( level );
break;
case EVENT_SYNC_TIMEOUT:
executing->Wait.return_code = RTEMS_TIMEOUT;
_ISR_Enable( level );
_Thread_Unblock( executing );
break;
case EVENT_SYNC_SATISFIED:
if ( _Watchdog_Is_active( &executing->Timer ) ) {
_Watchdog_Deactivate( &executing->Timer );
_ISR_Enable( level );
(void) _Watchdog_Remove( &executing->Timer );
} else
_ISR_Enable( level );
_Thread_Unblock( executing );
break;
_Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
_ISR_Enable( level );
return;
}
/*
* An interrupt completed the thread's blocking request.
* The blocking thread was satisfied by an ISR or timed out.
*
* WARNING! Returning with interrupts disabled!
*/
_Thread_blocking_operation_Cancel( sync_state, executing, level );
}
+41 -38
View File
@@ -1,7 +1,7 @@
/*
* Event Manager
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -63,48 +63,51 @@ void _Event_Surrender(
seized_events = _Event_sets_Get( pending_events, event_condition );
if ( !_Event_sets_Is_empty( seized_events ) ) {
if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
api->pending_events =
_Event_sets_Clear( pending_events, seized_events );
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
/*
* No events were seized in this operation
*/
if ( _Event_sets_Is_empty( seized_events ) )
return;
_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;
}
/*
* If we are in an ISR and sending to the current thread, then
* we have a critical section issue to deal with.
*/
if ( _ISR_Is_in_progress() &&
_Thread_Is_executing( the_thread ) &&
((_Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) ||
(_Event_Sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT)) ) {
if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
api->pending_events = _Event_sets_Clear( pending_events,seized_events );
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
_Event_Sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
}
_ISR_Enable( level );
return;
}
switch ( _Event_Sync_state ) {
case EVENT_SYNC_SYNCHRONIZED:
case EVENT_SYNC_SATISFIED:
break;
/*
* Otherwise, this is a normal send to another thread
*/
if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
api->pending_events = _Event_sets_Clear( pending_events, seized_events );
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
case EVENT_SYNC_NOTHING_HAPPENED:
case EVENT_SYNC_TIMEOUT:
if ( !_Thread_Is_executing( the_thread ) )
break;
_ISR_Flash( level );
if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
api->pending_events =
_Event_sets_Clear( pending_events,seized_events );
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
_Event_Sync_state = EVENT_SYNC_SATISFIED;
}
break;
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;
}
}
_ISR_Enable( level );
+20 -19
View File
@@ -1,7 +1,7 @@
/*
* Event Manager
*
* COPYRIGHT (c) 1989-2007.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -64,25 +64,26 @@ void _Event_Timeout(
* a timeout is not allowed to occur.
*/
_ISR_Disable( level );
if ( the_thread->Wait.count ) { /* verify thread is waiting */
the_thread->Wait.count = 0;
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;
}
_ISR_Enable( level );
} else {
the_thread->Wait.return_code = RTEMS_TIMEOUT;
_ISR_Enable( level );
_Thread_Unblock( the_thread );
}
}
else {
_ISR_Enable( level );
}
_ISR_Disable( level );
if ( !the_thread->Wait.count ) { /* verify thread is waiting */
_Thread_Unnest_dispatch();
_ISR_Enable( level );
return;
}
the_thread->Wait.count = 0;
if ( _Thread_Is_executing( the_thread ) ) {
Thread_blocking_operation_States sync = _Event_Sync_state;
if ( (sync == THREAD_BLOCKING_OPERATION_SYNCHRONIZED) ||
(sync == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) ) {
_Event_Sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
}
}
the_thread->Wait.return_code = RTEMS_TIMEOUT;
_ISR_Enable( level );
_Thread_Unblock( the_thread );
_Thread_Unnest_dispatch();
break;
+7 -5
View File
@@ -28,10 +28,11 @@ include_rtems_score_HEADERS = include/rtems/score/address.h \
include/rtems/score/object.h include/rtems/score/priority.h \
include/rtems/score/stack.h include/rtems/score/states.h \
include/rtems/score/sysstate.h include/rtems/score/thread.h \
include/rtems/score/threadq.h include/rtems/score/timespec.h \
include/rtems/score/tod.h include/rtems/score/tqdata.h \
include/rtems/score/userext.h include/rtems/score/watchdog.h \
include/rtems/score/wkspace.h include/rtems/score/cpuopts.h
include/rtems/score/threadq.h include/rtems/score/threadsync.h \
include/rtems/score/timespec.h include/rtems/score/tod.h \
include/rtems/score/tqdata.h include/rtems/score/userext.h \
include/rtems/score/watchdog.h include/rtems/score/wkspace.h \
include/rtems/score/cpuopts.h
if HAS_MP
# We only build multiprocessing related files if HAS_MP was defined
@@ -142,7 +143,8 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
src/threadsettransient.c src/threadstackallocate.c \
src/threadstackfree.c src/threadstart.c src/threadstartmultitasking.c \
src/threadsuspend.c src/threadtickletimeslice.c \
src/threadyieldprocessor.c src/iterateoverthreads.c
src/threadyieldprocessor.c src/iterateoverthreads.c \
src/threadblockingoperationcancel.c
## THREAD_C_FILES only used by ITRON API
if LIBITRON
+2 -1
View File
@@ -63,7 +63,8 @@ typedef enum {
INTERNAL_ERROR_INVALID_GLOBAL_ID,
INTERNAL_ERROR_BAD_STACK_HOOK,
INTERNAL_ERROR_BAD_ATTRIBUTES,
INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY
INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY,
INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL
} Internal_errors_Core_list;
/**
+22 -1
View File
@@ -6,7 +6,7 @@
*/
/*
* COPYRIGHT (c) 1989-2007.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -785,6 +785,27 @@ Thread_Control *_Thread_Get (
Objects_Locations *location
);
/**
* @brief Cancel a blocking operation due to ISR
*
* This method is used to cancel a blocking operation that was
* satisfied from an ISR while the thread executing was in the
* process of blocking.
*
* @param[in] sync_state is the synchronization state
* @param[in] the_thread is the thread whose blocking is canceled
* @param[in] level is the previous ISR disable level
*
* @note This is a rare routine in RTEMS. It is called with
* interrupts disabled and only when an ISR completed
* a blocking condition in process.
*/
void _Thread_blocking_operation_Cancel(
Thread_blocking_operation_States sync_state,
Thread_Control *the_thread,
ISR_Level level
);
#ifndef __RTEMS_APPLICATION__
#include <rtems/score/thread.inl>
#endif
+7 -5
View File
@@ -6,7 +6,7 @@
*/
/*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -178,9 +178,10 @@ Thread_Control *_Thread_queue_Dequeue_priority(
* the_thread_queue with an optional timeout using the
* priority discipline.
*/
void _Thread_queue_Enqueue_priority(
Thread_blocking_operation_States _Thread_queue_Enqueue_priority (
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread
Thread_Control *the_thread,
ISR_Level *level_p
);
/** @brief Thread queue Extract priority Helper
@@ -230,9 +231,10 @@ Thread_Control *_Thread_queue_Dequeue_fifo(
* the_thread_queue with an optional timeout using the
* FIFO discipline.
*/
void _Thread_queue_Enqueue_fifo(
Thread_blocking_operation_States _Thread_queue_Enqueue_fifo (
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread
Thread_Control *the_thread,
ISR_Level *level_p
);
/** @brief Thread queue Extract FIFO
@@ -0,0 +1,58 @@
/**
* @file rtems/score/threadsync.h
*
* This include file contains all constants and structures associated
* with synchronizing a thread blocking operation with potential
* actions in an ISR.
*/
/*
* COPYRIGHT (c) 1989-2008.
* 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.com/license/LICENSE.
*
* $Id$
*/
#ifndef _RTEMS_SCORE_THREAD_SYNC_H
#define _RTEMS_SCORE_THREAD_SYNC_H
/**
* @defgroup ScoreThread Thread Blocking Operation Synchronization Handler
*
* This handler encapsulates functionality related to the management of
* synchronization critical sections during blocking operations.
*/
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* The following enumerated types indicate what happened while the thread
* blocking was in the synchronization window.
*/
typedef enum {
THREAD_BLOCKING_OPERATION_SYNCHRONIZED,
THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED,
THREAD_BLOCKING_OPERATION_TIMEOUT,
THREAD_BLOCKING_OPERATION_SATISFIED
} Thread_blocking_operation_States;
/*
* Operations require a thread pointer so they are prototyped
* in thread.h
*/
#ifdef __cplusplus
}
#endif
/**@}*/
#endif
/* end of include file */
+3 -13
View File
@@ -6,7 +6,7 @@
*/
/*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -35,6 +35,7 @@ extern "C" {
#include <rtems/score/chain.h>
#include <rtems/score/priority.h>
#include <rtems/score/states.h>
#include <rtems/score/threadsync.h>
/**
* The following enumerated type details all of the disciplines
@@ -45,17 +46,6 @@ typedef enum {
THREAD_QUEUE_DISCIPLINE_PRIORITY /* PRIORITY queue discipline */
} Thread_queue_Disciplines;
/**
* The following enumerated types indicate what happened while the thread
* queue was in the synchronization window.
*/
typedef enum {
THREAD_QUEUE_SYNCHRONIZED,
THREAD_QUEUE_NOTHING_HAPPENED,
THREAD_QUEUE_TIMEOUT,
THREAD_QUEUE_SATISFIED
} Thread_queue_States;
/**
* This is one of the constants used to manage the priority queues.
*
@@ -99,7 +89,7 @@ typedef struct {
Chain_Control Priority[TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS];
} Queues;
/** This field is used to manage the critical section. */
Thread_queue_States sync_state;
Thread_blocking_operation_States sync_state;
/** This field indicates the thread queue's blocking discipline. */
Thread_queue_Disciplines discipline;
/** This indicates the blocking state for threads waiting on this
+6 -4
View File
@@ -6,7 +6,7 @@
*/
/*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -55,10 +55,12 @@ static inline void _Thread_queue_Process_timeout(
* a timeout is not allowed to occur.
*/
if ( the_thread_queue->sync_state != THREAD_QUEUE_SYNCHRONIZED &&
if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SYNCHRONIZED &&
_Thread_Is_executing( the_thread ) ) {
if ( the_thread_queue->sync_state != THREAD_QUEUE_SATISFIED )
the_thread_queue->sync_state = THREAD_QUEUE_TIMEOUT;
if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SATISFIED ) {
the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
}
} else {
the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
_Thread_queue_Extract( the_thread->Wait.queue, the_thread );
+2 -2
View File
@@ -6,7 +6,7 @@
*/
/*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -58,7 +58,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enter_critical_section (
Thread_queue_Control *the_thread_queue
)
{
the_thread_queue->sync_state = THREAD_QUEUE_NOTHING_HAPPENED;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
}
/**
+4
View File
@@ -131,6 +131,10 @@ $(PROJECT_INCLUDE)/rtems/score/threadq.h: include/rtems/score/threadq.h $(PROJEC
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/threadq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadq.h
$(PROJECT_INCLUDE)/rtems/score/threadsync.h: include/rtems/score/threadsync.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/threadsync.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadsync.h
$(PROJECT_INCLUDE)/rtems/score/timespec.h: include/rtems/score/timespec.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/timespec.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/timespec.h
@@ -0,0 +1,81 @@
/*
* Cancel Thread Blocking Operation
*
*
* 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.com/license/LICENSE.
*
* $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/thread.h>
#if defined(RTEMS_MULTIPROCESSING)
#include <rtems/score/mpci.h>
#endif
void _Thread_blocking_operation_Cancel(
Thread_blocking_operation_States sync_state,
Thread_Control *the_thread,
ISR_Level level
)
{
/*
* Cases that should not happen and why.
*
* THREAD_BLOCKING_OPERATION_SYNCHRONIZED:
*
* This indicates that someone did not enter a blocking
* operation critical section.
*
* THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED:
*
* This indicates that there was nothing to cancel so
* we should not have been called.
*/
#if defined(RTEMS_DEBUG)
if ( (sync_state == THREAD_BLOCKING_OPERATION_SYNCHRONIZED)
(sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) ) {
_Internal_error_Occurred(
INTERNAL_ERROR_CORE,
TRUE,
INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL
);
}
#endif
/*
* If the sync state is timed out, this is very likely not needed.
* But better safe than sorry when it comes to critical sections.
*/
if ( _Watchdog_Is_active( &the_thread->Timer ) ) {
_Watchdog_Deactivate( &the_thread->Timer );
the_thread->Wait.queue = NULL;
_ISR_Enable( level );
(void) _Watchdog_Remove( &the_thread->Timer );
} else
_ISR_Enable( level );
/*
* Global objects with thread queue's should not be operated on from an
* ISR. But the sync code still must allow short timeouts to be processed
* correctly.
*/
_Thread_Unblock( the_thread );
#if defined(RTEMS_MULTIPROCESSING)
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
_Thread_MP_Free_proxy( the_thread );
#endif
}
+11 -14
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -47,23 +47,20 @@ void _Thread_queue_Initialize(
uint32_t timeout_status
)
{
uint32_t index;
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;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
switch ( the_discipline ) {
case THREAD_QUEUE_DISCIPLINE_FIFO:
_Chain_Initialize_empty( &the_thread_queue->Queues.Fifo );
break;
case THREAD_QUEUE_DISCIPLINE_PRIORITY:
for( index=0 ;
index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
index++)
_Chain_Initialize_empty( &the_thread_queue->Queues.Priority[index] );
break;
if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
uint32_t index;
for( index=0 ;
index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
index++)
_Chain_Initialize_empty( &the_thread_queue->Queues.Priority[index] );
} else { /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
_Chain_Initialize_empty( &the_thread_queue->Queues.Fifo );
}
}
+7 -14
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -47,19 +47,12 @@ Thread_Control *_Thread_queue_Dequeue(
Thread_queue_Control *the_thread_queue
)
{
Thread_Control *the_thread;
Thread_Control *(*dequeue_p)( Thread_queue_Control * );
switch ( the_thread_queue->discipline ) {
case THREAD_QUEUE_DISCIPLINE_FIFO:
the_thread = _Thread_queue_Dequeue_fifo( the_thread_queue );
break;
case THREAD_QUEUE_DISCIPLINE_PRIORITY:
the_thread = _Thread_queue_Dequeue_priority( the_thread_queue );
break;
default: /* this is only to prevent warnings */
the_thread = NULL;
break;
}
if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY )
dequeue_p = _Thread_queue_Dequeue_priority;
else /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
dequeue_p = _Thread_queue_Dequeue_fifo;
return( the_thread );
return (*dequeue_p)( the_thread_queue );
}
+6 -6
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -75,14 +75,14 @@ Thread_Control *_Thread_queue_Dequeue_fifo(
}
switch ( the_thread_queue->sync_state ) {
case THREAD_QUEUE_SYNCHRONIZED:
case THREAD_QUEUE_SATISFIED:
case THREAD_BLOCKING_OPERATION_SYNCHRONIZED:
case THREAD_BLOCKING_OPERATION_SATISFIED:
_ISR_Enable( level );
return NULL;
case THREAD_QUEUE_NOTHING_HAPPENED:
case THREAD_QUEUE_TIMEOUT:
the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED;
case THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED:
case THREAD_BLOCKING_OPERATION_TIMEOUT:
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
_ISR_Enable( level );
return _Thread_Executing;
}
+16 -11
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -55,6 +55,7 @@ Thread_Control *_Thread_queue_Dequeue_priority(
Chain_Node *last_node;
Chain_Node *next_node;
Chain_Node *previous_node;
Thread_blocking_operation_States sync;
_ISR_Disable( level );
for( index=0 ;
@@ -67,17 +68,21 @@ Thread_Control *_Thread_queue_Dequeue_priority(
}
}
switch ( the_thread_queue->sync_state ) {
case THREAD_QUEUE_SYNCHRONIZED:
case THREAD_QUEUE_SATISFIED:
_ISR_Enable( level );
return NULL;
/*
* If we interrupted a blocking operation, cancel it.
*/
sync = the_thread_queue->sync_state;
if ( (sync == THREAD_BLOCKING_OPERATION_SYNCHRONIZED) ||
(sync == THREAD_BLOCKING_OPERATION_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;
if ( (sync == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) ||
(sync == THREAD_BLOCKING_OPERATION_TIMEOUT ) ) {
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
_ISR_Enable( level );
return _Thread_Executing;
}
dequeue:
+17 -10
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -51,7 +51,14 @@ void _Thread_queue_Enqueue_with_handler(
Thread_queue_Timeout_callout handler
)
{
Thread_Control *the_thread;
Thread_Control *the_thread;
ISR_Level level;
Thread_blocking_operation_States sync_state;
Thread_blocking_operation_States (*enqueue_p)(
Thread_queue_Control *,
Thread_Control *,
ISR_Level *
);
the_thread = _Thread_Executing;
@@ -82,12 +89,12 @@ void _Thread_queue_Enqueue_with_handler(
/*
* Now enqueue the thread per the discipline for this thread queue.
*/
switch( the_thread_queue->discipline ) {
case THREAD_QUEUE_DISCIPLINE_FIFO:
_Thread_queue_Enqueue_fifo( the_thread_queue, the_thread );
break;
case THREAD_QUEUE_DISCIPLINE_PRIORITY:
_Thread_queue_Enqueue_priority( the_thread_queue, the_thread );
break;
}
if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY )
enqueue_p = _Thread_queue_Enqueue_priority;
else /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
enqueue_p = _Thread_queue_Enqueue_fifo;
sync_state = (*enqueue_p)( the_thread_queue, the_thread, &level );
if ( sync_state != THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
_Thread_blocking_operation_Cancel( sync_state, the_thread, level );
}
+21 -47
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -41,64 +41,38 @@
* only case
*/
void _Thread_queue_Enqueue_fifo (
Thread_blocking_operation_States _Thread_queue_Enqueue_fifo (
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread
Thread_Control *the_thread,
ISR_Level *level_p
)
{
ISR_Level level;
Thread_queue_States sync_state;
Thread_blocking_operation_States sync_state;
ISR_Level level;
_ISR_Disable( level );
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:
sync_state = the_thread_queue->sync_state;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
if (sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) {
_Chain_Append_unprotected(
&the_thread_queue->Queues.Fifo,
&the_thread->Object.Node
);
the_thread->Wait.queue = the_thread_queue;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
_ISR_Enable( level );
return;
case THREAD_QUEUE_TIMEOUT:
the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
the_thread->Wait.queue = NULL;
_ISR_Enable( level );
break;
case THREAD_QUEUE_SATISFIED:
if ( _Watchdog_Is_active( &the_thread->Timer ) ) {
_Watchdog_Deactivate( &the_thread->Timer );
the_thread->Wait.queue = NULL;
_ISR_Enable( level );
(void) _Watchdog_Remove( &the_thread->Timer );
} else
_ISR_Enable( level );
break;
}
return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
}
/*
* Global objects with thread queue's should not be operated on from an
* ISR. But the sync code still must allow short timeouts to be processed
* correctly.
* An interrupt completed the thread's blocking request.
* For example, the blocking thread could have been given
* the mutex by an ISR or timed out.
*
* WARNING! Returning with interrupts disabled!
*/
_Thread_Unblock( the_thread );
#if defined(RTEMS_MULTIPROCESSING)
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
_Thread_MP_Free_proxy( the_thread );
#endif
*level_p = level;
return sync_state;
}
+20 -56
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -42,9 +42,10 @@
* forward equal
*/
void _Thread_queue_Enqueue_priority(
Thread_blocking_operation_States _Thread_queue_Enqueue_priority (
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread
Thread_Control *the_thread,
ISR_Level *level_p
)
{
Priority_Control search_priority;
@@ -58,7 +59,6 @@ void _Thread_queue_Enqueue_priority(
Chain_Node *search_node;
Priority_Control priority;
States_Control block_state;
Thread_queue_States sync_state;
_Chain_Initialize_empty( &the_thread->Wait.Block2n );
@@ -96,10 +96,11 @@ restart_forward_search:
(Thread_Control *)search_thread->Object.Node.next;
}
if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED )
if ( the_thread_queue->sync_state !=
THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
goto synchronize;
the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
if ( priority == search_priority )
goto equal_priority;
@@ -114,7 +115,7 @@ restart_forward_search:
search_node->previous = the_node;
the_thread->Wait.queue = the_thread_queue;
_ISR_Enable( level );
return;
return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
restart_reverse_search:
search_priority = PRIORITY_MAXIMUM + 1;
@@ -142,10 +143,11 @@ restart_reverse_search:
search_thread->Object.Node.previous;
}
if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED )
if ( the_thread_queue->sync_state !=
THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
goto synchronize;
the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
if ( priority == search_priority )
goto equal_priority;
@@ -160,7 +162,7 @@ restart_reverse_search:
next_node->previous = the_node;
the_thread->Wait.queue = the_thread_queue;
_ISR_Enable( level );
return;
return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
equal_priority: /* add at end of priority group */
search_node = _Chain_Tail( &search_thread->Wait.Block2n );
@@ -173,54 +175,16 @@ equal_priority: /* add at end of priority group */
search_node->previous = the_node;
the_thread->Wait.queue = the_thread_queue;
_ISR_Enable( level );
return;
return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
synchronize:
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:
/*
* This should never happen. All of this was dealt with above.
*/
break;
case THREAD_QUEUE_TIMEOUT:
the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
the_thread->Wait.queue = NULL;
_ISR_Enable( level );
break;
case THREAD_QUEUE_SATISFIED:
if ( _Watchdog_Is_active( &the_thread->Timer ) ) {
_Watchdog_Deactivate( &the_thread->Timer );
the_thread->Wait.queue = NULL;
_ISR_Enable( level );
(void) _Watchdog_Remove( &the_thread->Timer );
} else
_ISR_Enable( level );
break;
}
/*
* Global objects with thread queue's should not be operated on from an
* ISR. But the sync code still must allow short timeouts to be processed
* correctly.
* An interrupt completed the thread's blocking request.
* For example, the blocking thread could have been given
* the mutex by an ISR or timed out.
*
* WARNING! Returning with interrupts disabled!
*/
_Thread_Unblock( the_thread );
#if defined(RTEMS_MULTIPROCESSING)
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
_Thread_MP_Free_proxy( the_thread );
#endif
*level_p = level;
return the_thread_queue->sync_state;
}
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
+20 -19
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -46,28 +46,29 @@ void _Thread_queue_Requeue(
Thread_Control *the_thread
)
{
/* just in case the thread really wasn't blocked here */
if ( !the_thread_queue ) {
/*
* Just in case the thread really wasn't blocked on a thread queue
* when we get here.
*/
if ( !the_thread_queue )
return;
}
switch ( the_thread_queue->discipline ) {
case THREAD_QUEUE_DISCIPLINE_FIFO:
/* queueing by FIFO -- nothing to do */
break;
case THREAD_QUEUE_DISCIPLINE_PRIORITY: {
Thread_queue_Control *tq = the_thread_queue;
ISR_Level level;
/*
* If queueing by FIFO, there is nothing to do. This only applies to
* priority blocking discipline.
*/
if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
Thread_queue_Control *tq = the_thread_queue;
ISR_Level level;
ISR_Level level_ignored;
_ISR_Disable( level );
if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
_Thread_queue_Enter_critical_section( tq );
_Thread_queue_Extract_priority_helper( tq, the_thread, TRUE );
_Thread_queue_Enqueue_priority( tq, the_thread );
}
_ISR_Enable( level );
break;
_ISR_Disable( level );
if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
_Thread_queue_Enter_critical_section( tq );
_Thread_queue_Extract_priority_helper( tq, the_thread, TRUE );
(void) _Thread_queue_Enqueue_priority( tq, the_thread, &level_ignored );
}
_ISR_Enable( level );
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
* Thread Queue Handler
*
*
* COPYRIGHT (c) 1989-2007.
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be