diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-06-26 12:54:33 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-07-30 09:11:13 +0200 |
commit | 0e3c59d65c3d1d3351103abf743aa9702452343c (patch) | |
tree | 39b7187c20bad43b43f0999d55c957d29c0b8adc | |
parent | score: Add potpourri lock statistics (diff) | |
download | rtems-0e3c59d65c3d1d3351103abf743aa9702452343c.tar.bz2 |
score: Use a plain ticket lock for thread locks
This enables external libraries to use thread locks since they are
independent of the actual RTEMS build configuration, e.g. profiling
enabled or disabled.
-rw-r--r-- | cpukit/score/include/rtems/score/thread.h | 20 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadimpl.h | 80 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadq.h | 8 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadqimpl.h | 73 | ||||
-rw-r--r-- | cpukit/score/src/threadinitialize.c | 3 | ||||
-rw-r--r-- | cpukit/score/src/threadq.c | 3 | ||||
-rw-r--r-- | cpukit/score/src/threadqenqueue.c | 2 | ||||
-rw-r--r-- | cpukit/score/src/threadrestart.c | 3 | ||||
-rw-r--r-- | cpukit/score/src/threadtimeout.c | 2 |
9 files changed, 149 insertions, 45 deletions
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index ac908e2b82..94ce31ed50 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -651,14 +651,30 @@ typedef struct { typedef struct { /** * @brief The current thread lock. + * + * This is a plain ticket lock without SMP lock statistics support. This + * enables external libraries to use thread locks since they are independent + * of the actual RTEMS build configuration, e.g. profiling enabled or + * disabled. */ - ISR_lock_Control *current; + SMP_ticket_lock_Control *current; /** * @brief The default thread lock in case the thread is not blocked on a * resource. */ - ISR_lock_Control Default; + SMP_ticket_lock_Control Default; + +#if defined(RTEMS_PROFILING) + /** + * @brief The thread lock statistics. + * + * These statistics are used by the executing thread in case it acquires a + * thread lock. Thus the statistics are an aggregation of acquire and + * release operations of diffent locks. + */ + SMP_lock_Stats Stats; +#endif /** * @brief Generation number to invalidate stale locks. diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 52a040cf6f..46568813a4 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -970,45 +970,54 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources( } /** - * @brief Acquires the default thread lock and returns the executing thread. + * @brief Acquires the default thread lock inside a critical section + * (interrupts disabled). * + * @param[in] the_thread The thread. * @param[in] lock_context The lock context used for the corresponding lock * release. * - * @return The executing thread. - * * @see _Thread_Lock_release_default(). */ -RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Lock_acquire_default_for_executing( +RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default_critical( + Thread_Control *the_thread, ISR_lock_Context *lock_context ) { - Thread_Control *executing; - - _ISR_lock_ISR_disable( lock_context ); - executing = _Thread_Executing; - _ISR_lock_Acquire( &executing->Lock.Default, lock_context ); - - return executing; + _Assert( _ISR_Get_level() != 0 ); +#if defined(RTEMS_SMP) + _SMP_ticket_lock_Acquire( + &the_thread->Lock.Default, + &_Thread_Executing->Lock.Stats, + &lock_context->Lock_context.Stats_context + ); +#else + (void) the_thread; + (void) lock_context; +#endif } /** - * @brief Acquires the default thread lock inside a critical section - * (interrupts disabled). + * @brief Acquires the default thread lock and returns the executing thread. * - * @param[in] the_thread The thread. * @param[in] lock_context The lock context used for the corresponding lock * release. * + * @return The executing thread. + * * @see _Thread_Lock_release_default(). */ -RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default_critical( - Thread_Control *the_thread, +RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Lock_acquire_default_for_executing( ISR_lock_Context *lock_context ) { - _Assert( _ISR_Get_level() != 0 ); - _ISR_lock_Acquire( &the_thread->Lock.Default, lock_context ); + Thread_Control *executing; + + _ISR_lock_ISR_disable( lock_context ); + executing = _Thread_Executing; + _Thread_Lock_acquire_default_critical( executing, lock_context ); + + return executing; } /** @@ -1025,7 +1034,8 @@ RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default( ISR_lock_Context *lock_context ) { - _ISR_lock_ISR_disable_and_acquire( &the_thread->Lock.Default, lock_context ); + _ISR_lock_ISR_disable( lock_context ); + _Thread_Lock_acquire_default_critical( the_thread, lock_context ); } /** @@ -1039,11 +1049,19 @@ RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default( * acquire. */ RTEMS_INLINE_ROUTINE void _Thread_Lock_release_critical( - ISR_lock_Control *lock, + void *lock, ISR_lock_Context *lock_context ) { - _ISR_lock_Release( lock, lock_context ); +#if defined(RTEMS_SMP) + _SMP_ticket_lock_Release( + lock, + &lock_context->Lock_context.Stats_context + ); +#else + (void) lock; + (void) lock_context; +#endif } /** @@ -1053,7 +1071,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Lock_release_critical( * @param[in] lock_context The lock context used for _Thread_Lock_acquire(). */ RTEMS_INLINE_ROUTINE void _Thread_Lock_release( - ISR_lock_Control *lock, + void *lock, ISR_lock_Context *lock_context ) { @@ -1110,13 +1128,13 @@ RTEMS_INLINE_ROUTINE void _Thread_Lock_release_default( * * @return The lock required by _Thread_Lock_release(). */ -RTEMS_INLINE_ROUTINE ISR_lock_Control *_Thread_Lock_acquire( +RTEMS_INLINE_ROUTINE void *_Thread_Lock_acquire( Thread_Control *the_thread, ISR_lock_Context *lock_context ) { #if defined(RTEMS_SMP) - ISR_lock_Control *lock; + SMP_ticket_lock_Control *lock; while ( true ) { uint32_t my_generation; @@ -1131,7 +1149,11 @@ RTEMS_INLINE_ROUTINE ISR_lock_Control *_Thread_Lock_acquire( _Atomic_Fence( ATOMIC_ORDER_ACQUIRE ); lock = the_thread->Lock.current; - _ISR_lock_Acquire( lock, lock_context ); + _SMP_ticket_lock_Acquire( + lock, + &_Thread_Executing->Lock.Stats, + &lock_context->Lock_context.Stats_context + ); /* * Ensure that we read the second lock generation after we obtained our @@ -1160,8 +1182,8 @@ RTEMS_INLINE_ROUTINE ISR_lock_Control *_Thread_Lock_acquire( * instead. */ RTEMS_INLINE_ROUTINE void _Thread_Lock_set_unprotected( - Thread_Control *the_thread, - ISR_lock_Control *new_lock + Thread_Control *the_thread, + SMP_ticket_lock_Control *new_lock ) { the_thread->Lock.current = new_lock; @@ -1196,8 +1218,8 @@ RTEMS_INLINE_ROUTINE void _Thread_Lock_set_unprotected( */ #if defined(RTEMS_SMP) RTEMS_INLINE_ROUTINE void _Thread_Lock_set( - Thread_Control *the_thread, - ISR_lock_Control *new_lock + Thread_Control *the_thread, + SMP_ticket_lock_Control *new_lock ) { ISR_lock_Context lock_context; diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index 7622551cf4..8f2b138709 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -75,7 +75,9 @@ typedef struct { * @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and * _Thread_queue_Release(). */ - ISR_LOCK_MEMBER( Lock ) +#if defined(RTEMS_SMP) + SMP_ticket_lock_Control Lock; +#endif } Thread_queue_Queue; /** @@ -191,6 +193,10 @@ typedef struct { */ Thread_queue_Queue Queue; +#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) + SMP_lock_Stats Lock_stats; +#endif + /** * @brief The operations for the actual thread queue. */ diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index cf3aeed053..22118aba61 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -38,23 +38,53 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize( ) { queue->heads = NULL; - _ISR_lock_Initialize( &queue->Lock, "Thread Queue" ); +#if defined(RTEMS_SMP) + _SMP_ticket_lock_Initialize( &queue->Lock ); +#endif } -RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_acquire_critical( +RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_do_acquire_critical( Thread_queue_Queue *queue, +#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) + SMP_lock_Stats *lock_stats, +#endif ISR_lock_Context *lock_context ) { - _ISR_lock_Acquire( &queue->Lock, lock_context ); +#if defined(RTEMS_SMP) + _SMP_ticket_lock_Acquire( + &queue->Lock, + lock_stats, + &lock_context->Lock_context.Stats_context + ); +#else + (void) queue; + (void) lock_context; +#endif } +#if defined(RTEMS_SMP) && defined( RTEMS_PROFILING ) + #define \ + _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \ + _Thread_queue_Queue_do_acquire_critical( queue, lock_stats, lock_context ) +#else + #define \ + _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \ + _Thread_queue_Queue_do_acquire_critical( queue, lock_context ) +#endif + RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release( Thread_queue_Queue *queue, ISR_lock_Context *lock_context ) { - _ISR_lock_Release_and_ISR_enable( &queue->Lock, lock_context ); +#if defined(RTEMS_SMP) + _SMP_ticket_lock_Release( + &queue->Lock, + &lock_context->Lock_context.Stats_context + ); +#endif + _ISR_lock_ISR_enable( lock_context ); } RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical( @@ -64,6 +94,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical( { _Thread_queue_Queue_acquire_critical( &the_thread_queue->Queue, + &the_thread_queue->Lock_stats, lock_context ); } @@ -82,7 +113,10 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Release( ISR_lock_Context *lock_context ) { - _Thread_queue_Queue_release( &the_thread_queue->Queue, lock_context ); + _Thread_queue_Queue_release( + &the_thread_queue->Queue, + lock_context + ); } /** @@ -397,11 +431,29 @@ void _Thread_queue_Initialize( Thread_queue_Disciplines the_discipline ); -#if defined(RTEMS_SMP) +#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) + #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ + .Queue = { \ + .heads = NULL, \ + .Lock = SMP_TICKET_LOCK_INITIALIZER, \ + }, \ + .Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \ + .operations = &_Thread_queue_Operations_FIFO \ + } + + #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ + .Queue = { \ + .heads = NULL, \ + .Lock = SMP_TICKET_LOCK_INITIALIZER, \ + }, \ + .Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \ + .operations = &_Thread_queue_Operations_priority \ + } +#elif defined(RTEMS_SMP) #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ .Queue = { \ .heads = NULL, \ - .Lock = ISR_LOCK_INITIALIZER( name ), \ + .Lock = SMP_TICKET_LOCK_INITIALIZER, \ }, \ .operations = &_Thread_queue_Operations_FIFO \ } @@ -409,7 +461,7 @@ void _Thread_queue_Initialize( #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ .Queue = { \ .heads = NULL, \ - .Lock = ISR_LOCK_INITIALIZER( name ), \ + .Lock = SMP_TICKET_LOCK_INITIALIZER, \ }, \ .operations = &_Thread_queue_Operations_priority \ } @@ -429,7 +481,10 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy( Thread_queue_Control *the_thread_queue ) { - _ISR_lock_Destroy( &the_thread_queue->Queue.Lock ); +#if defined(RTEMS_SMP) + _SMP_ticket_lock_Destroy( &the_thread_queue->Queue.Lock ); + _SMP_lock_Stats_destroy( &the_thread_queue->Lock_stats ); +#endif } /** diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 7452c932d8..9a796e9bcc 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -204,7 +204,8 @@ bool _Thread_Initialize( _Resource_Node_initialize( &the_thread->Resource_node ); _CPU_Context_Set_is_executing( &the_thread->Registers, false ); the_thread->Lock.current = &the_thread->Lock.Default; - _ISR_lock_Initialize( &the_thread->Lock.Default, "Thread Lock Default"); + _SMP_ticket_lock_Initialize( &the_thread->Lock.Default ); + _SMP_lock_Stats_initialize( &the_thread->Lock.Stats, "Thread Lock" ); _SMP_lock_Stats_initialize( &the_thread->Potpourri_stats, "Thread Potpourri" ); _Atomic_Init_uint(&the_thread->Lock.generation, 0); #endif diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c index 27d4d5860e..fc81409924 100644 --- a/cpukit/score/src/threadq.c +++ b/cpukit/score/src/threadq.c @@ -60,4 +60,7 @@ void _Thread_queue_Initialize( the_thread_queue->operations = operations; _Thread_queue_Queue_initialize( &the_thread_queue->Queue ); +#if defined(RTEMS_SMP) + _SMP_lock_Stats_initialize( &the_thread_queue->Lock_stats, "Thread Queue" ); +#endif } diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index 1d1581a2fb..960783c74c 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -168,7 +168,7 @@ void _Thread_queue_Extract_critical( void _Thread_queue_Extract( Thread_Control *the_thread ) { ISR_lock_Context lock_context; - ISR_lock_Control *lock; + void *lock; Thread_queue_Queue *queue; lock = _Thread_Lock_acquire( the_thread, &lock_context ); diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c index 5d80beb78c..6d90587353 100644 --- a/cpukit/score/src/threadrestart.c +++ b/cpukit/score/src/threadrestart.c @@ -129,7 +129,8 @@ static void _Thread_Free( Thread_Control *the_thread ) _Workspace_Free( the_thread->Start.tls_area ); #if defined(RTEMS_SMP) - _ISR_lock_Destroy( &the_thread->Lock.Default ); + _SMP_ticket_lock_Destroy( &the_thread->Lock.Default ); + _SMP_lock_Stats_destroy( &the_thread->Lock.Stats ); _SMP_lock_Stats_destroy( &the_thread->Potpourri_stats ); #endif diff --git a/cpukit/score/src/threadtimeout.c b/cpukit/score/src/threadtimeout.c index f69bc35ea2..0e04998b26 100644 --- a/cpukit/score/src/threadtimeout.c +++ b/cpukit/score/src/threadtimeout.c @@ -36,7 +36,7 @@ static void _Thread_Do_timeout( Thread_Control *the_thread ) void _Thread_Timeout( Objects_Id id, void *arg ) { Thread_Control *the_thread; - ISR_lock_Control *thread_lock; + void *thread_lock; ISR_lock_Context lock_context; Thread_Wait_flags wait_flags; Thread_Wait_flags wait_class; |