This enables external libraries to use thread locks since they are independent of the actual RTEMS build configuration, e.g. profiling enabled or disabled. --- cpukit/score/include/rtems/score/thread.h | 20 ++++++- cpukit/score/include/rtems/score/threadimpl.h | 80 ++++++++++++++++---------- cpukit/score/include/rtems/score/threadq.h | 8 ++- cpukit/score/include/rtems/score/threadqimpl.h | 46 +++++++++++++-- cpukit/score/src/threadinitialize.c | 3 +- cpukit/score/src/threadq.c | 3 + cpukit/score/src/threadqenqueue.c | 2 +- cpukit/score/src/threadrestart.c | 3 +- cpukit/score/src/threadtimeout.c | 2 +- 9 files changed, 125 insertions(+), 42 deletions(-)
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index ac908e2..94ce31e 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 7b8f89c..0bf5cf4 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 7622551..8f2b138 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 cf3aeed..05c3d7d 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -38,23 +38,50 @@ 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_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 + ); +#endif } +#if 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 +91,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 +110,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 + ); } /** @@ -429,7 +460,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 7452c93..9a796e9 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 27d4d58..fc81409 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 1d1581a..960783c 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 5d80beb..6d90587 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 f69bc35..0e04998 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; -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel