diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-10-11 09:59:17 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-09 15:47:12 +0100 |
commit | 45ed58bb0fb7288afca372a8a783cb67ca180bd1 (patch) | |
tree | 694169284c14b79e8687263ed70213207050b914 | |
parent | 3beb71bcd916198a09e7c404def6c183b95744c4 (diff) |
testsuites/validation/tc-score-tq-smp.c
-rw-r--r-- | testsuites/validation/tc-score-tq-smp.c | 106 |
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 ); } |