diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-08-11 15:47:48 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-08-11 15:48:58 +0200 |
commit | 11b5826b3900a82d4f2b4c85f83706940f36fda2 (patch) | |
tree | f42768d678d7d848c6a1005204b1b3cd5b6a16d1 | |
parent | 04162cd5ef25d0fcd2b9b5003bc385b094ade7e6 (diff) |
testsuites/validation/tr-mtx-seize-try.c
-rw-r--r-- | testsuites/validation/tr-mtx-seize-try.c | 192 | ||||
-rw-r--r-- | testsuites/validation/tr-mtx-seize-try.h | 15 |
2 files changed, 159 insertions, 48 deletions
diff --git a/testsuites/validation/tr-mtx-seize-try.c b/testsuites/validation/tr-mtx-seize-try.c index cf322f7e8a..a9e2c918a4 100644 --- a/testsuites/validation/tr-mtx-seize-try.c +++ b/testsuites/validation/tr-mtx-seize-try.c @@ -72,7 +72,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 @@ -112,7 +112,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 @@ -126,13 +126,21 @@ static ScoreMtxReqSeizeTry_Context static const char * const ScoreMtxReqSeizeTry_PreDesc_Owner[] = { "No", - "Self", + "Caller", "Other", "NA" }; +static const char * const ScoreMtxReqSeizeTry_PreDesc_Priority[] = { + "Higher", + "Equal", + "Lower", + "NA" +}; + static const char * const * const ScoreMtxReqSeizeTry_PreDesc[] = { ScoreMtxReqSeizeTry_PreDesc_Owner, + ScoreMtxReqSeizeTry_PreDesc_Priority, NULL }; @@ -157,11 +165,11 @@ static void ScoreMtxReqSeizeTry_Pre_Owner_Prepare( break; } - case ScoreMtxReqSeizeTry_Pre_Owner_Self: { + case ScoreMtxReqSeizeTry_Pre_Owner_Caller: { /* * While the owner of the mutex is the calling thread. */ - ctx->owner_self = true; + ctx->owner_caller = true; break; } @@ -179,6 +187,44 @@ static void ScoreMtxReqSeizeTry_Pre_Owner_Prepare( } } +static void ScoreMtxReqSeizeTry_Pre_Priority_Prepare( + ScoreMtxReqSeizeTry_Context *ctx, + ScoreMtxReqSeizeTry_Pre_Priority state +) +{ + switch ( state ) { + case ScoreMtxReqSeizeTry_Pre_Priority_Higher: { + /* + * 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 ScoreMtxReqSeizeTry_Pre_Priority_Equal: { + /* + * 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 ScoreMtxReqSeizeTry_Pre_Priority_Lower: { + /* + * Where the mutex provides a priority ceiling, while the calling thread + * has a current priority lower than the priority ceiling. + */ + ctx->priority_before = ctx->tq_ctx->priority_ceiling + 1; + break; + } + + case ScoreMtxReqSeizeTry_Pre_Priority_NA: + break; + } +} + static void ScoreMtxReqSeizeTry_Post_Status_Check( ScoreMtxReqSeizeTry_Context *ctx, ScoreMtxReqSeizeTry_Post_Status state @@ -195,6 +241,23 @@ static void ScoreMtxReqSeizeTry_Post_Status_Check( break; } + case ScoreMtxReqSeizeTry_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 ScoreMtxReqSeizeTry_Post_Status_Recursive: { /* * Where the mutex supports a recursive seize, the return status of the @@ -247,31 +310,41 @@ static void ScoreMtxReqSeizeTry_Post_Owner_Check( ) { switch ( state ) { - case ScoreMtxReqSeizeTry_Post_Owner_Nop: { + case ScoreMtxReqSeizeTry_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 ScoreMtxReqSeizeTry_Post_Owner_New: { + case ScoreMtxReqSeizeTry_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 ScoreMtxReqSeizeTry_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 ScoreMtxReqSeizeTry_Post_Owner_NA: break; } @@ -314,13 +387,17 @@ static void ScoreMtxReqSeizeTry_Post_Priority_Check( static void ScoreMtxReqSeizeTry_Prepare( ScoreMtxReqSeizeTry_Context *ctx ) { - ctx->owner_self = false; + ctx->owner_caller = false; ctx->owner_other = false; } static void ScoreMtxReqSeizeTry_Action( ScoreMtxReqSeizeTry_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 ); @@ -344,12 +421,17 @@ static void ScoreMtxReqSeizeTry_Action( ScoreMtxReqSeizeTry_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 ) { @@ -369,30 +451,39 @@ static void ScoreMtxReqSeizeTry_Action( ScoreMtxReqSeizeTry_Context *ctx ) TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER ); } } + + SetSelfPriority( priority ); } typedef struct { - uint8_t Skip : 1; - uint8_t Pre_Owner_NA : 1; - uint8_t Post_Status : 2; - uint8_t Post_Owner : 2; - uint8_t Post_Priority : 2; + 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; } ScoreMtxReqSeizeTry_Entry; static const ScoreMtxReqSeizeTry_Entry ScoreMtxReqSeizeTry_Entries[] = { - { 0, 0, ScoreMtxReqSeizeTry_Post_Status_Ok, - ScoreMtxReqSeizeTry_Post_Owner_New, + { 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Unsat, + ScoreMtxReqSeizeTry_Post_Owner_Other, ScoreMtxReqSeizeTry_Post_Priority_Nop }, + { 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Ok, + ScoreMtxReqSeizeTry_Post_Owner_Caller, ScoreMtxReqSeizeTry_Post_Priority_Ceiling }, - { 0, 0, ScoreMtxReqSeizeTry_Post_Status_Recursive, - ScoreMtxReqSeizeTry_Post_Owner_Nop, ScoreMtxReqSeizeTry_Post_Priority_Nop }, - { 0, 0, ScoreMtxReqSeizeTry_Post_Status_Unsat, - ScoreMtxReqSeizeTry_Post_Owner_Nop, ScoreMtxReqSeizeTry_Post_Priority_Nop } + { 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Recursive, + ScoreMtxReqSeizeTry_Post_Owner_Caller, + ScoreMtxReqSeizeTry_Post_Priority_Nop }, + { 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_OkOrMutexCeilingViolated, + ScoreMtxReqSeizeTry_Post_Owner_CallerOrNoOwner, + ScoreMtxReqSeizeTry_Post_Priority_Nop }, + { 1, 0, 0, ScoreMtxReqSeizeTry_Post_Status_NA, + ScoreMtxReqSeizeTry_Post_Owner_NA, ScoreMtxReqSeizeTry_Post_Priority_NA } }; static const uint8_t ScoreMtxReqSeizeTry_Map[] = { - 0, 1, 2 + 3, 1, 1, 2, 2, 4, 0, 0, 0 }; static size_t ScoreMtxReqSeizeTry_Scope( void *arg, char *buf, size_t n ) @@ -447,17 +538,28 @@ void ScoreMtxReqSeizeTry_Run( TQMtxContext *tq_ctx ) ctx->pcs[ 0 ] < ScoreMtxReqSeizeTry_Pre_Owner_NA; ++ctx->pcs[ 0 ] ) { - ScoreMtxReqSeizeTry_Entry entry; - - entry = ScoreMtxReqSeizeTry_GetEntry( index ); - ++index; + for ( + ctx->pcs[ 1 ] = ScoreMtxReqSeizeTry_Pre_Priority_Higher; + ctx->pcs[ 1 ] < ScoreMtxReqSeizeTry_Pre_Priority_NA; + ++ctx->pcs[ 1 ] + ) { + ScoreMtxReqSeizeTry_Entry entry; + + entry = ScoreMtxReqSeizeTry_GetEntry( index ); + ++index; + + if ( entry.Skip ) { + continue; + } - ScoreMtxReqSeizeTry_Prepare( ctx ); - ScoreMtxReqSeizeTry_Pre_Owner_Prepare( ctx, ctx->pcs[ 0 ] ); - ScoreMtxReqSeizeTry_Action( ctx ); - ScoreMtxReqSeizeTry_Post_Status_Check( ctx, entry.Post_Status ); - ScoreMtxReqSeizeTry_Post_Owner_Check( ctx, entry.Post_Owner ); - ScoreMtxReqSeizeTry_Post_Priority_Check( ctx, entry.Post_Priority ); + ScoreMtxReqSeizeTry_Prepare( ctx ); + ScoreMtxReqSeizeTry_Pre_Owner_Prepare( ctx, ctx->pcs[ 0 ] ); + ScoreMtxReqSeizeTry_Pre_Priority_Prepare( ctx, ctx->pcs[ 1 ] ); + ScoreMtxReqSeizeTry_Action( ctx ); + ScoreMtxReqSeizeTry_Post_Status_Check( ctx, entry.Post_Status ); + ScoreMtxReqSeizeTry_Post_Owner_Check( ctx, entry.Post_Owner ); + ScoreMtxReqSeizeTry_Post_Priority_Check( ctx, entry.Post_Priority ); + } } T_pop_fixture(); diff --git a/testsuites/validation/tr-mtx-seize-try.h b/testsuites/validation/tr-mtx-seize-try.h index 65ba970b11..923200ae14 100644 --- a/testsuites/validation/tr-mtx-seize-try.h +++ b/testsuites/validation/tr-mtx-seize-try.h @@ -65,21 +65,30 @@ extern "C" { typedef enum { ScoreMtxReqSeizeTry_Pre_Owner_No, - ScoreMtxReqSeizeTry_Pre_Owner_Self, + ScoreMtxReqSeizeTry_Pre_Owner_Caller, ScoreMtxReqSeizeTry_Pre_Owner_Other, ScoreMtxReqSeizeTry_Pre_Owner_NA } ScoreMtxReqSeizeTry_Pre_Owner; typedef enum { + ScoreMtxReqSeizeTry_Pre_Priority_Higher, + ScoreMtxReqSeizeTry_Pre_Priority_Equal, + ScoreMtxReqSeizeTry_Pre_Priority_Lower, + ScoreMtxReqSeizeTry_Pre_Priority_NA +} ScoreMtxReqSeizeTry_Pre_Priority; + +typedef enum { ScoreMtxReqSeizeTry_Post_Status_Ok, + ScoreMtxReqSeizeTry_Post_Status_OkOrMutexCeilingViolated, ScoreMtxReqSeizeTry_Post_Status_Recursive, ScoreMtxReqSeizeTry_Post_Status_Unsat, ScoreMtxReqSeizeTry_Post_Status_NA } ScoreMtxReqSeizeTry_Post_Status; typedef enum { - ScoreMtxReqSeizeTry_Post_Owner_Nop, - ScoreMtxReqSeizeTry_Post_Owner_New, + ScoreMtxReqSeizeTry_Post_Owner_Other, + ScoreMtxReqSeizeTry_Post_Owner_Caller, + ScoreMtxReqSeizeTry_Post_Owner_CallerOrNoOwner, ScoreMtxReqSeizeTry_Post_Owner_NA } ScoreMtxReqSeizeTry_Post_Owner; |