summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-04 08:02:09 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-05 11:36:45 +0100
commit4c8a0acc3dd536b3a5684ced8df663931081ba09 (patch)
tree4a88d796319d3d047ff9a78985db73eb8e47a920
parentscore: Add thread acquire (diff)
downloadrtems-4c8a0acc3dd536b3a5684ced8df663931081ba09.tar.bz2
score: Add thread wait flags
Update #2273.
-rw-r--r--cpukit/score/include/rtems/score/thread.h30
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h161
-rw-r--r--cpukit/score/src/threadinitialize.c2
3 files changed, 193 insertions, 0 deletions
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 299bac6df5..4984949377 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 19c22bcc46..84c22f94ed 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 508636fa51..934fea9085 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;