summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/score/threadq.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/include/rtems/score/threadq.h')
-rw-r--r--cpukit/include/rtems/score/threadq.h595
1 files changed, 595 insertions, 0 deletions
diff --git a/cpukit/include/rtems/score/threadq.h b/cpukit/include/rtems/score/threadq.h
new file mode 100644
index 0000000000..3e618bf5af
--- /dev/null
+++ b/cpukit/include/rtems/score/threadq.h
@@ -0,0 +1,595 @@
+/**
+ * @file
+ *
+ * @brief Constants and Structures Needed to Declare a Thread Queue
+ *
+ * This include file contains all the constants and structures
+ * needed to declare a thread queue.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * 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.
+ */
+
+#ifndef _RTEMS_SCORE_THREADQ_H
+#define _RTEMS_SCORE_THREADQ_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/rbtree.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Scheduler_Node;
+
+/**
+ * @defgroup ScoreThreadQueue Thread Queue Handler
+ *
+ * @ingroup Score
+ *
+ * This handler provides the capability to have threads block in
+ * ordered sets. The sets may be ordered using the FIFO or priority
+ * discipline.
+ */
+/**@{*/
+
+typedef struct _Thread_Control Thread_Control;
+
+typedef struct Thread_queue_Context Thread_queue_Context;
+
+typedef struct Thread_queue_Queue Thread_queue_Queue;
+
+typedef struct Thread_queue_Operations Thread_queue_Operations;
+
+/**
+ * @brief Thread queue enqueue callout.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread to enqueue.
+ * @param[in] cpu_self The current processor.
+ * @param[in] queue_context The thread queue context of the lock acquire.
+ *
+ * @see _Thread_queue_Context_set_enqueue_callout().
+ */
+typedef void ( *Thread_queue_Enqueue_callout )(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ struct Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue deadlock callout.
+ *
+ * @param the_thread The thread that detected the deadlock.
+ *
+ * @see _Thread_queue_Context_set_deadlock_callout().
+ */
+typedef void ( *Thread_queue_Deadlock_callout )(
+ Thread_Control *the_thread
+);
+
+#if defined(RTEMS_MULTIPROCESSING)
+/**
+ * @brief Multiprocessing (MP) support callout for thread queue operations.
+ *
+ * @param the_proxy The thread proxy of the thread queue operation. A thread
+ * control is actually a thread proxy if and only if
+ * _Objects_Is_local_id( the_proxy->Object.id ) is false.
+ * @param mp_id Object identifier of the object containing the thread queue.
+ *
+ * @see _Thread_queue_Context_set_MP_callout().
+ */
+typedef void ( *Thread_queue_MP_callout )(
+ Thread_Control *the_proxy,
+ Objects_Id mp_id
+);
+#endif
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief The thread queue gate is an SMP synchronization means.
+ *
+ * The gates are added to a list of requests. A busy wait is performed to make
+ * sure that preceding requests are carried out. Each predecessor notifies its
+ * successor about on request completion.
+ *
+ * @see _Thread_queue_Gate_add(), _Thread_queue_Gate_wait(), and
+ * _Thread_queue_Gate_open().
+ */
+typedef struct {
+ Chain_Node Node;
+
+ Atomic_Uint go_ahead;
+} Thread_queue_Gate;
+#endif
+
+typedef struct {
+ /**
+ * @brief The lock context for the thread queue acquire and release
+ * operations.
+ */
+ ISR_lock_Context Lock_context;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Data to support thread queue enqueue operations.
+ */
+ struct {
+ /**
+ * @brief Gate to synchronize thread wait lock requests.
+ *
+ * @see _Thread_Wait_acquire_critical() and _Thread_Wait_tranquilize().
+ */
+ Thread_queue_Gate Gate;
+
+ /**
+ * @brief The thread queue in case the thread is blocked on a thread queue.
+ */
+ Thread_queue_Queue *queue;
+ } Wait;
+#endif
+} Thread_queue_Lock_context;
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief A thread queue link from one thread to another specified by the
+ * thread queue owner and thread wait queue relationships.
+ */
+typedef struct {
+ /**
+ * @brief Node to register this link in the global thread queue links lookup
+ * tree.
+ */
+ RBTree_Node Registry_node;
+
+ /**
+ * @brief The source thread queue determined by the thread queue owner.
+ */
+ Thread_queue_Queue *source;
+
+ /**
+ * @brief The target thread queue determined by the thread wait queue of the
+ * source owner.
+ */
+ Thread_queue_Queue *target;
+
+ /**
+ * @brief Node to add this link to a thread queue path.
+ */
+ Chain_Node Path_node;
+
+ /**
+ * @brief The owner of this thread queue link.
+ */
+ Thread_Control *owner;
+
+ /**
+ * @brief The queue lock context used to acquire the thread wait lock of the
+ * owner.
+ */
+ Thread_queue_Lock_context Lock_context;
+} Thread_queue_Link;
+#endif
+
+/**
+ * @brief Thread queue context for the thread queue methods.
+ *
+ * @see _Thread_queue_Context_initialize().
+ */
+struct Thread_queue_Context {
+ /**
+ * @brief The lock context for the thread queue acquire and release
+ * operations.
+ */
+ Thread_queue_Lock_context Lock_context;
+
+ /**
+ * @brief The thread state for _Thread_queue_Enqueue().
+ */
+ States_Control thread_state;
+
+ /**
+ * @brief The enqueue callout for _Thread_queue_Enqueue().
+ *
+ * The callout is invoked after the release of the thread queue lock with
+ * thread dispatching disabled. Afterwards the thread is blocked. This
+ * callout must be used to install the thread watchdog for timeout handling.
+ *
+ * @see _Thread_queue_Enqueue_do_nothing_extra().
+ * _Thread_queue_Add_timeout_ticks(), and
+ * _Thread_queue_Add_timeout_realtime_timespec().
+ */
+ Thread_queue_Enqueue_callout enqueue_callout;
+
+ /**
+ * @brief Interval to wait.
+ *
+ * May be used by the enqueue callout to register a timeout handler.
+ */
+ union {
+ /**
+ * @brief The timeout in ticks.
+ */
+ Watchdog_Interval ticks;
+
+ /**
+ * @brief The timeout argument, e.g. pointer to struct timespec.
+ */
+ const void *arg;
+ } Timeout;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Representation of a thread queue path from a start thread queue to
+ * the terminal thread queue.
+ *
+ * The start thread queue is determined by the object on which a thread intends
+ * to block. The terminal thread queue is the thread queue reachable via
+ * thread queue links whose owner is not blocked on a thread queue. The thread
+ * queue links are determined by the thread queue owner and thread wait queue
+ * relationships.
+ */
+ struct {
+ /**
+ * @brief The chain of thread queue links defining the thread queue path.
+ */
+ Chain_Control Links;
+
+ /**
+ * @brief The start of a thread queue path.
+ */
+ Thread_queue_Link Start;
+
+ /**
+ * @brief In case of a deadlock, a link for the first thread on the path
+ * that tries to enqueue on a thread queue.
+ */
+ Thread_queue_Link Deadlock;
+ } Path;
+#endif
+
+ /**
+ * @brief Block to manage thread priority changes due to a thread queue
+ * operation.
+ */
+ struct {
+ /**
+ * @brief A priority action list.
+ */
+ Priority_Actions Actions;
+
+ /**
+ * @brief Count of threads to update the priority via
+ * _Thread_Priority_update().
+ */
+ size_t update_count;
+
+ /**
+ * @brief Threads to update the priority via _Thread_Priority_update().
+ *
+ * Currently, a maximum of two threads need an update in one rush, for
+ * example the thread of the thread queue operation and the owner of the
+ * thread queue.
+ */
+ Thread_Control *update[ 2 ];
+ } Priority;
+
+ /**
+ * @brief Invoked in case of a detected deadlock.
+ *
+ * Must be initialized for _Thread_queue_Enqueue() in case the
+ * thread queue may have an owner, e.g. for mutex objects.
+ *
+ * @see _Thread_queue_Context_set_deadlock_callout().
+ */
+ Thread_queue_Deadlock_callout deadlock_callout;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ /**
+ * @brief Callout to unblock the thread in case it is actually a thread
+ * proxy.
+ *
+ * This field is only used on multiprocessing configurations. Used by
+ * thread queue extract and unblock methods for objects with multiprocessing
+ * (MP) support.
+ *
+ * @see _Thread_queue_Context_set_MP_callout().
+ */
+ Thread_queue_MP_callout mp_callout;
+#endif
+};
+
+/**
+ * @brief Thread priority queue.
+ */
+typedef struct {
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Node to enqueue this queue in the FIFO chain of the corresponding
+ * heads structure.
+ *
+ * @see Thread_queue_Heads::Heads::Fifo.
+ */
+ Chain_Node Node;
+#endif
+
+ /**
+ * @brief The actual thread priority queue.
+ */
+ Priority_Aggregation Queue;
+
+ /**
+ * @brief This priority queue is added to a scheduler node of the owner in
+ * case of priority inheritance.
+ */
+ struct Scheduler_Node *scheduler_node;
+} Thread_queue_Priority_queue;
+
+/**
+ * @brief Thread queue heads.
+ *
+ * Each thread is equipped with spare thread queue heads in case it is not
+ * enqueued on a thread queue. The first thread enqueued on a thread queue
+ * will give its spare thread queue heads to that thread queue. The threads
+ * arriving at the queue will add their thread queue heads to the free chain of
+ * the queue heads provided by the first thread enqueued. Once a thread is
+ * dequeued it use the free chain to get new spare thread queue heads.
+ *
+ * Uses a leading underscore in the structure name to allow forward
+ * declarations in standard header files provided by Newlib and GCC.
+ */
+typedef struct _Thread_queue_Heads {
+ /** This union contains the data structures used to manage the blocked
+ * set of tasks which varies based upon the discipline.
+ */
+ union {
+ /**
+ * @brief This is the FIFO discipline list.
+ *
+ * On SMP configurations this FIFO is used to enqueue the per scheduler
+ * instance priority queues of this structure. This ensures FIFO fairness
+ * among the highest priority thread of each scheduler instance.
+ */
+ Chain_Control Fifo;
+
+#if !defined(RTEMS_SMP)
+ /**
+ * @brief This is the set of threads for priority discipline waiting.
+ */
+ Thread_queue_Priority_queue Priority;
+#endif
+ } Heads;
+
+ /**
+ * @brief A chain with free thread queue heads providing the spare thread
+ * queue heads for a thread once it is dequeued.
+ */
+ Chain_Control Free_chain;
+
+ /**
+ * @brief A chain node to add these thread queue heads to the free chain of
+ * the thread queue heads dedicated to the thread queue of an object.
+ */
+ Chain_Node Free_node;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief One priority queue per scheduler instance.
+ */
+ Thread_queue_Priority_queue Priority[ RTEMS_ZERO_LENGTH_ARRAY ];
+#endif
+} Thread_queue_Heads;
+
+#if defined(RTEMS_SMP)
+ #define THREAD_QUEUE_HEADS_SIZE( scheduler_count ) \
+ ( sizeof( Thread_queue_Heads ) \
+ + ( scheduler_count ) * sizeof( Thread_queue_Priority_queue ) )
+#else
+ #define THREAD_QUEUE_HEADS_SIZE( scheduler_count ) \
+ sizeof( Thread_queue_Heads )
+#endif
+
+struct Thread_queue_Queue {
+ /**
+ * @brief Lock to protect this thread queue.
+ *
+ * It may be used to protect additional state of the object embedding this
+ * thread queue.
+ *
+ * Must be the first component of this structure to be able to re-use
+ * implementation parts for structures defined by Newlib <sys/lock.h>.
+ *
+ * @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and
+ * _Thread_queue_Release().
+ */
+#if defined(RTEMS_SMP)
+ SMP_ticket_lock_Control Lock;
+#endif
+
+ /**
+ * @brief The thread queue heads.
+ *
+ * This pointer is NULL, if and only if no threads are enqueued. The first
+ * thread to enqueue will give its spare thread queue heads to this thread
+ * queue.
+ */
+ Thread_queue_Heads *heads;
+
+ /**
+ * @brief The thread queue owner.
+ */
+ Thread_Control *owner;
+
+ /**
+ * @brief The thread queue name.
+ */
+ const char *name;
+};
+
+/**
+ * @brief Thread queue action operation.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context providing the thread queue
+ * action set to perform. Returns the thread queue action set to perform on
+ * the thread queue owner or the empty set in case there is nothing to do.
+ */
+typedef void ( *Thread_queue_Priority_actions_operation )(
+ Thread_queue_Queue *queue,
+ Priority_Actions *priority_actions
+);
+
+/**
+ * @brief Thread queue enqueue operation.
+ *
+ * A potential thread to update the priority due to priority inheritance is
+ * returned via the thread queue context. This thread is handed over to
+ * _Thread_Priority_update().
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread to enqueue on the queue.
+ */
+typedef void ( *Thread_queue_Enqueue_operation )(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue extract operation.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread to extract from the thread queue.
+ */
+typedef void ( *Thread_queue_Extract_operation )(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue surrender operation.
+ *
+ * This operation must dequeue and return the first thread on the queue.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] heads The thread queue heads. It must not be NULL.
+ * @param[in] previous_owner The previous owner of the thread queue.
+ *
+ * @return The previous first thread on the queue.
+ */
+typedef Thread_Control *( *Thread_queue_Surrender_operation )(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue first operation.
+ *
+ * @param[in] heads The thread queue heads.
+ *
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread of the thread queue according to the insert
+ * order. This thread remains on the thread queue.
+ */
+typedef Thread_Control *( *Thread_queue_First_operation )(
+ Thread_queue_Heads *heads
+);
+
+/**
+ * @brief Thread queue operations.
+ *
+ * @see _Thread_wait_Set_operations().
+ */
+struct Thread_queue_Operations {
+ /**
+ * @brief Thread queue priority actions operation.
+ */
+ Thread_queue_Priority_actions_operation priority_actions;
+
+ /**
+ * @brief Thread queue enqueue operation.
+ *
+ * Called by object routines to enqueue the thread.
+ */
+ Thread_queue_Enqueue_operation enqueue;
+
+ /**
+ * @brief Thread queue extract operation.
+ *
+ * Called by object routines to extract a thread from a thread queue.
+ */
+ Thread_queue_Extract_operation extract;
+
+ /**
+ * @brief Thread queue surrender operation.
+ */
+ Thread_queue_Surrender_operation surrender;
+
+ /**
+ * @brief Thread queue first operation.
+ */
+ Thread_queue_First_operation first;
+};
+
+/**
+ * This is the structure used to manage sets of tasks which are blocked
+ * waiting to acquire a resource.
+ */
+typedef struct {
+#if defined(RTEMS_SMP)
+#if defined(RTEMS_DEBUG)
+ /**
+ * @brief The index of the owning processor of the thread queue lock.
+ *
+ * The thread queue lock may be acquired via the thread lock also. This path
+ * is not covered by this field. In case the lock is not owned directly via
+ * _Thread_queue_Acquire(), then the value of this field is
+ * SMP_LOCK_NO_OWNER.
+ *
+ * Must be before the queue component of this structure to be able to re-use
+ * implementation parts for structures defined by Newlib <sys/lock.h>.
+ */
+ uint32_t owner;
+#endif
+
+#if defined(RTEMS_PROFILING)
+ /**
+ * @brief SMP lock statistics in case SMP and profiling are enabled.
+ *
+ * Must be before the queue component of this structure to be able to re-use
+ * implementation parts for structures defined by Newlib <sys/lock.h>.
+ */
+ SMP_lock_Stats Lock_stats;
+#endif
+#endif
+
+ /**
+ * @brief The actual thread queue.
+ */
+ Thread_queue_Queue Queue;
+} Thread_queue_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */