summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/threadqimpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/include/rtems/score/threadqimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/threadqimpl.h333
1 files changed, 254 insertions, 79 deletions
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index 6eac3643f4..32217ad73e 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -20,6 +20,8 @@
#define _RTEMS_SCORE_THREADQIMPL_H
#include <rtems/score/threadq.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/rbtreeimpl.h>
#include <rtems/score/thread.h>
#ifdef __cplusplus
@@ -31,6 +33,31 @@ extern "C" {
*/
/**@{*/
+RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &the_thread_queue->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable( lock_context );
+ _Thread_queue_Acquire_critical( the_thread_queue, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable( &the_thread_queue->Lock, lock_context );
+}
+
/**
* The following type defines the callout used when a remote task
* is extracted from a local thread queue.
@@ -55,62 +82,191 @@ Thread_Control *_Thread_queue_Dequeue(
);
/**
- * @brief Blocks a thread and places it on a thread.
+ * @brief Blocks the thread and places it on the thread queue.
*
- * This routine blocks a thread, places it on a thread, and optionally
- * starts a timeout timer.
+ * This enqueues the thread on the thread queue, blocks the thread, and
+ * optionally starts the thread timer in case the timeout interval is not
+ * WATCHDOG_NO_TIMEOUT.
*
- * @param[in] the_thread_queue pointer to threadq
- * @param[in] the_thread the thread to enqueue
- * @param[in] state is the new state of the thread
- * @param[in] timeout interval to wait
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock and register it as the new thread lock.
+ * Thread dispatching is disabled before the thread queue lock is released.
+ * Thread dispatching is enabled once the sequence to block the thread is
+ * complete. The operation to enqueue the thread on the queue is protected by
+ * the thread queue lock. This makes it possible to use the thread queue lock
+ * to protect the state of objects embedding the thread queue and directly
+ * enter _Thread_queue_Enqueue_critical() in case the thread must block.
*
- * - INTERRUPT LATENCY:
- * + single case
+ * @code
+ * #include <rtems/score/threadqimpl.h>
+ * #include <rtems/score/statesimpl.h>
+ *
+ * typedef struct {
+ * Thread_queue_Control Queue;
+ * Thread_Control *owner;
+ * } Mutex;
+ *
+ * void _Mutex_Obtain( Mutex *mutex )
+ * {
+ * ISR_lock_Context lock_context;
+ * Thread_Control *executing;
+ *
+ * _Thread_queue_Acquire( &mutex->Queue, &lock_context );
+ *
+ * executing = _Thread_Executing;
+ *
+ * if ( mutex->owner == NULL ) {
+ * mutex->owner = executing;
+ * _Thread_queue_Release( &mutex->Queue, &lock_context );
+ * } else {
+ * _Thread_queue_Enqueue_critical(
+ * &mutex->Queue,
+ * executing,
+ * STATES_WAITING_FOR_MUTEX,
+ * WATCHDOG_NO_TIMEOUT,
+ * 0,
+ * &lock_context
+ * );
+ * }
+ * }
+ * @endcode
+ *
+ * @param[in] the_thread_queue The thread queue.
+ * @param[in] the_thread The thread to enqueue.
+ * @param[in] state The new state of the thread.
+ * @param[in] timeout Interval to wait. Use WATCHDOG_NO_TIMEOUT to block
+ * potentially forever.
+ * @param[in] timeout_code The return code in case a timeout occurs.
+ * @param[in] lock_context The lock context of the lock acquire.
*/
-void _Thread_queue_Enqueue(
+void _Thread_queue_Enqueue_critical(
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread,
States_Control state,
- Watchdog_Interval timeout
+ Watchdog_Interval timeout,
+ uint32_t timeout_code,
+ ISR_lock_Context *lock_context
);
/**
- * @brief Extracts thread from thread queue.
+ * @brief Acquires the thread queue lock and calls
+ * _Thread_queue_Enqueue_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread,
+ States_Control state,
+ Watchdog_Interval timeout,
+ uint32_t timeout_code
+)
+{
+ ISR_lock_Context lock_context;
+
+ _Thread_queue_Acquire( the_thread_queue, &lock_context );
+ _Thread_queue_Enqueue_critical(
+ the_thread_queue,
+ the_thread,
+ state,
+ timeout,
+ timeout_code,
+ &lock_context
+ );
+}
+
+/**
+ * @brief Extracts the thread from the thread queue, restores the default wait
+ * operations and restores the default thread lock.
*
- * This routine removes @a the_thread from @a the_thread_queue
- * and cancels any timeouts associated with this blocking.
+ * The caller must be the owner of the thread queue lock. The thread queue
+ * lock is not released.
*
- * @param[in] the_thread_queue is the pointer to the ThreadQ header
- * @param[in] the_thread is the pointer to a thread control block that
- * is to be removed
+ * @param[in] the_thread_queue The thread queue.
+ * @param[in] the_thread The thread to extract.
*/
-void _Thread_queue_Extract(
+void _Thread_queue_Extract_locked(
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread
);
/**
- * @brief Extracts thread from thread queue (w/return code).
+ * @brief Unblocks the thread which was on the thread queue before.
*
- * This routine removes @a the_thread from @a the_thread_queue
- * and cancels any timeouts associated with this blocking.
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock. Thread dispatching is disabled before the
+ * thread queue lock is released and an unblock is necessary. Thread
+ * dispatching is enabled once the sequence to unblock the thread is complete.
*
- * @param[in] the_thread_queue is the pointer to the ThreadQ header
- * @param[in] the_thread is the pointer to a thread control block that
- * is to be removed
- * @param[in] return_code specifies the status to be returned.
+ * @param[in] the_thread_queue The thread queue.
+ * @param[in] the_thread The thread to extract.
+ * @param[in] lock_context The lock context of the lock acquire.
+ */
+void _Thread_queue_Unblock_critical(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief Extracts the thread from the thread queue and unblocks it.
*
- * - INTERRUPT LATENCY:
- * + single case
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock and restore the default thread lock. Thread
+ * dispatching is disabled before the thread queue lock is released and an
+ * unblock is necessary. Thread dispatching is enabled once the sequence to
+ * unblock the thread is complete. This makes it possible to use the thread
+ * queue lock to protect the state of objects embedding the thread queue and
+ * directly enter _Thread_queue_Extract_critical() to finalize an operation in
+ * case a waiting thread exists.
+ *
+ * @code
+ * #include <rtems/score/threadqimpl.h>
+ *
+ * typedef struct {
+ * Thread_queue_Control Queue;
+ * Thread_Control *owner;
+ * } Mutex;
+ *
+ * void _Mutex_Release( Mutex *mutex )
+ * {
+ * ISR_lock_Context lock_context;
+ * Thread_Control *first;
+ *
+ * _Thread_queue_Acquire( &mutex->Queue, &lock_context );
+ *
+ * first = _Thread_queue_First_locked( &mutex->Queue );
+ * mutex->owner = first;
+ *
+ * if ( first != NULL ) {
+ * _Thread_queue_Extract_critical(
+ * &mutex->Queue,
+ * first,
+ * &lock_context
+ * );
+ * }
+ * @endcode
+ *
+ * @param[in] the_thread_queue The thread queue.
+ * @param[in] the_thread The thread to extract.
+ * @param[in] lock_context The lock context of the lock acquire.
*/
-void _Thread_queue_Extract_with_return_code(
+void _Thread_queue_Extract_critical(
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread,
- uint32_t return_code
+ ISR_lock_Context *lock_context
);
/**
+ * @brief Extracts thread from thread queue.
+ *
+ * This routine removes @a the_thread its thread queue
+ * and cancels any timeouts associated with this blocking.
+ *
+ * @param[in] the_thread is the pointer to a thread control block that
+ * is to be removed
+ */
+void _Thread_queue_Extract( Thread_Control *the_thread );
+
+/**
* @brief Extracts the_thread from the_thread_queue.
*
* This routine extracts the_thread from the_thread_queue
@@ -122,15 +278,34 @@ void _Thread_queue_Extract_with_proxy(
);
/**
- * @brief Gets a pointer to the "first" thread on the_thread_queue.
+ * @brief Returns the first thread on the thread queue if it exists, otherwise
+ * @c NULL.
+ *
+ * The caller must be the owner of the thread queue lock. The thread queue
+ * lock is not released.
+ *
+ * @param[in] the_thread_queue The thread queue.
*
- * This function returns a pointer to the "first" thread
- * on the_thread_queue. The "first" thread is selected
- * based on the discipline of the_thread_queue.
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread on the thread queue according to the enqueue
+ * order.
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ return ( *the_thread_queue->operations->first )( the_thread_queue );
+}
+
+/**
+ * @brief Returns the first thread on the thread queue if it exists, otherwise
+ * @c NULL.
*
- * @param[in] the_thread_queue pointer to thread queue
+ * @param[in] the_thread_queue The thread queue.
*
- * @retval first thread or NULL
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread on the thread queue according to the enqueue
+ * order.
*/
Thread_Control *_Thread_queue_First(
Thread_queue_Control *the_thread_queue
@@ -163,45 +338,50 @@ void _Thread_queue_Flush(
*
* @param[in] the_thread_queue is the pointer to a threadq header
* @param[in] the_discipline is the queueing discipline
- * @param[in] timeout_status is the return on a timeout
*/
void _Thread_queue_Initialize(
- Thread_queue_Control *the_thread_queue,
- Thread_queue_Disciplines the_discipline,
- uint32_t timeout_status
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Disciplines the_discipline
);
-/**
- * @brief Thread queue timeout.
- *
- * This routine is invoked when a task's request has not
- * been satisfied after the timeout interval specified to
- * enqueue. The task represented by ID will be unblocked and
- * its status code will be set in it's control block to indicate
- * that a timeout has occurred.
- *
- * @param[in] id thread id
- */
-void _Thread_queue_Timeout(
- Objects_Id id,
- void *ignored
-);
+#if defined(RTEMS_SMP)
+ #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
+ .Queues = { \
+ .Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queues.Fifo ) \
+ }, \
+ .operations = &_Thread_queue_Operations_FIFO, \
+ .Lock = ISR_LOCK_INITIALIZER( name ) \
+ }
-/**
- * @brief Process thread queue timeout.
- *
- * This is a shared helper routine which makes it easier to have multiple
- * object class specific timeout routines.
- *
- * @param[in] the_thread is the thread to extract
- *
- * @note This method assumes thread dispatching is disabled
- * and is expected to be called via the processing of
- * a clock tick.
- */
-void _Thread_queue_Process_timeout(
- Thread_Control *the_thread
-);
+ #define THREAD_QUEUE_PRIORIY_INITIALIZER( designator, name ) { \
+ .Queues = { \
+ .Priority = RBTREE_INITIALIZER_EMPTY( designator.Queues.Priority ) \
+ }, \
+ .operations = &_Thread_queue_Operations_priority, \
+ .Lock = ISR_LOCK_INITIALIZER( name ) \
+ }
+#else
+ #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
+ .Queues = { \
+ .Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queues.Fifo ) \
+ }, \
+ .operations = &_Thread_queue_Operations_FIFO \
+ }
+
+ #define THREAD_QUEUE_PRIORIY_INITIALIZER( designator, name ) { \
+ .Queues = { \
+ .Priority = RBTREE_INITIALIZER_EMPTY( designator.Queues.Priority ) \
+ }, \
+ .operations = &_Thread_queue_Operations_priority \
+ }
+#endif
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
+ Thread_queue_Control *the_thread_queue
+)
+{
+ _ISR_lock_Destroy( &the_thread_queue->Lock );
+}
/**
* @brief Compare two thread's priority for RBTree Insertion.
@@ -218,16 +398,11 @@ RBTree_Compare_result _Thread_queue_Compare_priority(
const RBTree_Node *right
);
-/**
- * This routine is invoked to indicate that the specified thread queue is
- * entering a critical section.
- */
-RTEMS_INLINE_ROUTINE void _Thread_queue_Enter_critical_section (
- Thread_queue_Control *the_thread_queue
-)
-{
- the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
-}
+extern const Thread_queue_Operations _Thread_queue_Operations_default;
+
+extern const Thread_queue_Operations _Thread_queue_Operations_FIFO;
+
+extern const Thread_queue_Operations _Thread_queue_Operations_priority;
/**@}*/