summaryrefslogtreecommitdiffstats
path: root/cpukit
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 /cpukit
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.
Diffstat (limited to 'cpukit')
-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;