summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-08-11 15:47:48 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-08-11 15:48:58 +0200
commit11b5826b3900a82d4f2b4c85f83706940f36fda2 (patch)
treef42768d678d7d848c6a1005204b1b3cd5b6a16d1
parent04162cd5ef25d0fcd2b9b5003bc385b094ade7e6 (diff)
testsuites/validation/tr-mtx-seize-try.c
-rw-r--r--testsuites/validation/tr-mtx-seize-try.c192
-rw-r--r--testsuites/validation/tr-mtx-seize-try.h15
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;