summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/threadqimpl.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-04-24 12:02:20 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-19 12:00:45 +0200
commitcc366ec8c9ecaab838a745175a0d53a7a5db437e (patch)
tree330c714baf220f30a07ea57bd08c545a072a12d3 /cpukit/score/include/rtems/score/threadqimpl.h
parentscore: More thread queue operations (diff)
downloadrtems-cc366ec8c9ecaab838a745175a0d53a7a5db437e.tar.bz2
score: New thread queue implementation
Use thread wait flags for synchronization. The enqueue operation is now part of the initial critical section. This is the key change and enables fine grained locking on SMP for objects using a thread queue like semaphores and message queues. Update #2273.
Diffstat (limited to 'cpukit/score/include/rtems/score/threadqimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/threadqimpl.h189
1 files changed, 135 insertions, 54 deletions
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index 04e67309b2..9893aae8af 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -80,13 +80,54 @@ Thread_Control *_Thread_queue_Dequeue(
);
/**
- * @brief Blocks a thread and places it on a thread queue.
+ * @brief Blocks the thread and places it on the thread queue.
*
- * This routine blocks a thread, places it on a thread queue, and optionally
- * starts a watchdog in case the timeout interval is not WATCHDOG_NO_TIMEOUT.
+ * 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.
*
* 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.
+ *
+ * @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.
@@ -103,6 +144,10 @@ void _Thread_queue_Enqueue_critical(
ISR_lock_Context *lock_context
);
+/**
+ * @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,
@@ -123,33 +168,97 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
}
/**
- * @brief Extracts thread from thread queue.
+ * @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 its 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 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( Thread_Control *the_thread );
+void _Thread_queue_Extract_locked(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread
+);
+
+/**
+ * @brief Unblocks the thread which was on the thread queue before.
+ *
+ * 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 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.
+ *
+ * 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_critical(
+ Thread_queue_Control *the_thread_queue,
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+);
/**
- * @brief Extracts thread from thread queue (w/return code).
+ * @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
- * @param[in] return_code specifies the status to be returned.
- *
- * - INTERRUPT LATENCY:
- * + single case
*/
-void _Thread_queue_Extract_with_return_code(
- Thread_Control *the_thread,
- uint32_t return_code
-);
+void _Thread_queue_Extract( Thread_Control *the_thread );
/**
* @brief Extracts the_thread from the_thread_queue.
@@ -164,9 +273,10 @@ void _Thread_queue_Extract_with_proxy(
/**
* @brief Returns the first thread on the thread queue if it exists, otherwise
- * @c NULL (locked).
+ * @c NULL.
*
- * The caller must be the owner of the thread queue lock.
+ * 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.
*
@@ -174,9 +284,12 @@ void _Thread_queue_Extract_with_proxy(
* @retval first The first thread on the thread queue according to the enqueue
* order.
*/
-Thread_Control *_Thread_queue_First_locked(
+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
@@ -235,38 +348,6 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
}
/**
- * @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
-);
-
-/**
- * @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
-);
-
-/**
* @brief Compare two thread's priority for RBTree Insertion.
*
* @param[in] left points to the left thread's RBnode