From 08fe84b5d7072b7809581b1a25954a3b221497a5 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 22 Apr 2015 10:06:05 +0200 Subject: score: Generalize _Event_Timeout() Add a thread wait timeout code. Replace _Event_Timeout() with a general purpose _Thread_Timeout() watchdog handler. Update #2273. --- cpukit/rtems/Makefile.am | 1 - cpukit/rtems/src/eventseize.c | 8 ++- cpukit/rtems/src/eventtimeout.c | 70 ------------------------- cpukit/score/Makefile.am | 1 + cpukit/score/include/rtems/score/thread.h | 5 ++ cpukit/score/include/rtems/score/threadimpl.h | 22 ++++++++ cpukit/score/src/threadtimeout.c | 74 +++++++++++++++++++++++++++ testsuites/sptests/spintrcritical10/init.c | 6 +-- 8 files changed, 112 insertions(+), 75 deletions(-) delete mode 100644 cpukit/rtems/src/eventtimeout.c create mode 100644 cpukit/score/src/threadtimeout.c diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index 5e6f2eafa0..084b39f8b3 100644 --- a/cpukit/rtems/Makefile.am +++ b/cpukit/rtems/Makefile.am @@ -210,7 +210,6 @@ librtems_a_SOURCES += src/eventreceive.c librtems_a_SOURCES += src/eventseize.c librtems_a_SOURCES += src/eventsend.c librtems_a_SOURCES += src/eventsurrender.c -librtems_a_SOURCES += src/eventtimeout.c librtems_a_SOURCES += src/systemeventsend.c librtems_a_SOURCES += src/systemeventreceive.c diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c index 36b1964820..6611a8d6f6 100644 --- a/cpukit/rtems/src/eventseize.c +++ b/cpukit/rtems/src/eventseize.c @@ -89,7 +89,13 @@ void _Event_Seize( _Giant_Acquire( cpu_self ); if ( ticks ) { - _Watchdog_Initialize( &executing->Timer, _Event_Timeout, 0, executing ); + _Thread_Wait_set_timeout_code( executing, RTEMS_TIMEOUT ); + _Watchdog_Initialize( + &executing->Timer, + _Thread_Timeout, + 0, + executing + ); _Watchdog_Insert_ticks( &executing->Timer, ticks ); } diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c deleted file mode 100644 index 5db118b183..0000000000 --- a/cpukit/rtems/src/eventtimeout.c +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file - * - * @brief Timeout Event - * @ingroup ClassicEvent - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include -#include - -void _Event_Timeout( - Objects_Id id, - void *arg -) -{ - Thread_Control *the_thread; - ISR_lock_Context lock_context; - Thread_Wait_flags wait_flags; - Thread_Wait_flags wait_class; - Thread_Wait_flags intend_to_block; - Thread_Wait_flags blocked; - bool success; - bool unblock; - - the_thread = arg; - _Thread_Lock_acquire_default( the_thread, &lock_context ); - - wait_flags = _Thread_Wait_flags_get( the_thread ); - wait_class = wait_flags & THREAD_WAIT_CLASS_MASK; - intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK; - blocked = wait_class | THREAD_WAIT_STATE_BLOCKED; - success = _Thread_Wait_flags_try_change_critical( - the_thread, - intend_to_block, - wait_class | THREAD_WAIT_STATE_READY_AGAIN - ); - - if ( success ) { - the_thread->Wait.return_code = RTEMS_TIMEOUT; - unblock = false; - } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) { - the_thread->Wait.return_code = RTEMS_TIMEOUT; - _Thread_Wait_flags_set( - the_thread, - wait_class | THREAD_WAIT_STATE_READY_AGAIN - ); - unblock = true; - } else { - unblock = false; - } - - _Thread_Lock_release_default( the_thread, &lock_context ); - - if ( unblock ) { - _Thread_Unblock( the_thread ); - } -} diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 3eb2caa902..35470972af 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -290,6 +290,7 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \ src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \ src/threadstartmultitasking.c src/iterateoverthreads.c libscore_a_SOURCES += src/threadglobalconstruction.c +libscore_a_SOURCES += src/threadtimeout.c libscore_a_SOURCES += src/threadyield.c if HAS_SMP diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 112bd22e63..1a73fdaa8a 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -354,6 +354,11 @@ typedef struct { */ uint32_t return_code; + /** + * @brief Code to set the timeout return code in _Thread_Timeout(). + */ + uint32_t timeout_code; + /** This field points to the thread queue on which this thread is blocked. */ Thread_queue_Control *queue; diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 3577a7493b..c266a9cce3 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -1257,6 +1257,28 @@ RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change( return success; } +/** + * @brief Sets the thread wait timeout code. + * + * @param[in] the_thread The thread. + * @param[in] timeout_code The new thread wait timeout code. + */ +RTEMS_INLINE_ROUTINE void _Thread_Wait_set_timeout_code( + Thread_Control *the_thread, + uint32_t timeout_code +) +{ + the_thread->Wait.timeout_code = timeout_code; +} + +/** + * @brief General purpose thread wait timeout. + * + * @param[in] id Unused. + * @param[in] arg The thread. + */ +void _Thread_Timeout( Objects_Id id, void *arg ); + RTEMS_INLINE_ROUTINE void _Thread_Debug_set_real_processor( Thread_Control *the_thread, Per_CPU_Control *cpu diff --git a/cpukit/score/src/threadtimeout.c b/cpukit/score/src/threadtimeout.c new file mode 100644 index 0000000000..b6ce2d7362 --- /dev/null +++ b/cpukit/score/src/threadtimeout.c @@ -0,0 +1,74 @@ +/** + * @file + * + * @brief Thread Wait Timeout + * + * @ingroup ScoreThread + */ + +/* + * 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.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include + +static void _Thread_Do_timeout( Thread_Control *the_thread ) +{ + the_thread->Wait.return_code = the_thread->Wait.timeout_code; + _Thread_Lock_restore_default( the_thread ); +} + +void _Thread_Timeout( Objects_Id id, void *arg ) +{ + Thread_Control *the_thread; + ISR_lock_Control *thread_lock; + ISR_lock_Context lock_context; + Thread_Wait_flags wait_flags; + Thread_Wait_flags wait_class; + Thread_Wait_flags intend_to_block; + Thread_Wait_flags blocked; + bool success; + bool unblock; + + the_thread = arg; + thread_lock = _Thread_Lock_acquire( the_thread, &lock_context ); + + wait_flags = _Thread_Wait_flags_get( the_thread ); + wait_class = wait_flags & THREAD_WAIT_CLASS_MASK; + intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK; + blocked = wait_class | THREAD_WAIT_STATE_BLOCKED; + success = _Thread_Wait_flags_try_change_critical( + the_thread, + intend_to_block, + wait_class | THREAD_WAIT_STATE_READY_AGAIN + ); + + if ( success ) { + _Thread_Do_timeout( the_thread ); + unblock = false; + } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) { + _Thread_Wait_flags_set( + the_thread, + wait_class | THREAD_WAIT_STATE_READY_AGAIN + ); + _Thread_Do_timeout( the_thread ); + unblock = true; + } else { + unblock = false; + } + + _Thread_Lock_release( thread_lock, &lock_context ); + + if ( unblock ) { + _Thread_Unblock( the_thread ); + } +} diff --git a/testsuites/sptests/spintrcritical10/init.c b/testsuites/sptests/spintrcritical10/init.c index e9f813d521..e4a2a940a6 100644 --- a/testsuites/sptests/spintrcritical10/init.c +++ b/testsuites/sptests/spintrcritical10/init.c @@ -78,7 +78,7 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(0, thread); + _Thread_Timeout(0, thread); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN @@ -175,7 +175,7 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(0, thread); + _Thread_Timeout(0, thread); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == EVENTS @@ -251,7 +251,7 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(0, thread); + _Thread_Timeout(0, thread); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF -- cgit v1.2.3