[PATCH 4/8] score: Use a plain ticket lock for thread locks
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Jul 23 12:54:44 UTC 2015
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
More information about the devel
mailing list