summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-10-11 09:59:17 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-09 15:47:12 +0100
commit45ed58bb0fb7288afca372a8a783cb67ca180bd1 (patch)
tree694169284c14b79e8687263ed70213207050b914
parent3beb71bcd916198a09e7c404def6c183b95744c4 (diff)
testsuites/validation/tc-score-tq-smp.c
-rw-r--r--testsuites/validation/tc-score-tq-smp.c106
1 files changed, 69 insertions, 37 deletions
diff --git a/testsuites/validation/tc-score-tq-smp.c b/testsuites/validation/tc-score-tq-smp.c
index c0cc36db7a..f163a34e85 100644
--- a/testsuites/validation/tc-score-tq-smp.c
+++ b/testsuites/validation/tc-score-tq-smp.c
@@ -69,16 +69,22 @@
*
* This test case performs the following actions:
*
- * - Create two worker threads and a mutex. Use the mutex and the worker to do
- * a thread priority change in parallel with a thread queue extraction.
+ * - Create two or three worker threads and a mutex. Use the mutex and the
+ * worker to do a thread priority change in parallel with a thread queue
+ * extraction.
*
- * - Create and start worker A on a second processor. Let it obtain the
- * mutex.
+ * - Create a mutex and let the runner obtain it.
+ *
+ * - Create and start worker A on a second processor. mutex. Let it wait on
+ * the barrier.
+ *
+ * - If there are more than two processors, then create and start also worker
+ * C. Let it wait on the barrier.
*
* - Create and start worker B. Let it try to obtain the mutex which is
- * owned by worker A. Delete worker B to extract it from the thread queue.
- * Wrap the thread queue extract operation to do a parallel thread priority
- * change carried out by worker A.
+ * owned by the runner. Delete worker B to extract it from the thread
+ * queue. Wrap the thread queue extract operation to do a parallel thread
+ * priority change carried out by worker A (and maybe C).
*
* - Clean up all used resources.
*
@@ -161,6 +167,11 @@ typedef struct {
rtems_id mutex_d_id;
/**
+ * @brief This member contains the count of processors used by the test.
+ */
+ uint32_t used_cpus;
+
+ /**
* @brief This member contains the thread queue of the mutex.
*/
Thread_queue_Queue *thread_queue;
@@ -227,26 +238,27 @@ static void Extract( void *arg )
ctx = arg;
- /* PC1 */
- _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, 2 );
+ /* PC0 */
+ _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, ctx->used_cpus );
/*
- * Ensure that worker A acquired the thread wait lock of worker B.
+ * Ensure that worker A (and maybe C) acquired the thread wait lock of
+ * worker B.
*/
- TicketLockWaitForOthers( &ctx->thread_queue->Lock, 1 );
+ TicketLockWaitForOthers( &ctx->thread_queue->Lock, ctx->used_cpus - 1 );
/*
* Continue with the thread queue extraction. The thread wait lock of
* worker B will be changed back to the default thread wait lock. This
- * will cause worker A to release the thread queue lock and acquire the
- * default thread wait lock of worker B instead to carry out the priority
- * change.
+ * will cause worker A (and maybe C) to release the thread queue lock and
+ * acquire the default thread wait lock of worker B instead to carry out
+ * the priority change.
*
* See also _Thread_Wait_acquire_critical().
*/
}
-static void PriorityChangeWorkerA( rtems_task_argument arg )
+static void PriorityChangeWorker( rtems_task_argument arg )
{
Context *ctx;
SMP_barrier_State state;
@@ -254,24 +266,18 @@ static void PriorityChangeWorkerA( rtems_task_argument arg )
ctx = (Context *) arg;
_SMP_barrier_State_initialize( &state );
- ObtainMutex( ctx->mutex_a_id );
-
/* PC0 */
- _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
-
- /* PC1 */
- _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+ _SMP_barrier_Wait( &ctx->barrier, &state, ctx->used_cpus );
SetPriority( ctx->worker_b_id, PRIO_VERY_HIGH );
- ReleaseMutex( ctx->mutex_a_id );
- /* PC2 */
- _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+ /* PC1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, ctx->used_cpus );
(void) ReceiveAnyEvents();
}
-static void PriorityChangeWorkerB( rtems_task_argument arg )
+static void MutexObtainWorker( rtems_task_argument arg )
{
Context *ctx;
@@ -359,8 +365,9 @@ static void DeadlockWorkerE( rtems_task_argument arg )
}
/**
- * @brief Create two worker threads and a mutex. Use the mutex and the worker
- * to do a thread priority change in parallel with a thread queue extraction.
+ * @brief Create two or three worker threads and a mutex. Use the mutex and
+ * the worker to do a thread priority change in parallel with a thread queue
+ * extraction.
*/
static void ScoreTqValSmp_Action_0( ScoreTqValSmp_Context *ctx )
{
@@ -368,38 +375,63 @@ static void ScoreTqValSmp_Action_0( ScoreTqValSmp_Context *ctx )
_SMP_barrier_State_initialize( &ctx->barrier_state );
WrapThreadQueueInitialize( &ctx->wrap, Extract, ctx );
- ctx->mutex_a_id = CreateMutex();
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ ctx->used_cpus = 3;
+ } else {
+ ctx->used_cpus = 2;
+ }
+
+ /*
+ * Create a mutex and let the runner obtain it.
+ */
+ ctx->mutex_a_id = CreateMutexNoProtocol();
ctx->thread_queue = GetMutexThreadQueue( ctx->mutex_a_id );
+ ObtainMutex( ctx->mutex_a_id );
/*
- * Create and start worker A on a second processor. Let it obtain the mutex.
+ * Create and start worker A on a second processor. mutex. Let it wait on
+ * the barrier.
*/
ctx->worker_a_id = CreateTask( "WRKA", PRIO_NORMAL );
SetScheduler( ctx->worker_a_id, SCHEDULER_B_ID, PRIO_NORMAL );
- StartTask( ctx->worker_a_id, PriorityChangeWorkerA, ctx );
+ StartTask( ctx->worker_a_id, PriorityChangeWorker, ctx );
- /* PC0 */
- _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, 2 );
+ /*
+ * If there are more than two processors, then create and start also worker
+ * C. Let it wait on the barrier.
+ */
+ if ( ctx->used_cpus > 2 ) {
+ ctx->worker_c_id = CreateTask( "WRKC", PRIO_NORMAL );
+ SetScheduler( ctx->worker_c_id, SCHEDULER_C_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_c_id, PriorityChangeWorker, ctx );
+ }
/*
* Create and start worker B. Let it try to obtain the mutex which is owned
- * by worker A. Delete worker B to extract it from the thread queue. Wrap
+ * by the runner. Delete worker B to extract it from the thread queue. Wrap
* the thread queue extract operation to do a parallel thread priority change
- * carried out by worker A.
+ * carried out by worker A (and maybe C).
*/
ctx->worker_b_id = CreateTask( "WRKB", PRIO_HIGH );
- StartTask( ctx->worker_b_id, PriorityChangeWorkerB, ctx );
+ StartTask( ctx->worker_b_id, MutexObtainWorker, ctx );
WrapThreadQueueExtractDirect( &ctx->wrap, GetThread( ctx->worker_b_id ) );
DeleteTask( ctx->worker_b_id );
/*
* Clean up all used resources.
*/
- /* PC2 */
- _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, 2 );
+ /* PC1 */
+ _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, ctx->used_cpus );
WaitForExecutionStop( ctx->worker_a_id );
DeleteTask( ctx->worker_a_id );
+
+ if ( ctx->used_cpus > 2 ) {
+ WaitForExecutionStop( ctx->worker_c_id );
+ DeleteTask( ctx->worker_c_id );
+ }
+
+ ReleaseMutex( ctx->mutex_a_id );
DeleteMutex( ctx->mutex_a_id );
WrapThreadQueueDestroy( &ctx->wrap );
}