From 42c3b3be87cfda0c8bbd16d4a07dda0ece1d80ee Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 12 Aug 2021 15:54:59 +0200 Subject: mtx-seize --- testsuites/validation/tr-mtx-seize-try.c | 18 +-- testsuites/validation/tr-mtx-seize-try.h | 6 +- testsuites/validation/tr-mtx-seize-wait.c | 185 +++++++++++++++++++++++------- testsuites/validation/tr-mtx-seize-wait.h | 15 ++- 4 files changed, 168 insertions(+), 56 deletions(-) diff --git a/testsuites/validation/tr-mtx-seize-try.c b/testsuites/validation/tr-mtx-seize-try.c index a9e2c918a4..c7ac9b3745 100644 --- a/testsuites/validation/tr-mtx-seize-try.c +++ b/testsuites/validation/tr-mtx-seize-try.c @@ -132,9 +132,9 @@ static const char * const ScoreMtxReqSeizeTry_PreDesc_Owner[] = { }; static const char * const ScoreMtxReqSeizeTry_PreDesc_Priority[] = { - "Higher", - "Equal", - "Lower", + "LT", + "EQ", + "GT", "NA" }; @@ -193,16 +193,16 @@ static void ScoreMtxReqSeizeTry_Pre_Priority_Prepare( ) { switch ( state ) { - case ScoreMtxReqSeizeTry_Pre_Priority_Higher: { + case ScoreMtxReqSeizeTry_Pre_Priority_LT: { /* * Where the mutex provides a priority ceiling, while the calling thread - * has a current priority greater than the priority ceiling. + * has a current priority less than the priority ceiling. */ ctx->priority_before = ctx->tq_ctx->priority_ceiling - 1; break; } - case ScoreMtxReqSeizeTry_Pre_Priority_Equal: { + case ScoreMtxReqSeizeTry_Pre_Priority_EQ: { /* * Where the mutex provides a priority ceiling, while the calling thread * has a current priority equal to the priority ceiling. @@ -211,10 +211,10 @@ static void ScoreMtxReqSeizeTry_Pre_Priority_Prepare( break; } - case ScoreMtxReqSeizeTry_Pre_Priority_Lower: { + case ScoreMtxReqSeizeTry_Pre_Priority_GT: { /* * Where the mutex provides a priority ceiling, while the calling thread - * has a current priority lower than the priority ceiling. + * has a current priority greater than the priority ceiling. */ ctx->priority_before = ctx->tq_ctx->priority_ceiling + 1; break; @@ -539,7 +539,7 @@ void ScoreMtxReqSeizeTry_Run( TQMtxContext *tq_ctx ) ++ctx->pcs[ 0 ] ) { for ( - ctx->pcs[ 1 ] = ScoreMtxReqSeizeTry_Pre_Priority_Higher; + ctx->pcs[ 1 ] = ScoreMtxReqSeizeTry_Pre_Priority_LT; ctx->pcs[ 1 ] < ScoreMtxReqSeizeTry_Pre_Priority_NA; ++ctx->pcs[ 1 ] ) { diff --git a/testsuites/validation/tr-mtx-seize-try.h b/testsuites/validation/tr-mtx-seize-try.h index 923200ae14..6340e69fe9 100644 --- a/testsuites/validation/tr-mtx-seize-try.h +++ b/testsuites/validation/tr-mtx-seize-try.h @@ -71,9 +71,9 @@ typedef enum { } ScoreMtxReqSeizeTry_Pre_Owner; typedef enum { - ScoreMtxReqSeizeTry_Pre_Priority_Higher, - ScoreMtxReqSeizeTry_Pre_Priority_Equal, - ScoreMtxReqSeizeTry_Pre_Priority_Lower, + ScoreMtxReqSeizeTry_Pre_Priority_LT, + ScoreMtxReqSeizeTry_Pre_Priority_EQ, + ScoreMtxReqSeizeTry_Pre_Priority_GT, ScoreMtxReqSeizeTry_Pre_Priority_NA } ScoreMtxReqSeizeTry_Pre_Priority; diff --git a/testsuites/validation/tr-mtx-seize-wait.c b/testsuites/validation/tr-mtx-seize-wait.c index 4ca89c7e0b..cc80336355 100644 --- a/testsuites/validation/tr-mtx-seize-wait.c +++ b/testsuites/validation/tr-mtx-seize-wait.c @@ -79,7 +79,7 @@ typedef struct { * @brief If this member is true, then the calling thread shall be the owner * of the mutex. */ - bool owner_self;; + bool owner_caller;; /** * @brief If this member is true, then a thread other than the calling thread @@ -124,7 +124,7 @@ typedef struct { /** * @brief This member defines the pre-condition states for the next action. */ - size_t pcs[ 1 ]; + size_t pcs[ 2 ]; /** * @brief This member indicates if the test action loop is currently @@ -138,14 +138,22 @@ static ScoreMtxReqSeizeWait_Context static const char * const ScoreMtxReqSeizeWait_PreDesc_Owner[] = { "No", - "Self", + "Caller", "Other", "Deadlock", "NA" }; +static const char * const ScoreMtxReqSeizeWait_PreDesc_Priority[] = { + "LT", + "EQ", + "GT", + "NA" +}; + static const char * const * const ScoreMtxReqSeizeWait_PreDesc[] = { ScoreMtxReqSeizeWait_PreDesc_Owner, + ScoreMtxReqSeizeWait_PreDesc_Priority, NULL }; @@ -180,7 +188,11 @@ static void GetProperties( TQContext *base, TQWorkerKind enqueued_worker ) static void NonDeadlockAction( Context *ctx ) { - if ( ctx->owner_self ) { + rtems_task_priority priority; + + priority = GetSelfPriority(); + + if ( ctx->owner_caller ) { Status_Control status; status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT ); @@ -204,12 +216,17 @@ static void NonDeadlockAction( Context *ctx ) } } - ctx->priority_before = GetSelfPriority(); + if ( ctx->tq_ctx->priority_ceiling != PRIO_INVALID ) { + SetSelfPriority( ctx->priority_before ); + } else { + ctx->priority_before = GetSelfPriority(); + } + ctx->status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT ); ctx->owner_after = TQMtxGetOwner( ctx->tq_ctx ); ctx->priority_after = GetSelfPriority(); - if ( ctx->owner_self ) { + if ( ctx->owner_caller ) { TQSurrender( &ctx->tq_ctx->base ); } else if ( ctx->owner_other ) { if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) { @@ -229,6 +246,8 @@ static void NonDeadlockAction( Context *ctx ) TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER ); } } + + SetSelfPriority( priority ); } static void ScoreMtxReqSeizeWait_Pre_Owner_Prepare( @@ -245,11 +264,11 @@ static void ScoreMtxReqSeizeWait_Pre_Owner_Prepare( break; } - case ScoreMtxReqSeizeWait_Pre_Owner_Self: { + case ScoreMtxReqSeizeWait_Pre_Owner_Caller: { /* * While the owner of the mutex is the calling thread. */ - ctx->owner_self = true; + ctx->owner_caller = true; break; } @@ -275,6 +294,44 @@ static void ScoreMtxReqSeizeWait_Pre_Owner_Prepare( } } +static void ScoreMtxReqSeizeWait_Pre_Priority_Prepare( + ScoreMtxReqSeizeWait_Context *ctx, + ScoreMtxReqSeizeWait_Pre_Priority state +) +{ + switch ( state ) { + case ScoreMtxReqSeizeWait_Pre_Priority_LT: { + /* + * Where the mutex provides a priority ceiling, while the calling thread + * has a current priority less than the priority ceiling. + */ + ctx->priority_before = ctx->tq_ctx->priority_ceiling - 1; + break; + } + + case ScoreMtxReqSeizeWait_Pre_Priority_EQ: { + /* + * Where the mutex provides a priority ceiling, while the calling thread + * has a current priority equal to the priority ceiling. + */ + ctx->priority_before = ctx->tq_ctx->priority_ceiling; + break; + } + + case ScoreMtxReqSeizeWait_Pre_Priority_GT: { + /* + * Where the mutex provides a priority ceiling, while the calling thread + * has a current priority greater than the priority ceiling. + */ + ctx->priority_before = ctx->tq_ctx->priority_ceiling + 1; + break; + } + + case ScoreMtxReqSeizeWait_Pre_Priority_NA: + break; + } +} + static void ScoreMtxReqSeizeWait_Post_Status_Check( ScoreMtxReqSeizeWait_Context *ctx, ScoreMtxReqSeizeWait_Post_Status state @@ -291,6 +348,23 @@ static void ScoreMtxReqSeizeWait_Post_Status_Check( break; } + case ScoreMtxReqSeizeWait_Post_Status_OkOrMutexCeilingViolated: { + /* + * Where the mutex provides a priority ceiling, the return status of the + * directive call shall be derived from STATUS_MUTEX_CEILING_VIOLATED. + * + * Where the mutex does not provide a priority ceiling, the return status + * of the directive call shall be derived from STATUS_SUCCESSFUL. + */ + if ( ctx->tq_ctx->priority_ceiling != PRIO_INVALID ) { + T_eq_int( ctx->status, Status( ctx, STATUS_MUTEX_CEILING_VIOLATED ) ); + } else { + T_eq_int( ctx->status, Status( ctx, STATUS_SUCCESSFUL ) ); + TQSurrender( &ctx->tq_ctx->base ); + } + break; + } + case ScoreMtxReqSeizeWait_Post_Status_Recursive: { /* * Where the mutex supports a recursive seize, the return status of the @@ -374,31 +448,41 @@ static void ScoreMtxReqSeizeWait_Post_Owner_Check( ) { switch ( state ) { - case ScoreMtxReqSeizeWait_Post_Owner_Nop: { + case ScoreMtxReqSeizeWait_Post_Owner_Other: { /* - * The owner of the semaphore shall not be modified. + * The owner of the mutex shall not be modified. */ - if ( ctx->owner_self ) { - T_eq_ptr( ctx->owner_after, ctx->tq_ctx->base.runner_tcb ); - } else if ( ctx->owner_other ) { - T_eq_ptr( - ctx->owner_after, - ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_A ] - ); - } else { - T_null( ctx->owner_after ); - } + T_eq_ptr( + ctx->owner_after, + ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_A ] + ); break; } - case ScoreMtxReqSeizeWait_Post_Owner_New: { + case ScoreMtxReqSeizeWait_Post_Owner_Caller: { /* - * The owner of the semaphore shall be the calling thread. + * The owner of the mutex shall be the calling thread. */ T_eq_ptr( ctx->owner_after, ctx->tq_ctx->base.runner_tcb ); break; } + case ScoreMtxReqSeizeWait_Post_Owner_CallerOrNoOwner: { + /* + * Where the mutex provides a priority ceiling, the mutex shall have no + * owner. + * + * Where the mutex does not provide a priority ceiling, the owner of the + * mutex shall be the calling thread. + */ + if ( ctx->tq_ctx->priority_ceiling != PRIO_INVALID ) { + T_null( ctx->owner_after ); + } else { + T_eq_ptr( ctx->owner_after, ctx->tq_ctx->base.runner_tcb ); + } + break; + } + case ScoreMtxReqSeizeWait_Post_Owner_NA: break; } @@ -444,7 +528,7 @@ static void ScoreMtxReqSeizeWait_Prepare( ScoreMtxReqSeizeWait_Context *ctx ) ctx->tq_ctx->base.enqueue_prepare = TQEnqueuePrepareClassicSem; ctx->tq_ctx->base.enqueue_done = TQSurrenderClassicSem; ctx->tq_ctx->base.get_properties = GetProperties; - ctx->owner_self = false; + ctx->owner_caller = false; ctx->owner_other = false; ctx->deadlock = false; } @@ -459,6 +543,7 @@ static void ScoreMtxReqSeizeWait_Action( ScoreMtxReqSeizeWait_Context *ctx ) typedef struct { uint16_t Skip : 1; uint16_t Pre_Owner_NA : 1; + uint16_t Pre_Priority_NA : 1; uint16_t Post_Status : 3; uint16_t Post_Owner : 2; uint16_t Post_Priority : 2; @@ -466,20 +551,27 @@ typedef struct { static const ScoreMtxReqSeizeWait_Entry ScoreMtxReqSeizeWait_Entries[] = { - { 0, 0, ScoreMtxReqSeizeWait_Post_Status_Ok, - ScoreMtxReqSeizeWait_Post_Owner_New, + { 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Enqueued, + ScoreMtxReqSeizeWait_Post_Owner_Other, + ScoreMtxReqSeizeWait_Post_Priority_Nop }, + { 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Deadlock, + ScoreMtxReqSeizeWait_Post_Owner_NA, ScoreMtxReqSeizeWait_Post_Priority_NA }, + { 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Ok, + ScoreMtxReqSeizeWait_Post_Owner_Caller, ScoreMtxReqSeizeWait_Post_Priority_Ceiling }, - { 0, 0, ScoreMtxReqSeizeWait_Post_Status_Recursive, - ScoreMtxReqSeizeWait_Post_Owner_Nop, ScoreMtxReqSeizeWait_Post_Priority_Nop }, - { 0, 0, ScoreMtxReqSeizeWait_Post_Status_Enqueued, - ScoreMtxReqSeizeWait_Post_Owner_Nop, ScoreMtxReqSeizeWait_Post_Priority_Nop }, - { 0, 0, ScoreMtxReqSeizeWait_Post_Status_Deadlock, + { 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Recursive, + ScoreMtxReqSeizeWait_Post_Owner_Caller, + ScoreMtxReqSeizeWait_Post_Priority_Nop }, + { 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_OkOrMutexCeilingViolated, + ScoreMtxReqSeizeWait_Post_Owner_CallerOrNoOwner, + ScoreMtxReqSeizeWait_Post_Priority_Nop }, + { 1, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA, ScoreMtxReqSeizeWait_Post_Owner_NA, ScoreMtxReqSeizeWait_Post_Priority_NA } }; static const uint8_t ScoreMtxReqSeizeWait_Map[] = { - 0, 1, 2, 3 + 4, 2, 2, 3, 3, 5, 0, 0, 0, 1, 1, 1 }; static size_t ScoreMtxReqSeizeWait_Scope( void *arg, char *buf, size_t n ) @@ -534,17 +626,28 @@ void ScoreMtxReqSeizeWait_Run( TQMtxContext *tq_ctx ) ctx->pcs[ 0 ] < ScoreMtxReqSeizeWait_Pre_Owner_NA; ++ctx->pcs[ 0 ] ) { - ScoreMtxReqSeizeWait_Entry entry; - - entry = ScoreMtxReqSeizeWait_GetEntry( index ); - ++index; + for ( + ctx->pcs[ 1 ] = ScoreMtxReqSeizeWait_Pre_Priority_LT; + ctx->pcs[ 1 ] < ScoreMtxReqSeizeWait_Pre_Priority_NA; + ++ctx->pcs[ 1 ] + ) { + ScoreMtxReqSeizeWait_Entry entry; + + entry = ScoreMtxReqSeizeWait_GetEntry( index ); + ++index; + + if ( entry.Skip ) { + continue; + } - ScoreMtxReqSeizeWait_Prepare( ctx ); - ScoreMtxReqSeizeWait_Pre_Owner_Prepare( ctx, ctx->pcs[ 0 ] ); - ScoreMtxReqSeizeWait_Action( ctx ); - ScoreMtxReqSeizeWait_Post_Status_Check( ctx, entry.Post_Status ); - ScoreMtxReqSeizeWait_Post_Owner_Check( ctx, entry.Post_Owner ); - ScoreMtxReqSeizeWait_Post_Priority_Check( ctx, entry.Post_Priority ); + ScoreMtxReqSeizeWait_Prepare( ctx ); + ScoreMtxReqSeizeWait_Pre_Owner_Prepare( ctx, ctx->pcs[ 0 ] ); + ScoreMtxReqSeizeWait_Pre_Priority_Prepare( ctx, ctx->pcs[ 1 ] ); + ScoreMtxReqSeizeWait_Action( ctx ); + ScoreMtxReqSeizeWait_Post_Status_Check( ctx, entry.Post_Status ); + ScoreMtxReqSeizeWait_Post_Owner_Check( ctx, entry.Post_Owner ); + ScoreMtxReqSeizeWait_Post_Priority_Check( ctx, entry.Post_Priority ); + } } T_pop_fixture(); diff --git a/testsuites/validation/tr-mtx-seize-wait.h b/testsuites/validation/tr-mtx-seize-wait.h index 0c604ff43a..bd2e88c4fe 100644 --- a/testsuites/validation/tr-mtx-seize-wait.h +++ b/testsuites/validation/tr-mtx-seize-wait.h @@ -65,14 +65,22 @@ extern "C" { typedef enum { ScoreMtxReqSeizeWait_Pre_Owner_No, - ScoreMtxReqSeizeWait_Pre_Owner_Self, + ScoreMtxReqSeizeWait_Pre_Owner_Caller, ScoreMtxReqSeizeWait_Pre_Owner_Other, ScoreMtxReqSeizeWait_Pre_Owner_Deadlock, ScoreMtxReqSeizeWait_Pre_Owner_NA } ScoreMtxReqSeizeWait_Pre_Owner; +typedef enum { + ScoreMtxReqSeizeWait_Pre_Priority_LT, + ScoreMtxReqSeizeWait_Pre_Priority_EQ, + ScoreMtxReqSeizeWait_Pre_Priority_GT, + ScoreMtxReqSeizeWait_Pre_Priority_NA +} ScoreMtxReqSeizeWait_Pre_Priority; + typedef enum { ScoreMtxReqSeizeWait_Post_Status_Ok, + ScoreMtxReqSeizeWait_Post_Status_OkOrMutexCeilingViolated, ScoreMtxReqSeizeWait_Post_Status_Recursive, ScoreMtxReqSeizeWait_Post_Status_Deadlock, ScoreMtxReqSeizeWait_Post_Status_Enqueued, @@ -80,8 +88,9 @@ typedef enum { } ScoreMtxReqSeizeWait_Post_Status; typedef enum { - ScoreMtxReqSeizeWait_Post_Owner_Nop, - ScoreMtxReqSeizeWait_Post_Owner_New, + ScoreMtxReqSeizeWait_Post_Owner_Other, + ScoreMtxReqSeizeWait_Post_Owner_Caller, + ScoreMtxReqSeizeWait_Post_Owner_CallerOrNoOwner, ScoreMtxReqSeizeWait_Post_Owner_NA } ScoreMtxReqSeizeWait_Post_Owner; -- cgit v1.2.3