[PATCH 7/8] score: Add thread wait flags

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Mar 4 15:07:07 UTC 2015


Update #2273.
---
 cpukit/score/include/rtems/score/thread.h     |  30 +++++
 cpukit/score/include/rtems/score/threadimpl.h | 161 ++++++++++++++++++++++++++
 cpukit/score/src/threadinitialize.c           |   2 +
 3 files changed, 193 insertions(+)

diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 299bac6..4984949 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -21,6 +21,7 @@
 #ifndef _RTEMS_SCORE_THREAD_H
 #define _RTEMS_SCORE_THREAD_H
 
+#include <rtems/score/atomic.h>
 #include <rtems/score/context.h>
 #if defined(RTEMS_MULTIPROCESSING)
 #include <rtems/score/mppkt.h>
@@ -262,6 +263,25 @@ typedef union {
 } Thread_Wait_information_Object_argument_type;
 
 /**
+ * @brief This type is able to contain several flags used to control the wait
+ * class and state of a thread.
+ *
+ * The mutually exclusive wait class flags are
+ * - @ref THREAD_WAIT_CLASS_EVENT,
+ * - @ref THREAD_WAIT_CLASS_SYSTEM_EVENT, and
+ * - @ref THREAD_WAIT_CLASS_OBJECT.
+ *
+ * The mutually exclusive wait state flags are
+ * - @ref THREAD_WAIT_STATE_INTEND_TO_BLOCK,
+ * - @ref THREAD_WAIT_STATE_BLOCKED,
+ * - @ref THREAD_WAIT_STATE_SATISFIED,
+ * - @ref THREAD_WAIT_STATE_TIMEOUT,
+ * - @ref THREAD_WAIT_STATE_INTERRUPT_SATISFIED, and
+ * - @ref THREAD_WAIT_STATE_INTERRUPT_TIMEOUT,
+ */
+typedef unsigned int Thread_Wait_flags;
+
+/**
  *  @brief Information required to manage a thread while it is blocked.
  *
  *  This contains the information required to manage a thread while it is
@@ -288,6 +308,16 @@ typedef struct {
 
   /** This field points to the thread queue on which this thread is blocked. */
   Thread_queue_Control *queue;
