summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-06-26 12:54:33 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-07-30 09:11:13 +0200
commit0e3c59d65c3d1d3351103abf743aa9702452343c (patch)
tree39b7187c20bad43b43f0999d55c957d29c0b8adc
parentscore: Add potpourri lock statistics (diff)
downloadrtems-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.h20
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h80
-rw-r--r--cpukit/score/include/rtems/score/threadq.h8
-rw-r--r--cpukit/score/include/rtems/score/threadqimpl.h73
-rw-r--r--cpukit/score/src/threadinitialize.c3
-rw-r--r--cpukit/score/src/threadq.c3
-rw-r--r--cpukit/score/src/threadqenqueue.c2
-rw-r--r--cpukit/score/src/threadrestart.c3
-rw-r--r--cpukit/score/src/threadtimeout.c2
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;