[PATCH 17/45] score: Generalize _Event_Timeout()
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri May 15 11:41:17 UTC 2015
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 5e6f2ea..084b39f 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 36b1964..6611a8d 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 5db118b..0000000
--- 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 <rtems/rtems/eventimpl.h>
-#include <rtems/score/threadimpl.h>
-
-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 3eb2caa..3547097 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 112bd22..1a73fda 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 3577a74..c266a9c 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 0000000..b6ce2d7
--- /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 <rtems/score/threadimpl.h>
+
+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 e9f813d..e4a2a94 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
--
1.8.4.5
More information about the devel
mailing list