diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-04-23 10:01:22 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-05-19 12:00:45 +0200 |
commit | 02c4c441a51b43b55608893efa4a80a62bb9d4d5 (patch) | |
tree | 709655b1c53afc3ff981890989a5290d1c400ad2 /cpukit/score/include | |
parent | score: Generalize _Event_Timeout() (diff) | |
download | rtems-02c4c441a51b43b55608893efa4a80a62bb9d4d5.tar.bz2 |
score: Add Thread_queue_Control::Lock
Move the complete thread queue enqueue procedure into
_Thread_queue_Enqueue_critical(). It is possible to use the thread
queue lock to protect state of the object embedding the thread queue.
This enables per object fine grained locking in the future.
Delete _Thread_queue_Enter_critical_section().
Update #2273.
Diffstat (limited to 'cpukit/score/include')
-rw-r--r-- | cpukit/score/include/rtems/score/corebarrierimpl.h | 8 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/coremuteximpl.h | 5 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/corerwlockimpl.h | 8 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/coresemimpl.h | 19 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadq.h | 13 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadqimpl.h | 114 |
6 files changed, 132 insertions, 35 deletions
diff --git a/cpukit/score/include/rtems/score/corebarrierimpl.h b/cpukit/score/include/rtems/score/corebarrierimpl.h index 124ecabf05..e8b330dcb6 100644 --- a/cpukit/score/include/rtems/score/corebarrierimpl.h +++ b/cpukit/score/include/rtems/score/corebarrierimpl.h @@ -21,6 +21,7 @@ #include <rtems/score/corebarrier.h> #include <rtems/score/thread.h> +#include <rtems/score/threadqimpl.h> #include <rtems/score/watchdog.h> #ifdef __cplusplus @@ -83,6 +84,13 @@ void _CORE_barrier_Initialize( CORE_barrier_Attributes *the_barrier_attributes ); +RTEMS_INLINE_ROUTINE void _CORE_barrier_Destroy( + CORE_barrier_Control *the_barrier +) +{ + _Thread_queue_Destroy( &the_barrier->Wait_queue ); +} + /** * @brief Wait for the barrier. * diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h index e019b0abab..a6811680ff 100644 --- a/cpukit/score/include/rtems/score/coremuteximpl.h +++ b/cpukit/score/include/rtems/score/coremuteximpl.h @@ -119,6 +119,11 @@ CORE_mutex_Status _CORE_mutex_Initialize( bool initially_locked ); +RTEMS_INLINE_ROUTINE void _CORE_mutex_Destroy( CORE_mutex_Control *the_mutex ) +{ + _Thread_queue_Destroy( &the_mutex->Wait_queue ); +} + /** * @brief Attempt to receive a unit from the_mutex. * diff --git a/cpukit/score/include/rtems/score/corerwlockimpl.h b/cpukit/score/include/rtems/score/corerwlockimpl.h index 331510ba02..e619574d89 100644 --- a/cpukit/score/include/rtems/score/corerwlockimpl.h +++ b/cpukit/score/include/rtems/score/corerwlockimpl.h @@ -21,6 +21,7 @@ #include <rtems/score/corerwlock.h> #include <rtems/score/thread.h> +#include <rtems/score/threadqimpl.h> #include <rtems/score/watchdog.h> #ifdef __cplusplus @@ -87,6 +88,13 @@ void _CORE_RWLock_Initialize( CORE_RWLock_Attributes *the_rwlock_attributes ); +RTEMS_INLINE_ROUTINE void _CORE_RWLock_Destroy( + CORE_RWLock_Control *the_rwlock +) +{ + _Thread_queue_Destroy( &the_rwlock->Wait_queue ); +} + /** * @brief Obtain RWLock for reading. * diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h index 6a3a212f34..fac9f689e4 100644 --- a/cpukit/score/include/rtems/score/coresemimpl.h +++ b/cpukit/score/include/rtems/score/coresemimpl.h @@ -98,6 +98,13 @@ void _CORE_semaphore_Initialize( uint32_t initial_value ); +RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy( + CORE_semaphore_Control *the_semaphore +) +{ + _Thread_queue_Destroy( &the_semaphore->Wait_queue ); +} + #if defined(RTEMS_SCORE_CORESEM_ENABLE_SEIZE_BODY) /** * This routine attempts to receive a unit from @a the_semaphore. @@ -234,16 +241,14 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize_isr_disable( } _Thread_Disable_dispatch(); - _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue ); - executing->Wait.queue = &the_semaphore->Wait_queue; - executing->Wait.id = id; - _ISR_lock_ISR_enable( lock_context ); - - _Thread_queue_Enqueue( + executing->Wait.id = id; + _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context ); + _Thread_queue_Enqueue_critical( &the_semaphore->Wait_queue, executing, STATES_WAITING_FOR_SEMAPHORE, - timeout + timeout, + lock_context ); _Thread_Enable_dispatch(); } diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index 00b9221356..1f99ffde04 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -20,6 +20,7 @@ #define _RTEMS_SCORE_THREADQ_H #include <rtems/score/chain.h> +#include <rtems/score/isrlock.h> #include <rtems/score/states.h> #include <rtems/score/threadsync.h> #include <rtems/score/rbtree.h> @@ -62,6 +63,18 @@ typedef struct { /** This is the set of threads for priority discipline waiting. */ RBTree_Control Priority; } Queues; + + /** + * @brief Lock to protect this thread queue. + * + * It may be used to protect additional state of the object embedding this + * thread queue. + * + * @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and + * _Thread_queue_Release(). + */ + ISR_LOCK_MEMBER( Lock ) + /** This field is used to manage the critical section. */ Thread_blocking_operation_States sync_state; /** This field indicates the thread queue's blocking discipline. */ diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 6fc38cfa5b..3595dc5d85 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -31,6 +31,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,26 +80,48 @@ Thread_Control *_Thread_queue_Dequeue( ); /** - * @brief Blocks a thread and places it on a thread. + * @brief Blocks a thread and places it on a thread queue. * - * This routine blocks a thread, places it on a thread, and optionally - * starts a timeout timer. + * 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. * - * @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. * - * - INTERRUPT LATENCY: - * + single case + * @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] 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, + ISR_lock_Context *lock_context ); +RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + States_Control state, + Watchdog_Interval timeout +) +{ + ISR_lock_Context lock_context; + + _Thread_queue_Acquire( the_thread_queue, &lock_context ); + _Thread_queue_Enqueue_critical( + the_thread_queue, + the_thread, + state, + timeout, + &lock_context + ); +} + /** * @brief Extracts thread from thread queue. * @@ -116,15 +163,30 @@ 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 (locked). + * + * The caller must be the owner of the thread queue lock. + * + * @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. + */ +Thread_Control *_Thread_queue_First_locked( + Thread_queue_Control *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 @@ -165,6 +227,13 @@ void _Thread_queue_Initialize( uint32_t timeout_status ); +RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy( + Thread_queue_Control *the_thread_queue +) +{ + _ISR_lock_Destroy( &the_thread_queue->Lock ); +} + /** * @brief Thread queue timeout. * @@ -212,17 +281,6 @@ 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; -} - /**@}*/ #ifdef __cplusplus |