summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2008-01-22 18:28:53 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2008-01-22 18:28:53 +0000
commit3168deaa10fae157b38a94c5204a66d28a43ad7a (patch)
tree0bda84e785960fa6641c2b167d626cf3271b3352
parent2008-01-22 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-3168deaa10fae157b38a94c5204a66d28a43ad7a.tar.bz2
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.
-rw-r--r--cpukit/ChangeLog31
-rw-r--r--cpukit/rtems/include/rtems/rtems/event.h17
-rw-r--r--cpukit/rtems/inline/rtems/rtems/eventset.inl2
-rw-r--r--cpukit/rtems/src/event.c4
-rw-r--r--cpukit/rtems/src/eventseize.c57
-rw-r--r--cpukit/rtems/src/eventsurrender.c79
-rw-r--r--cpukit/rtems/src/eventtimeout.c31
-rw-r--r--cpukit/score/Makefile.am12
-rw-r--r--cpukit/score/include/rtems/score/interr.h3
-rw-r--r--cpukit/score/include/rtems/score/thread.h23
-rw-r--r--cpukit/score/include/rtems/score/threadq.h12
-rw-r--r--cpukit/score/include/rtems/score/threadsync.h58
-rw-r--r--cpukit/score/include/rtems/score/tqdata.h16
-rw-r--r--cpukit/score/inline/rtems/score/threadq.inl10
-rw-r--r--cpukit/score/inline/rtems/score/tqdata.inl4
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/threadblockingoperationcancel.c81
-rw-r--r--cpukit/score/src/threadq.c25
-rw-r--r--cpukit/score/src/threadqdequeue.c21
-rw-r--r--cpukit/score/src/threadqdequeuefifo.c12
-rw-r--r--cpukit/score/src/threadqdequeuepriority.c27
-rw-r--r--cpukit/score/src/threadqenqueue.c27
-rw-r--r--cpukit/score/src/threadqenqueuefifo.c66
-rw-r--r--cpukit/score/src/threadqenqueuepriority.c76
-rw-r--r--cpukit/score/src/threadqextract.c2
-rw-r--r--cpukit/score/src/threadqextractfifo.c2
-rw-r--r--cpukit/score/src/threadqextractpriority.c2
-rw-r--r--cpukit/score/src/threadqextractwithproxy.c2
-rw-r--r--cpukit/score/src/threadqfirst.c2
-rw-r--r--cpukit/score/src/threadqfirstfifo.c2
-rw-r--r--cpukit/score/src/threadqfirstpriority.c2
-rw-r--r--cpukit/score/src/threadqflush.c2
-rw-r--r--cpukit/score/src/threadqrequeue.c39
-rw-r--r--cpukit/score/src/threadqtimeout.c2
34 files changed, 432 insertions, 323 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
index 754ee6517b..29b2767801 100644
--- a/cpukit/ChangeLog
+++ b/cpukit/ChangeLog
@@ -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.
diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h
index 4d2b4513fe..68687af31e 100644
--- a/cpukit/rtems/include/rtems/rtems/event.h
+++ b/cpukit/rtems/include/rtems/rtems/event.h
@@ -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>
@@ -50,18 +51,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
*
* DESCRIPTION:
@@ -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>
diff --git a/cpukit/rtems/inline/rtems/rtems/eventset.inl b/cpukit/rtems/inline/rtems/rtems/eventset.inl
index 05f0e805d4..dff78bdce0 100644
--- a/cpukit/rtems/inline/rtems/rtems/eventset.inl
+++ b/cpukit/rtems/inline/rtems/rtems/eventset.inl
@@ -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
diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c
index ebc5682cde..85d35829c2 100644
--- a/cpukit/rtems/src/event.c
+++ b/cpukit/rtems/src/event.c
@@ -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.
diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c
index d9e0797747..9abb54fa6a 100644
--- a/cpukit/rtems/src/eventseize.c
+++ b/cpukit/rtems/src/eventseize.c
@@ -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 );
}
diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c
index 4c2d3b12ce..5fb53922f3 100644
--- a/cpukit/rtems/src/eventsurrender.c
+++ b/cpukit/rtems/src/eventsurrender.c
@@ -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 );
diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c
index b01d8199ad..04abe71766 100644
--- a/cpukit/rtems/src/eventtimeout.c
+++ b/cpukit/rtems/src/eventtimeout.c
@@ -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 */
+ if ( !the_thread->Wait.count ) { /* verify thread is waiting */
+ _Thread_Unnest_dispatch();
+ _ISR_Enable( level );
+ return;
+ }
+
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;
+ 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;
}
- _ISR_Enable( level );
- } else {
- the_thread->Wait.return_code = RTEMS_TIMEOUT;
- _ISR_Enable( level );
- _Thread_Unblock( the_thread );
}
- }
- else {
- _ISR_Enable( level );
- }
+ the_thread->Wait.return_code = RTEMS_TIMEOUT;
+ _ISR_Enable( level );
+ _Thread_Unblock( the_thread );
_Thread_Unnest_dispatch();
break;
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 3446062f6b..3440af7090 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -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
diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h
index 323bc06818..a8792c334b 100644
--- a/cpukit/score/include/rtems/score/interr.h
+++ b/cpukit/score/include/rtems/score/interr.h
@@ -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;
/**
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 9b9f324b9e..fcf26c9507 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -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
diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h
index 7b609285eb..2345087c04 100644
--- a/cpukit/score/include/rtems/score/threadq.h
+++ b/cpukit/score/include/rtems/score/threadq.h
@@ -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
diff --git a/cpukit/score/include/rtems/score/threadsync.h b/cpukit/score/include/rtems/score/threadsync.h
new file mode 100644
index 0000000000..6902f7b33b
--- /dev/null
+++ b/cpukit/score/include/rtems/score/threadsync.h
@@ -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 */
diff --git a/cpukit/score/include/rtems/score/tqdata.h b/cpukit/score/include/rtems/score/tqdata.h
index b70124ff9e..5b7ce98a03 100644
--- a/cpukit/score/include/rtems/score/tqdata.h
+++ b/cpukit/score/include/rtems/score/tqdata.h
@@ -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
@@ -46,17 +47,6 @@ typedef enum {
} 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.
*
* There are four chains used to maintain a priority -- each chain
@@ -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
diff --git a/cpukit/score/inline/rtems/score/threadq.inl b/cpukit/score/inline/rtems/score/threadq.inl
index ccbb928849..5e0d921ac8 100644
--- a/cpukit/score/inline/rtems/score/threadq.inl
+++ b/cpukit/score/inline/rtems/score/threadq.inl
@@ -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 );
diff --git a/cpukit/score/inline/rtems/score/tqdata.inl b/cpukit/score/inline/rtems/score/tqdata.inl
index d1248f4b74..b063998f8e 100644
--- a/cpukit/score/inline/rtems/score/tqdata.inl
+++ b/cpukit/score/inline/rtems/score/tqdata.inl
@@ -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;
}
/**
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 040616aa6a..cb27e47d48 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -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
diff --git a/cpukit/score/src/threadblockingoperationcancel.c b/cpukit/score/src/threadblockingoperationcancel.c
new file mode 100644
index 0000000000..b2b7a22745
--- /dev/null
+++ b/cpukit/score/src/threadblockingoperationcancel.c
@@ -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
+
+}
diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c
index d17c3d8f7e..baa85a13e1 100644
--- a/cpukit/score/src/threadq.c
+++ b/cpukit/score/src/threadq.c
@@ -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;
+
+ if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
+ uint32_t index;
- 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;
+ 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 );
}
}
diff --git a/cpukit/score/src/threadqdequeue.c b/cpukit/score/src/threadqdequeue.c
index d5968b0210..160bd6e84c 100644
--- a/cpukit/score/src/threadqdequeue.c
+++ b/cpukit/score/src/threadqdequeue.c
@@ -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 );
}
diff --git a/cpukit/score/src/threadqdequeuefifo.c b/cpukit/score/src/threadqdequeuefifo.c
index 787ec41074..d494b90b85 100644
--- a/cpukit/score/src/threadqdequeuefifo.c
+++ b/cpukit/score/src/threadqdequeuefifo.c
@@ -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;
}
diff --git a/cpukit/score/src/threadqdequeuepriority.c b/cpukit/score/src/threadqdequeuepriority.c
index 4da18165d9..d9aa1b14f8 100644
--- a/cpukit/score/src/threadqdequeuepriority.c
+++ b/cpukit/score/src/threadqdequeuepriority.c
@@ -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:
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 2cc1141993..688962950a 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -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 );
}
diff --git a/cpukit/score/src/threadqenqueuefifo.c b/cpukit/score/src/threadqenqueuefifo.c
index c7260807ed..229261efad 100644
--- a/cpukit/score/src/threadqenqueuefifo.c
+++ b/cpukit/score/src/threadqenqueuefifo.c
@@ -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;
- _ISR_Enable( level );
- return;
- case THREAD_QUEUE_TIMEOUT:
- the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
- the_thread->Wait.queue = NULL;
+ the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
_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;
}
diff --git a/cpukit/score/src/threadqenqueuepriority.c b/cpukit/score/src/threadqenqueuepriority.c
index 9974a3a674..cad998cf87 100644
--- a/cpukit/score/src/threadqenqueuepriority.c
+++ b/cpukit/score/src/threadqenqueuepriority.c
@@ -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;
}
diff --git a/cpukit/score/src/threadqextract.c b/cpukit/score/src/threadqextract.c
index a8faef03f7..f971a7b970 100644
--- a/cpukit/score/src/threadqextract.c
+++ b/cpukit/score/src/threadqextract.c
@@ -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
diff --git a/cpukit/score/src/threadqextractfifo.c b/cpukit/score/src/threadqextractfifo.c
index f7ecf3e270..7fd6f41d34 100644
--- a/cpukit/score/src/threadqextractfifo.c
+++ b/cpukit/score/src/threadqextractfifo.c
@@ -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
diff --git a/cpukit/score/src/threadqextractpriority.c b/cpukit/score/src/threadqextractpriority.c
index ef45fb4423..739e6985c4 100644
--- a/cpukit/score/src/threadqextractpriority.c
+++ b/cpukit/score/src/threadqextractpriority.c
@@ -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
diff --git a/cpukit/score/src/threadqextractwithproxy.c b/cpukit/score/src/threadqextractwithproxy.c
index 14653091b3..5c24431ab5 100644
--- a/cpukit/score/src/threadqextractwithproxy.c
+++ b/cpukit/score/src/threadqextractwithproxy.c
@@ -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
diff --git a/cpukit/score/src/threadqfirst.c b/cpukit/score/src/threadqfirst.c
index bcbe759eda..9112b0ab72 100644
--- a/cpukit/score/src/threadqfirst.c
+++ b/cpukit/score/src/threadqfirst.c
@@ -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
diff --git a/cpukit/score/src/threadqfirstfifo.c b/cpukit/score/src/threadqfirstfifo.c
index b002f1f448..9163780c76 100644
--- a/cpukit/score/src/threadqfirstfifo.c
+++ b/cpukit/score/src/threadqfirstfifo.c
@@ -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
diff --git a/cpukit/score/src/threadqfirstpriority.c b/cpukit/score/src/threadqfirstpriority.c
index 81ac2742eb..442a4323b3 100644
--- a/cpukit/score/src/threadqfirstpriority.c
+++ b/cpukit/score/src/threadqfirstpriority.c
@@ -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
diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c
index ecb9b0df20..f609a0fc60 100644
--- a/cpukit/score/src/threadqflush.c
+++ b/cpukit/score/src/threadqflush.c
@@ -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
diff --git a/cpukit/score/src/threadqrequeue.c b/cpukit/score/src/threadqrequeue.c
index a536eecdcf..4c50565b86 100644
--- a/cpukit/score/src/threadqrequeue.c
+++ b/cpukit/score/src/threadqrequeue.c
@@ -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 );
}
}
diff --git a/cpukit/score/src/threadqtimeout.c b/cpukit/score/src/threadqtimeout.c
index ae11f0b40f..7b0fcd5061 100644
--- a/cpukit/score/src/threadqtimeout.c
+++ b/cpukit/score/src/threadqtimeout.c
@@ -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