+
+  /**
+   * @brief This field contains several flags used to control the wait class
+   * and state of a thread in case fine-grained locking is used.
+   */
+#if defined(RTEMS_SMP)
+  Atomic_Uint           flags;
+#else
+  Thread_Wait_flags     flags;
+#endif
 }   Thread_Wait_information;
 
 /**
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 19c22bc..84c22f9 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -923,6 +923,167 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources(
   return owns_resources;
 }
 
+/**
+ * @brief The initial thread wait flags value set by _Thread_Initialize().
+ */
+#define THREAD_WAIT_FLAGS_INITIAL 0x0U
+
+/**
+ * @brief Mask to get the thread wait state flags.
+ */
+#define THREAD_WAIT_STATE_MASK 0xffU
+
+/**
+ * @brief Indicates that the thread begins with the blocking operation.
+ *
+ * A blocking operation consists of an optional watchdog initialization and the
+ * setting of the appropriate thread blocking state with the corresponding
+ * scheduler block operation.
+ */
+#define THREAD_WAIT_STATE_INTEND_TO_BLOCK 0x1U
+
+/**
+ * @brief Indicates that the thread completed the blocking operation.
+ */
+#define THREAD_WAIT_STATE_BLOCKED 0x2U
+
+/**
+ * @brief Indicates that the thread progress condition is satisfied and it is
+ * ready to resume execution.
+ */
+#define THREAD_WAIT_STATE_SATISFIED 0x4U
+
+/**
+ * @brief Indicates that a timeout occurred and the thread is ready to resume
+ * execution.
+ */
+#define THREAD_WAIT_STATE_TIMEOUT 0x8U
+
+/**
+ * @brief Indicates that the thread progress condition was satisfied during the
+ * blocking operation and it is ready to resume execution.
+ */
+#define THREAD_WAIT_STATE_INTERRUPT_SATISFIED 0x10U
+
+/**
+ * @brief Indicates that a timeout occurred during the blocking operation and
+ * the thread is ready to resume execution.
+ */
+#define THREAD_WAIT_STATE_INTERRUPT_TIMEOUT 0x20U
+
+/**
+ * @brief Mask to get the thread wait class flags.
+ */
+#define THREAD_WAIT_CLASS_MASK 0xff00U
+
+/**
+ * @brief Indicates that the thread waits for an event.
+ */
+#define THREAD_WAIT_CLASS_EVENT 0x100U
+
+/**
+ * @brief Indicates that the thread waits for a system event.
+ */
+#define THREAD_WAIT_CLASS_SYSTEM_EVENT 0x200U
+
+/**
+ * @brief Indicates that the thread waits for a object.
+ */
+#define THREAD_WAIT_CLASS_OBJECT 0x400U
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_flags_set(
+  Thread_Control    *the_thread,
+  Thread_Wait_flags  flags
+)
+{
+#if defined(RTEMS_SMP)
+  _Atomic_Store_uint( &the_thread->Wait.flags, flags, ATOMIC_ORDER_RELAXED );
+#else
+  the_thread->Wait.flags = flags;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get(
+  const Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+  return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_RELAXED );
+#else
+  return the_thread->Wait.flags;
+#endif
+}
+
+/**
+ * @brief Tries to change the thread wait flags inside a critical section
+ * (interrupts disabled).
+ *
+ * In case the wait flags are equal to the expected wait flags, then the wait
+ * flags are set to the desired wait flags.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] expected_flags The expected wait flags.
+ * @param[in] desired_flags The desired wait flags.
+ *
+ * @retval true The wait flags were equal to the expected wait flags.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_critical(
+  Thread_Control    *the_thread,
+  Thread_Wait_flags  expected_flags,
+  Thread_Wait_flags  desired_flags
+)
+{
+#if defined(RTEMS_SMP)
+  return _Atomic_Compare_exchange_uint(
+    &the_thread->Wait.flags,
+    &expected_flags,
+    desired_flags,
+    ATOMIC_ORDER_RELAXED,
+    ATOMIC_ORDER_RELAXED
+  );
+#else
+  bool success = the_thread->Wait.flags == expected_flags;
+
+  if ( success ) {
+    the_thread->Wait.flags = desired_flags;
+  }
+
+  return success;
+#endif
+}
+
+/**
+ * @brief Tries to change the thread wait flags.
+ *
+ * @see _Thread_Wait_flags_try_change_critical().
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change(
+  Thread_Control    *the_thread,
+  Thread_Wait_flags  expected_flags,
+  Thread_Wait_flags  desired_flags
+)
+{
+  bool success;
+#if !defined(RTEMS_SMP)
+  ISR_Level level;
+
+  _ISR_Disable_without_giant( level );
+#endif
+
+  success = _Thread_Wait_flags_try_change_critical(
+    the_thread,
+    expected_flags,
+    desired_flags
+  );
+
+#if !defined(RTEMS_SMP)
+  _ISR_Enable_without_giant( level );
+#endif
+
+  return success;
+}
+
 RTEMS_INLINE_ROUTINE void _Thread_Debug_set_real_processor(
   Thread_Control  *the_thread,
   Per_CPU_Control *cpu
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 508636f..934fea9 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -200,6 +200,8 @@ bool _Thread_Initialize(
   the_thread->real_priority           = priority;
   the_thread->Start.initial_priority  = priority;
 
+  _Thread_Wait_flags_set( the_thread, THREAD_WAIT_FLAGS_INITIAL );
+
   _Scheduler_Node_initialize( scheduler, the_thread );
   scheduler_node_initialized = true;
 
-- 
1.8.4.5




More information about the devel mailing list