summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-05-10 08:31:43 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-07-12 15:09:24 +0200
commit182ce7fd17ff771c9065dff1bd3c1b92d91e2cc0 (patch)
tree9b8fb732d15013671f99143f114e0578e9748394
parent5544439ac511b862adadcbb536042f0cb497edab (diff)
validation: Add task manager tests
-rw-r--r--spec/build/testsuites/validation/validation-0.yml13
-rw-r--r--testsuites/validation/tc-task-construct-errors.c4
-rw-r--r--testsuites/validation/tc-task-create-errors.c4
-rw-r--r--testsuites/validation/tc-task-get-affinity.c492
-rw-r--r--testsuites/validation/tc-task-get-priority.c579
-rw-r--r--testsuites/validation/tc-task-get-scheduler.c389
-rw-r--r--testsuites/validation/tc-task-is-suspended.c390
-rw-r--r--testsuites/validation/tc-task-restart.c719
-rw-r--r--testsuites/validation/tc-task-resume.c378
-rw-r--r--testsuites/validation/tc-task-set-affinity.c537
-rw-r--r--testsuites/validation/tc-task-set-priority.c550
-rw-r--r--testsuites/validation/tc-task-set-scheduler.c1454
-rw-r--r--testsuites/validation/tc-task-start.c822
-rw-r--r--testsuites/validation/tc-task-storage-size.c388
-rw-r--r--testsuites/validation/tc-task-suspend.c378
-rw-r--r--testsuites/validation/tc-task.c207
16 files changed, 7300 insertions, 4 deletions
diff --git a/spec/build/testsuites/validation/validation-0.yml b/spec/build/testsuites/validation/validation-0.yml
index ffc070972e..c2f8d653e4 100644
--- a/spec/build/testsuites/validation/validation-0.yml
+++ b/spec/build/testsuites/validation/validation-0.yml
@@ -70,10 +70,23 @@ source:
- testsuites/validation/tc-sem-set-priority.c
- testsuites/validation/tc-signal-catch.c
- testsuites/validation/tc-signal-send.c
+- testsuites/validation/tc-task.c
- testsuites/validation/tc-task-construct-errors.c
- testsuites/validation/tc-task-create-errors.c
+- testsuites/validation/tc-task-get-affinity.c
+- testsuites/validation/tc-task-get-priority.c
+- testsuites/validation/tc-task-get-scheduler.c
- testsuites/validation/tc-task-ident.c
+- testsuites/validation/tc-task-is-suspended.c
- testsuites/validation/tc-task-mode.c
+- testsuites/validation/tc-task-restart.c
+- testsuites/validation/tc-task-resume.c
+- testsuites/validation/tc-task-set-affinity.c
+- testsuites/validation/tc-task-set-priority.c
+- testsuites/validation/tc-task-set-scheduler.c
+- testsuites/validation/tc-task-start.c
+- testsuites/validation/tc-task-storage-size.c
+- testsuites/validation/tc-task-suspend.c
- testsuites/validation/tc-timer-create.c
- testsuites/validation/tc-timer-delete.c
- testsuites/validation/tc-timer-ident.c
diff --git a/testsuites/validation/tc-task-construct-errors.c b/testsuites/validation/tc-task-construct-errors.c
index e6f8c5faa5..c31ee29fb8 100644
--- a/testsuites/validation/tc-task-construct-errors.c
+++ b/testsuites/validation/tc-task-construct-errors.c
@@ -57,6 +57,8 @@
#include <rtems/score/apimutex.h>
#include <rtems/score/threadimpl.h>
+#include "tx-support.h"
+
#include <rtems/test.h>
/**
@@ -278,8 +280,6 @@ static const char * const * const RtemsTaskReqConstructErrors_PreDesc[] = {
#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
-#define INVALID_ID 0xffffffff
-
typedef RtemsTaskReqConstructErrors_Context Context;
static _Thread_local int tls_variable;
diff --git a/testsuites/validation/tc-task-create-errors.c b/testsuites/validation/tc-task-create-errors.c
index 3121d753fc..c60344544e 100644
--- a/testsuites/validation/tc-task-create-errors.c
+++ b/testsuites/validation/tc-task-create-errors.c
@@ -57,6 +57,8 @@
#include <rtems/score/apimutex.h>
#include <rtems/score/threadimpl.h>
+#include "tx-support.h"
+
#include <rtems/test.h>
/**
@@ -247,8 +249,6 @@ static const char * const * const RtemsTaskReqCreateErrors_PreDesc[] = {
#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
-#define INVALID_ID 0xffffffff
-
typedef RtemsTaskReqCreateErrors_Context Context;
static rtems_status_code Create( void *arg, uint32_t *id )
diff --git a/testsuites/validation/tc-task-get-affinity.c b/testsuites/validation/tc-task-get-affinity.c
new file mode 100644
index 0000000000..fc50df997a
--- /dev/null
+++ b/testsuites/validation/tc-task-get-affinity.c
@@ -0,0 +1,492 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqGetAffinity
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqGetAffinity \
+ * spec:/rtems/task/req/get-affinity
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Pre_Id_Invalid,
+ RtemsTaskReqGetAffinity_Pre_Id_Task,
+ RtemsTaskReqGetAffinity_Pre_Id_NA
+} RtemsTaskReqGetAffinity_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA
+} RtemsTaskReqGetAffinity_Pre_CPUSetSize;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Pre_CPUSet_Valid,
+ RtemsTaskReqGetAffinity_Pre_CPUSet_Null,
+ RtemsTaskReqGetAffinity_Pre_CPUSet_NA
+} RtemsTaskReqGetAffinity_Pre_CPUSet;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Post_Status_Ok,
+ RtemsTaskReqGetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqGetAffinity_Post_Status_InvId,
+ RtemsTaskReqGetAffinity_Post_Status_InvSize,
+ RtemsTaskReqGetAffinity_Post_Status_NA
+} RtemsTaskReqGetAffinity_Post_Status;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Set,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_NA
+} RtemsTaskReqGetAffinity_Post_CPUSetObj;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/get-affinity test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the object referenced by the ``cpuset``
+ * parameter.
+ */
+ cpu_set_t cpuset_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_get_affinity() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``cpusetsize`` parameter value.
+ */
+ size_t cpusetsize;
+
+ /**
+ * @brief This member specifies if the ``cpuset`` parameter value.
+ */
+ cpu_set_t *cpuset;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqGetAffinity_Context;
+
+static RtemsTaskReqGetAffinity_Context
+ RtemsTaskReqGetAffinity_Instance;
+
+static const char * const RtemsTaskReqGetAffinity_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSetSize[] = {
+ "Valid",
+ "TooSmall",
+ "Askew",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSet[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqGetAffinity_PreDesc[] = {
+ RtemsTaskReqGetAffinity_PreDesc_Id,
+ RtemsTaskReqGetAffinity_PreDesc_CPUSetSize,
+ RtemsTaskReqGetAffinity_PreDesc_CPUSet,
+ NULL
+};
+
+static void RtemsTaskReqGetAffinity_Pre_Id_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter specifies a processor set
+ * which is large enough to contain the processor affinity set of the
+ * task.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter specifies a processor set
+ * which is not large enough to contain the processor affinity set of the
+ * task.
+ */
+ ctx->cpusetsize = 0;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew: {
+ /*
+ * While the ``cpusetsize`` parameter is not an integral multiple of the
+ * size of long.
+ */
+ ctx->cpusetsize = SIZE_MAX;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Pre_CPUSet state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Pre_CPUSet_Valid: {
+ /*
+ * While the ``cpuset`` parameter references an object of type cpu_set_t.
+ */
+ ctx->cpuset = &ctx->cpuset_obj;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSet_Null: {
+ /*
+ * While the ``cpuset`` parameter is equal to NULL.
+ */
+ ctx->cpuset = NULL;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSet_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Post_Status_Check(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj state
+)
+{
+ cpu_set_t set;
+ uint32_t cpu_index;
+ uint32_t cpu_max;
+
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Post_CPUSetObj_Set: {
+ /*
+ * The value of the object referenced by the ``cpuset`` parameter shall
+ * be set to the processor affinity set of the task specified by the
+ * ``id`` parameter at some point during the call after the return of the
+ * rtems_task_get_affinity() call.
+ */
+ CPU_ZERO( &set );
+
+ cpu_max = rtems_scheduler_get_processor_maximum();
+
+ /* We need the online processors */
+ if ( cpu_max > 4 ) {
+ cpu_max = 4;
+ }
+
+ for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
+ CPU_SET( (int) cpu_index, &set );
+ }
+
+ T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop: {
+ /*
+ * Objects referenced by the ``cpuset`` parameter in past calls to
+ * rtems_task_get_affinity() shall not be accessed by the
+ * rtems_task_get_affinity() call.
+ */
+ CPU_ZERO( &set );
+ T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_CPUSetObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx
+)
+{
+ CPU_ZERO( &ctx->cpuset_obj );
+}
+
+static void RtemsTaskReqGetAffinity_Action(
+ RtemsTaskReqGetAffinity_Context *ctx
+)
+{
+ ctx->status = rtems_task_get_affinity(
+ ctx->id,
+ ctx->cpusetsize,
+ ctx->cpuset
+ );
+}
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_CPUSetSize_NA : 1;
+ uint16_t Pre_CPUSet_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_CPUSetObj : 2;
+} RtemsTaskReqGetAffinity_Entry;
+
+static const RtemsTaskReqGetAffinity_Entry
+RtemsTaskReqGetAffinity_Entries[] = {
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvId,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvSize,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_Ok,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Set }
+};
+
+static const uint8_t
+RtemsTaskReqGetAffinity_Map[] = {
+ 1, 0, 1, 0, 1, 0, 3, 0, 2, 0, 2, 0
+};
+
+static size_t RtemsTaskReqGetAffinity_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqGetAffinity_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqGetAffinity_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqGetAffinity_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqGetAffinity_Scope,
+ .initial_context = &RtemsTaskReqGetAffinity_Instance
+};
+
+static inline RtemsTaskReqGetAffinity_Entry RtemsTaskReqGetAffinity_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqGetAffinity_Entries[
+ RtemsTaskReqGetAffinity_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqGetAffinity( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqGetAffinity,
+ &RtemsTaskReqGetAffinity_Fixture
+)
+{
+ RtemsTaskReqGetAffinity_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqGetAffinity_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqGetAffinity_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid;
+ ctx->pcs[ 1 ] < RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ for (
+ ctx->pcs[ 2 ] = RtemsTaskReqGetAffinity_Pre_CPUSet_Valid;
+ ctx->pcs[ 2 ] < RtemsTaskReqGetAffinity_Pre_CPUSet_NA;
+ ++ctx->pcs[ 2 ]
+ ) {
+ RtemsTaskReqGetAffinity_Entry entry;
+
+ entry = RtemsTaskReqGetAffinity_GetEntry( index );
+ ++index;
+
+ RtemsTaskReqGetAffinity_Prepare( ctx );
+ RtemsTaskReqGetAffinity_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->pcs[ 2 ] );
+ RtemsTaskReqGetAffinity_Action( ctx );
+ RtemsTaskReqGetAffinity_Post_Status_Check( ctx, entry.Post_Status );
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
+ ctx,
+ entry.Post_CPUSetObj
+ );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-get-priority.c b/testsuites/validation/tc-task-get-priority.c
new file mode 100644
index 0000000000..5d69242f9c
--- /dev/null
+++ b/testsuites/validation/tc-task-get-priority.c
@@ -0,0 +1,579 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqGetPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqGetPriority \
+ * spec:/rtems/task/req/get-priority
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_TaskId_Invalid,
+ RtemsTaskReqGetPriority_Pre_TaskId_Task,
+ RtemsTaskReqGetPriority_Pre_TaskId_NA
+} RtemsTaskReqGetPriority_Pre_TaskId;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid,
+ RtemsTaskReqGetPriority_Pre_SchedulerId_Scheduler,
+ RtemsTaskReqGetPriority_Pre_SchedulerId_NA
+} RtemsTaskReqGetPriority_Pre_SchedulerId;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_Scheduler_Eligible,
+ RtemsTaskReqGetPriority_Pre_Scheduler_Ineligible,
+ RtemsTaskReqGetPriority_Pre_Scheduler_NA
+} RtemsTaskReqGetPriority_Pre_Scheduler;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_Priority_Valid,
+ RtemsTaskReqGetPriority_Pre_Priority_Null,
+ RtemsTaskReqGetPriority_Pre_Priority_NA
+} RtemsTaskReqGetPriority_Pre_Priority;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Post_Status_Ok,
+ RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_Status_InvId,
+ RtemsTaskReqGetPriority_Post_Status_NotDef,
+ RtemsTaskReqGetPriority_Post_Status_NA
+} RtemsTaskReqGetPriority_Post_Status;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Post_PriorityObj_Set,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop,
+ RtemsTaskReqGetPriority_Post_PriorityObj_NA
+} RtemsTaskReqGetPriority_Post_PriorityObj;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/get-priority test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the scheduler A identifier.
+ */
+ rtems_id scheduler_a_id;
+
+ /**
+ * @brief This member contains the scheduler B identifier.
+ */
+ rtems_id scheduler_b_id;
+
+ /**
+ * @brief This member provides the object referenced by the ``priority``
+ * parameter.
+ */
+ rtems_task_priority priority_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_get_priority() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``task_id`` parameter value.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member specifies if the ``priority`` parameter value.
+ */
+ rtems_id *priority;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqGetPriority_Context;
+
+static RtemsTaskReqGetPriority_Context
+ RtemsTaskReqGetPriority_Instance;
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_TaskId[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_SchedulerId[] = {
+ "Invalid",
+ "Scheduler",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_Scheduler[] = {
+ "Eligible",
+ "Ineligible",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_Priority[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqGetPriority_PreDesc[] = {
+ RtemsTaskReqGetPriority_PreDesc_TaskId,
+ RtemsTaskReqGetPriority_PreDesc_SchedulerId,
+ RtemsTaskReqGetPriority_PreDesc_Scheduler,
+ RtemsTaskReqGetPriority_PreDesc_Priority,
+ NULL
+};
+
+static void RtemsTaskReqGetPriority_Pre_TaskId_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_TaskId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_TaskId_Invalid: {
+ /*
+ * While the ``task_id`` parameter is not associated with a task.
+ */
+ ctx->task_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_TaskId_Task: {
+ /*
+ * While the ``task_id`` parameter is associated with a task.
+ */
+ ctx->task_id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_TaskId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Pre_SchedulerId_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_SchedulerId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->scheduler_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_SchedulerId_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_SchedulerId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Pre_Scheduler_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_Scheduler_Eligible: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with an eligible
+ * scheduler of the task specified by ``task_id``.
+ */
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Scheduler_Ineligible: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with an ineligible
+ * scheduler of the task specified by ``task_id``.
+ */
+ ctx->scheduler_id = ctx->scheduler_b_id;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Pre_Priority_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_Priority_Valid: {
+ /*
+ * While the ``priority`` parameter references an object of type
+ * rtems_task_priority.
+ */
+ ctx->priority = &ctx->priority_obj;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Priority_Null: {
+ /*
+ * While the ``priority`` parameter is equal to NULL.
+ */
+ ctx->priority = NULL;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Post_Status_Check(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_NOT_DEFINED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Post_PriorityObj_Check(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Post_PriorityObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Post_PriorityObj_Set: {
+ /*
+ * The value of the object referenced by the ``scheduler_id`` parameter
+ * shall be set to the object identifier of the home scheduler of the
+ * task specified by the ``task_id`` parameter at some point during the
+ * call after the return of the rtems_task_get_priority() call.
+ */
+ T_eq_u32( ctx->priority_obj, PRIO_DEFAULT );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_PriorityObj_Nop: {
+ /*
+ * Objects referenced by the ``scheduler_id`` parameter in past calls to
+ * rtems_task_get_priority() shall not be accessed by the
+ * rtems_task_get_priority() call.
+ */
+ T_eq_u32( ctx->priority_obj, PRIO_INVALID );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_PriorityObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Setup(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_a_id
+ );
+ T_rsc_success( sc );
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_B_NAME,
+ &ctx->scheduler_b_id
+ );
+ T_rsc_success( sc );
+ #endif
+}
+
+static void RtemsTaskReqGetPriority_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqGetPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqGetPriority_Setup( ctx );
+}
+
+static void RtemsTaskReqGetPriority_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ ctx->priority_obj = PRIO_INVALID;
+}
+
+static void RtemsTaskReqGetPriority_Action(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ ctx->status = rtems_task_get_priority(
+ ctx->task_id,
+ ctx->scheduler_id,
+ ctx->priority
+ );
+}
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_TaskId_NA : 1;
+ uint16_t Pre_SchedulerId_NA : 1;
+ uint16_t Pre_Scheduler_NA : 1;
+ uint16_t Pre_Priority_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_PriorityObj : 2;
+} RtemsTaskReqGetPriority_Entry;
+
+static const RtemsTaskReqGetPriority_Entry
+RtemsTaskReqGetPriority_Entries[] = {
+ { 0, 0, 0, 1, 0, RtemsTaskReqGetPriority_Post_Status_InvId,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+ { 0, 0, 0, 1, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_Ok,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Set },
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NotDef,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+#else
+ { 1, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NA,
+ RtemsTaskReqGetPriority_Post_PriorityObj_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop }
+#else
+ { 1, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NA,
+ RtemsTaskReqGetPriority_Post_PriorityObj_NA }
+#endif
+};
+
+static const uint8_t
+RtemsTaskReqGetPriority_Map[] = {
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 4, 5
+};
+
+static size_t RtemsTaskReqGetPriority_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqGetPriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqGetPriority_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqGetPriority_Fixture = {
+ .setup = RtemsTaskReqGetPriority_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqGetPriority_Scope,
+ .initial_context = &RtemsTaskReqGetPriority_Instance
+};
+
+static inline RtemsTaskReqGetPriority_Entry RtemsTaskReqGetPriority_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqGetPriority_Entries[
+ RtemsTaskReqGetPriority_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqGetPriority( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqGetPriority,
+ &RtemsTaskReqGetPriority_Fixture
+)
+{
+ RtemsTaskReqGetPriority_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqGetPriority_Pre_TaskId_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqGetPriority_Pre_TaskId_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid;
+ ctx->pcs[ 1 ] < RtemsTaskReqGetPriority_Pre_SchedulerId_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ for (
+ ctx->pcs[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_Eligible;
+ ctx->pcs[ 2 ] < RtemsTaskReqGetPriority_Pre_Scheduler_NA;
+ ++ctx->pcs[ 2 ]
+ ) {
+ for (
+ ctx->pcs[ 3 ] = RtemsTaskReqGetPriority_Pre_Priority_Valid;
+ ctx->pcs[ 3 ] < RtemsTaskReqGetPriority_Pre_Priority_NA;
+ ++ctx->pcs[ 3 ]
+ ) {
+ RtemsTaskReqGetPriority_Entry entry;
+ size_t pcs[ 4 ];
+
+ entry = RtemsTaskReqGetPriority_GetEntry( index );
+ ++index;
+
+ if ( entry.Skip ) {
+ continue;
+ }
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Scheduler_NA ) {
+ ctx->pcs[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_NA;
+ }
+
+ RtemsTaskReqGetPriority_Prepare( ctx );
+ RtemsTaskReqGetPriority_Pre_TaskId_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqGetPriority_Pre_SchedulerId_Prepare(
+ ctx,
+ ctx->pcs[ 1 ]
+ );
+ RtemsTaskReqGetPriority_Pre_Scheduler_Prepare( ctx, ctx->pcs[ 2 ] );
+ RtemsTaskReqGetPriority_Pre_Priority_Prepare( ctx, ctx->pcs[ 3 ] );
+ RtemsTaskReqGetPriority_Action( ctx );
+ RtemsTaskReqGetPriority_Post_Status_Check( ctx, entry.Post_Status );
+ RtemsTaskReqGetPriority_Post_PriorityObj_Check(
+ ctx,
+ entry.Post_PriorityObj
+ );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-get-scheduler.c b/testsuites/validation/tc-task-get-scheduler.c
new file mode 100644
index 0000000000..f6da709cee
--- /dev/null
+++ b/testsuites/validation/tc-task-get-scheduler.c
@@ -0,0 +1,389 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqGetScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqGetScheduler \
+ * spec:/rtems/task/req/get-scheduler
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Pre_Id_Invalid,
+ RtemsTaskReqGetScheduler_Pre_Id_Task,
+ RtemsTaskReqGetScheduler_Pre_Id_NA
+} RtemsTaskReqGetScheduler_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid,
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_Null,
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_NA
+} RtemsTaskReqGetScheduler_Pre_SchedulerID;
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Post_Status_Ok,
+ RtemsTaskReqGetScheduler_Post_Status_InvAddr,
+ RtemsTaskReqGetScheduler_Post_Status_InvId,
+ RtemsTaskReqGetScheduler_Post_Status_NA
+} RtemsTaskReqGetScheduler_Post_Status;
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_NA
+} RtemsTaskReqGetScheduler_Post_SchedulerIDObj;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/get-scheduler test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the object referenced by the ``scheduler_id``
+ * parameter.
+ */
+ rtems_id scheduler_id_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_get_scheduler() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``task_id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id *scheduler_id;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqGetScheduler_Context;
+
+static RtemsTaskReqGetScheduler_Context
+ RtemsTaskReqGetScheduler_Instance;
+
+static const char * const RtemsTaskReqGetScheduler_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetScheduler_PreDesc_SchedulerID[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqGetScheduler_PreDesc[] = {
+ RtemsTaskReqGetScheduler_PreDesc_Id,
+ RtemsTaskReqGetScheduler_PreDesc_SchedulerID,
+ NULL
+};
+
+static void RtemsTaskReqGetScheduler_Pre_Id_Prepare(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Pre_Id_Invalid: {
+ /*
+ * While the ``task_id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_Id_Task: {
+ /*
+ * While the ``task_id`` parameter is associated with a task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Pre_SchedulerID_Prepare(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Pre_SchedulerID state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid: {
+ /*
+ * While the ``scheduler_id`` parameter references an object of type
+ * rtems_id.
+ */
+ ctx->scheduler_id = &ctx->scheduler_id_obj;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_SchedulerID_Null: {
+ /*
+ * While the ``scheduler_id`` parameter is equal to NULL.
+ */
+ ctx->scheduler_id = NULL;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_SchedulerID_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Post_Status_Check(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_get_scheduler() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_get_scheduler() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_get_scheduler() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Check(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set: {
+ /*
+ * The value of the object referenced by the ``scheduler_id`` parameter
+ * shall be set to the object identifier of the home scheduler of the
+ * task specified by the ``task_id`` parameter at some point during the
+ * call after the return of the rtems_task_get_scheduler() call.
+ */
+ T_eq_u32( ctx->scheduler_id_obj, 0x0f010001 );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop: {
+ /*
+ * Objects referenced by the ``scheduler_id`` parameter in past calls to
+ * rtems_task_get_scheduler() shall not be accessed by the
+ * rtems_task_get_scheduler() call.
+ */
+ T_eq_u32( ctx->scheduler_id_obj, INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Prepare(
+ RtemsTaskReqGetScheduler_Context *ctx
+)
+{
+ ctx->scheduler_id_obj = INVALID_ID;
+}
+
+static void RtemsTaskReqGetScheduler_Action(
+ RtemsTaskReqGetScheduler_Context *ctx
+)
+{
+ ctx->status = rtems_task_get_scheduler( ctx->id, ctx->scheduler_id );
+}
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_SchedulerID_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_SchedulerIDObj : 2;
+} RtemsTaskReqGetScheduler_Entry;
+
+static const RtemsTaskReqGetScheduler_Entry
+RtemsTaskReqGetScheduler_Entries[] = {
+ { 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_InvAddr,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop },
+ { 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_InvId,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop },
+ { 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_Ok,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set }
+};
+
+static const uint8_t
+RtemsTaskReqGetScheduler_Map[] = {
+ 1, 0, 2, 0
+};
+
+static size_t RtemsTaskReqGetScheduler_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqGetScheduler_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqGetScheduler_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqGetScheduler_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqGetScheduler_Scope,
+ .initial_context = &RtemsTaskReqGetScheduler_Instance
+};
+
+static inline RtemsTaskReqGetScheduler_Entry RtemsTaskReqGetScheduler_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqGetScheduler_Entries[
+ RtemsTaskReqGetScheduler_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqGetScheduler( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqGetScheduler,
+ &RtemsTaskReqGetScheduler_Fixture
+)
+{
+ RtemsTaskReqGetScheduler_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqGetScheduler_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqGetScheduler_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid;
+ ctx->pcs[ 1 ] < RtemsTaskReqGetScheduler_Pre_SchedulerID_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ RtemsTaskReqGetScheduler_Entry entry;
+
+ entry = RtemsTaskReqGetScheduler_GetEntry( index );
+ ++index;
+
+ RtemsTaskReqGetScheduler_Prepare( ctx );
+ RtemsTaskReqGetScheduler_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqGetScheduler_Action( ctx );
+ RtemsTaskReqGetScheduler_Post_Status_Check( ctx, entry.Post_Status );
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Check(
+ ctx,
+ entry.Post_SchedulerIDObj
+ );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-is-suspended.c b/testsuites/validation/tc-task-is-suspended.c
new file mode 100644
index 0000000000..ce0e00a568
--- /dev/null
+++ b/testsuites/validation/tc-task-is-suspended.c
@@ -0,0 +1,390 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqIsSuspended
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqIsSuspended \
+ * spec:/rtems/task/req/is-suspended
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqIsSuspended_Pre_Id_Invalid,
+ RtemsTaskReqIsSuspended_Pre_Id_Task,
+ RtemsTaskReqIsSuspended_Pre_Id_NA
+} RtemsTaskReqIsSuspended_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqIsSuspended_Pre_Suspended_Yes,
+ RtemsTaskReqIsSuspended_Pre_Suspended_No,
+ RtemsTaskReqIsSuspended_Pre_Suspended_NA
+} RtemsTaskReqIsSuspended_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqIsSuspended_Post_Status_Ok,
+ RtemsTaskReqIsSuspended_Post_Status_InvId,
+ RtemsTaskReqIsSuspended_Post_Status_AlrdySus,
+ RtemsTaskReqIsSuspended_Post_Status_NA
+} RtemsTaskReqIsSuspended_Post_Status;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/is-suspended test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_is_suspended() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_is_suspended() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqIsSuspended_Context;
+
+static RtemsTaskReqIsSuspended_Context
+ RtemsTaskReqIsSuspended_Instance;
+
+static const char * const RtemsTaskReqIsSuspended_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqIsSuspended_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqIsSuspended_PreDesc[] = {
+ RtemsTaskReqIsSuspended_PreDesc_Id,
+ RtemsTaskReqIsSuspended_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Pre_Id_Prepare(
+ RtemsTaskReqIsSuspended_Context *ctx,
+ RtemsTaskReqIsSuspended_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIsSuspended_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Pre_Suspended_Prepare(
+ RtemsTaskReqIsSuspended_Context *ctx,
+ RtemsTaskReqIsSuspended_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIsSuspended_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Post_Status_Check(
+ RtemsTaskReqIsSuspended_Context *ctx,
+ RtemsTaskReqIsSuspended_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIsSuspended_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_is_suspended() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_is_suspended() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Post_Status_AlrdySus: {
+ /*
+ * The return status of rtems_task_is_suspended() shall be
+ * RTEMS_ALREADY_SUSPENDED.
+ */
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Setup(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqIsSuspended_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqIsSuspended_Setup( ctx );
+}
+
+static void RtemsTaskReqIsSuspended_Teardown(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqIsSuspended_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqIsSuspended_Teardown( ctx );
+}
+
+static void RtemsTaskReqIsSuspended_Action(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_is_suspended( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqIsSuspended_Entry;
+
+static const RtemsTaskReqIsSuspended_Entry
+RtemsTaskReqIsSuspended_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqIsSuspended_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqIsSuspended_Post_Status_AlrdySus },
+ { 0, 0, 0, RtemsTaskReqIsSuspended_Post_Status_Ok }
+};
+
+static const uint8_t
+RtemsTaskReqIsSuspended_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqIsSuspended_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqIsSuspended_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqIsSuspended_Fixture = {
+ .setup = RtemsTaskReqIsSuspended_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqIsSuspended_Teardown_Wrap,
+ .scope = RtemsTaskReqIsSuspended_Scope,
+ .initial_context = &RtemsTaskReqIsSuspended_Instance
+};
+
+static inline RtemsTaskReqIsSuspended_Entry RtemsTaskReqIsSuspended_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqIsSuspended_Entries[
+ RtemsTaskReqIsSuspended_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqIsSuspended( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqIsSuspended,
+ &RtemsTaskReqIsSuspended_Fixture
+)
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqIsSuspended_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqIsSuspended_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_Yes;
+ ctx->pcs[ 1 ] < RtemsTaskReqIsSuspended_Pre_Suspended_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ RtemsTaskReqIsSuspended_Entry entry;
+ size_t pcs[ 2 ];
+
+ entry = RtemsTaskReqIsSuspended_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Suspended_NA ) {
+ ctx->pcs[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_NA;
+ }
+
+ RtemsTaskReqIsSuspended_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqIsSuspended_Pre_Suspended_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqIsSuspended_Action( ctx );
+ RtemsTaskReqIsSuspended_Post_Status_Check( ctx, entry.Post_Status );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-restart.c b/testsuites/validation/tc-task-restart.c
new file mode 100644
index 0000000000..da27412285
--- /dev/null
+++ b/testsuites/validation/tc-task-restart.c
@@ -0,0 +1,719 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqRestart
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqRestart spec:/rtems/task/req/restart
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Id_Invalid,
+ RtemsTaskReqRestart_Pre_Id_Task,
+ RtemsTaskReqRestart_Pre_Id_NA
+} RtemsTaskReqRestart_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Argument_Pointer,
+ RtemsTaskReqRestart_Pre_Argument_Number,
+ RtemsTaskReqRestart_Pre_Argument_NA
+} RtemsTaskReqRestart_Pre_Argument;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Dormant_Yes,
+ RtemsTaskReqRestart_Pre_Dormant_No,
+ RtemsTaskReqRestart_Pre_Dormant_NA
+} RtemsTaskReqRestart_Pre_Dormant;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Suspended_Yes,
+ RtemsTaskReqRestart_Pre_Suspended_No,
+ RtemsTaskReqRestart_Pre_Suspended_NA
+} RtemsTaskReqRestart_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_Status_InvId,
+ RtemsTaskReqRestart_Post_Status_IncStat,
+ RtemsTaskReqRestart_Post_Status_NA
+} RtemsTaskReqRestart_Post_Status;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_Argument_Nop,
+ RtemsTaskReqRestart_Post_Argument_NA
+} RtemsTaskReqRestart_Post_Argument;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Unblock_Yes,
+ RtemsTaskReqRestart_Post_Unblock_Nop,
+ RtemsTaskReqRestart_Post_Unblock_NA
+} RtemsTaskReqRestart_Post_Unblock;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_RestartExtensions_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA
+} RtemsTaskReqRestart_Post_RestartExtensions;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/restart test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_2 scheduler_log;
+
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the identifier of the test user extensions.
+ */
+ rtems_id extension_id;
+
+ /**
+ * @brief This member contains the count of thread restart extension calls.
+ */
+ uint32_t restart_extension_calls;
+
+ /**
+ * @brief This member contains the actual argument passed to the entry point.
+ */
+ rtems_task_argument actual_argument;
+
+ /**
+ * @brief This member contains the entry point counter.
+ */
+ uint32_t counter;
+
+ /**
+ * @brief If this member is true, then the worker is started before the
+ * rtems_task_restart() call.
+ */
+ bool start;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_restart() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_restart()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``argument`` parameter value.
+ */
+ rtems_task_argument argument;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqRestart_Context;
+
+static RtemsTaskReqRestart_Context
+ RtemsTaskReqRestart_Instance;
+
+static const char * const RtemsTaskReqRestart_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Argument[] = {
+ "Pointer",
+ "Number",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Dormant[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqRestart_PreDesc[] = {
+ RtemsTaskReqRestart_PreDesc_Id,
+ RtemsTaskReqRestart_PreDesc_Argument,
+ RtemsTaskReqRestart_PreDesc_Dormant,
+ RtemsTaskReqRestart_PreDesc_Suspended,
+ NULL
+};
+
+typedef RtemsTaskReqRestart_Context Context;
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = &RtemsTaskReqRestart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ ++ctx->counter;
+ Yield();
+ }
+}
+
+static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
+{
+ (void) executing;
+ (void) restarted;
+
+ ++RtemsTaskReqRestart_Instance.restart_extension_calls;
+}
+
+static const rtems_extensions_table extensions = {
+ .thread_restart = ThreadRestart
+};
+
+static void RtemsTaskReqRestart_Pre_Id_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Argument_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Argument state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Argument_Pointer: {
+ /*
+ * While the entry point argument specified by the ``argument`` parameter
+ * is a pointer.
+ */
+ ctx->argument = (rtems_task_argument) ctx;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Argument_Number: {
+ /*
+ * While the entry point argument specified by the ``argument`` parameter
+ * is a 32-bit number.
+ */
+ ctx->argument = UINT32_C( 0x87654321 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Argument_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Dormant_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Dormant state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Dormant_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is dormant.
+ */
+ ctx->start = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Dormant_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not dormant.
+ */
+ ctx->start = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Dormant_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Suspended_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Status_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_restart() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_restart() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_task_restart() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Argument_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Argument state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Argument_Set: {
+ /*
+ * The entry point argument of the task specified by the ``id`` parameter
+ * shall be set to the value specified by the ``argument`` parameter
+ * before the task is unblocked by the rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->actual_argument, ctx->argument );
+ T_eq_u32( ctx->counter, 2 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Argument_Nop: {
+ /*
+ * No entry point argument of a task shall be modified by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->actual_argument, 0 );
+
+ if ( ctx->start ) {
+ T_eq_u32( ctx->counter, 1 );
+ } else {
+ T_eq_u32( ctx->counter, 0 );
+ }
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Argument_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Unblock_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Unblock state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Unblock_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be unblocked by the
+ * rtems_task_restart() call.
+ */
+ if ( ctx->suspend ) {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ } else {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 2 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_BLOCK
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 1 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ }
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Unblock_Nop: {
+ /*
+ * No task shall be unblocked by the rtems_task_restart() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_RestartExtensions_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_RestartExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_RestartExtensions_Yes: {
+ /*
+ * The thread restart user extensions shall be invoked by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->restart_extension_calls, 1 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_RestartExtensions_Nop: {
+ /*
+ * The thread restart user extensions shall not be invoked by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->restart_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_RestartExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Setup( RtemsTaskReqRestart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsTaskReqRestart_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqRestart_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqRestart_Setup( ctx );
+}
+
+static void RtemsTaskReqRestart_Teardown( RtemsTaskReqRestart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+}
+
+static void RtemsTaskReqRestart_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqRestart_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqRestart_Teardown( ctx );
+}
+
+static void RtemsTaskReqRestart_Prepare( RtemsTaskReqRestart_Context *ctx )
+{
+ ctx->actual_argument = 0;
+ ctx->counter = 0;
+ ctx->worker_id = CreateTask( "WORK", PRIO_DEFAULT );
+}
+
+static void RtemsTaskReqRestart_Action( RtemsTaskReqRestart_Context *ctx )
+{
+ T_scheduler_log *log;
+
+ if ( ctx->start ) {
+ StartTask( ctx->worker_id, Worker, 0 );
+ Yield();
+ }
+
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->restart_extension_calls = 0;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_restart( ctx->id, ctx->argument );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ Yield();
+}
+
+static void RtemsTaskReqRestart_Cleanup( RtemsTaskReqRestart_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Argument_NA : 1;
+ uint16_t Pre_Dormant_NA : 1;
+ uint16_t Pre_Suspended_NA : 1;
+ uint16_t Post_Status : 2;
+ uint16_t Post_Argument : 2;
+ uint16_t Post_Unblock : 2;
+ uint16_t Post_RestartExtensions : 2;
+} RtemsTaskReqRestart_Entry;
+
+static const RtemsTaskReqRestart_Entry
+RtemsTaskReqRestart_Entries[] = {
+ { 0, 0, 0, 1, 1, RtemsTaskReqRestart_Post_Status_InvId,
+ RtemsTaskReqRestart_Post_Argument_Nop,
+ RtemsTaskReqRestart_Post_Unblock_Nop,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop },
+ { 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_IncStat,
+ RtemsTaskReqRestart_Post_Argument_Nop,
+ RtemsTaskReqRestart_Post_Unblock_Nop,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop },
+ { 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_Unblock_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Yes }
+};
+
+static const uint8_t
+RtemsTaskReqRestart_Map[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2
+};
+
+static size_t RtemsTaskReqRestart_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqRestart_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqRestart_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqRestart_Fixture = {
+ .setup = RtemsTaskReqRestart_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqRestart_Teardown_Wrap,
+ .scope = RtemsTaskReqRestart_Scope,
+ .initial_context = &RtemsTaskReqRestart_Instance
+};
+
+static inline RtemsTaskReqRestart_Entry RtemsTaskReqRestart_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqRestart_Entries[
+ RtemsTaskReqRestart_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqRestart( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqRestart, &RtemsTaskReqRestart_Fixture )
+{
+ RtemsTaskReqRestart_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqRestart_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqRestart_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqRestart_Pre_Argument_Pointer;
+ ctx->pcs[ 1 ] < RtemsTaskReqRestart_Pre_Argument_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ for (
+ ctx->pcs[ 2 ] = RtemsTaskReqRestart_Pre_Dormant_Yes;
+ ctx->pcs[ 2 ] < RtemsTaskReqRestart_Pre_Dormant_NA;
+ ++ctx->pcs[ 2 ]
+ ) {
+ for (
+ ctx->pcs[ 3 ] = RtemsTaskReqRestart_Pre_Suspended_Yes;
+ ctx->pcs[ 3 ] < RtemsTaskReqRestart_Pre_Suspended_NA;
+ ++ctx->pcs[ 3 ]
+ ) {
+ RtemsTaskReqRestart_Entry entry;
+ size_t pcs[ 4 ];
+
+ entry = RtemsTaskReqRestart_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Dormant_NA ) {
+ ctx->pcs[ 2 ] = RtemsTaskReqRestart_Pre_Dormant_NA;
+ }
+
+ if ( entry.Pre_Suspended_NA ) {
+ ctx->pcs[ 3 ] = RtemsTaskReqRestart_Pre_Suspended_NA;
+ }
+
+ RtemsTaskReqRestart_Prepare( ctx );
+ RtemsTaskReqRestart_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqRestart_Pre_Argument_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqRestart_Pre_Dormant_Prepare( ctx, ctx->pcs[ 2 ] );
+ RtemsTaskReqRestart_Pre_Suspended_Prepare( ctx, ctx->pcs[ 3 ] );
+ RtemsTaskReqRestart_Action( ctx );
+ RtemsTaskReqRestart_Post_Status_Check( ctx, entry.Post_Status );
+ RtemsTaskReqRestart_Post_Argument_Check( ctx, entry.Post_Argument );
+ RtemsTaskReqRestart_Post_Unblock_Check( ctx, entry.Post_Unblock );
+ RtemsTaskReqRestart_Post_RestartExtensions_Check(
+ ctx,
+ entry.Post_RestartExtensions
+ );
+ RtemsTaskReqRestart_Cleanup( ctx );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-resume.c b/testsuites/validation/tc-task-resume.c
new file mode 100644
index 0000000000..8a96ede9f7
--- /dev/null
+++ b/testsuites/validation/tc-task-resume.c
@@ -0,0 +1,378 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqResume
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqResume spec:/rtems/task/req/resume
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqResume_Pre_Id_Invalid,
+ RtemsTaskReqResume_Pre_Id_Task,
+ RtemsTaskReqResume_Pre_Id_NA
+} RtemsTaskReqResume_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqResume_Pre_Suspended_Yes,
+ RtemsTaskReqResume_Pre_Suspended_No,
+ RtemsTaskReqResume_Pre_Suspended_NA
+} RtemsTaskReqResume_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqResume_Post_Status_Ok,
+ RtemsTaskReqResume_Post_Status_InvId,
+ RtemsTaskReqResume_Post_Status_IncStat,
+ RtemsTaskReqResume_Post_Status_NA
+} RtemsTaskReqResume_Post_Status;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/resume test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_resume() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_resume()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqResume_Context;
+
+static RtemsTaskReqResume_Context
+ RtemsTaskReqResume_Instance;
+
+static const char * const RtemsTaskReqResume_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqResume_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqResume_PreDesc[] = {
+ RtemsTaskReqResume_PreDesc_Id,
+ RtemsTaskReqResume_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqResume_Pre_Id_Prepare(
+ RtemsTaskReqResume_Context *ctx,
+ RtemsTaskReqResume_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqResume_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqResume_Pre_Suspended_Prepare(
+ RtemsTaskReqResume_Context *ctx,
+ RtemsTaskReqResume_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqResume_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqResume_Post_Status_Check(
+ RtemsTaskReqResume_Context *ctx,
+ RtemsTaskReqResume_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqResume_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_resume() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqResume_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_resume() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqResume_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_task_resume() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTaskReqResume_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqResume_Setup( RtemsTaskReqResume_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqResume_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqResume_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqResume_Setup( ctx );
+}
+
+static void RtemsTaskReqResume_Teardown( RtemsTaskReqResume_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqResume_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqResume_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqResume_Teardown( ctx );
+}
+
+static void RtemsTaskReqResume_Action( RtemsTaskReqResume_Context *ctx )
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_resume( ctx->id );
+
+ if ( ctx->suspend && ctx->status != RTEMS_SUCCESSFUL ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqResume_Entry;
+
+static const RtemsTaskReqResume_Entry
+RtemsTaskReqResume_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqResume_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqResume_Post_Status_Ok },
+ { 0, 0, 0, RtemsTaskReqResume_Post_Status_IncStat }
+};
+
+static const uint8_t
+RtemsTaskReqResume_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqResume_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqResume_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqResume_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqResume_Fixture = {
+ .setup = RtemsTaskReqResume_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqResume_Teardown_Wrap,
+ .scope = RtemsTaskReqResume_Scope,
+ .initial_context = &RtemsTaskReqResume_Instance
+};
+
+static inline RtemsTaskReqResume_Entry RtemsTaskReqResume_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqResume_Entries[
+ RtemsTaskReqResume_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqResume( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqResume, &RtemsTaskReqResume_Fixture )
+{
+ RtemsTaskReqResume_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqResume_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqResume_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqResume_Pre_Suspended_Yes;
+ ctx->pcs[ 1 ] < RtemsTaskReqResume_Pre_Suspended_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ RtemsTaskReqResume_Entry entry;
+ size_t pcs[ 2 ];
+
+ entry = RtemsTaskReqResume_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Suspended_NA ) {
+ ctx->pcs[ 1 ] = RtemsTaskReqResume_Pre_Suspended_NA;
+ }
+
+ RtemsTaskReqResume_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqResume_Pre_Suspended_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqResume_Action( ctx );
+ RtemsTaskReqResume_Post_Status_Check( ctx, entry.Post_Status );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-set-affinity.c b/testsuites/validation/tc-task-set-affinity.c
new file mode 100644
index 0000000000..d21f83495b
--- /dev/null
+++ b/testsuites/validation/tc-task-set-affinity.c
@@ -0,0 +1,537 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqSetAffinity
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqSetAffinity \
+ * spec:/rtems/task/req/set-affinity
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_Id_Invalid,
+ RtemsTaskReqSetAffinity_Pre_Id_Task,
+ RtemsTaskReqSetAffinity_Pre_Id_NA
+} RtemsTaskReqSetAffinity_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_CPUSetKind_Askew,
+ RtemsTaskReqSetAffinity_Pre_CPUSetKind_Huge,
+ RtemsTaskReqSetAffinity_Pre_CPUSetKind_Supported,
+ RtemsTaskReqSetAffinity_Pre_CPUSetKind_Unsupported,
+ RtemsTaskReqSetAffinity_Pre_CPUSetKind_NA
+} RtemsTaskReqSetAffinity_Pre_CPUSetKind;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_CPUSet_Valid,
+ RtemsTaskReqSetAffinity_Pre_CPUSet_Null,
+ RtemsTaskReqSetAffinity_Pre_CPUSet_NA
+} RtemsTaskReqSetAffinity_Pre_CPUSet;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Post_Status_Ok,
+ RtemsTaskReqSetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqSetAffinity_Post_Status_InvId,
+ RtemsTaskReqSetAffinity_Post_Status_InvNum,
+ RtemsTaskReqSetAffinity_Post_Status_NA
+} RtemsTaskReqSetAffinity_Post_Status;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Yes,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_NA
+} RtemsTaskReqSetAffinity_Post_SetAffinity;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/set-affinity test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_2 scheduler_log;;
+
+ /**
+ * @brief This member provides the object referenced by the ``cpuset``
+ * parameter.
+ */
+ cpu_set_t cpuset_obj[ 2 ];
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_set_affinity() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``cpusetsize`` parameter value.
+ */
+ size_t cpusetsize;
+
+ /**
+ * @brief This member specifies if the ``cpuset`` parameter value.
+ */
+ cpu_set_t *cpuset;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqSetAffinity_Context;
+
+static RtemsTaskReqSetAffinity_Context
+ RtemsTaskReqSetAffinity_Instance;
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetKind[] = {
+ "Askew",
+ "Huge",
+ "Supported",
+ "Unsupported",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSet[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSetAffinity_PreDesc[] = {
+ RtemsTaskReqSetAffinity_PreDesc_Id,
+ RtemsTaskReqSetAffinity_PreDesc_CPUSetKind,
+ RtemsTaskReqSetAffinity_PreDesc_CPUSet,
+ NULL
+};
+
+static void RtemsTaskReqSetAffinity_Pre_Id_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Pre_CPUSetKind_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_CPUSetKind state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_CPUSetKind_Askew: {
+ /*
+ * While the ``cpusetsize`` parameter is not an integral multiple of the
+ * size of long.
+ */
+ ctx->cpusetsize = SIZE_MAX;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetKind_Huge: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` and ``cpuset`` parameter specify a
+ * processor set which exceeds the implementation limits.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj );
+ CPU_ZERO( &ctx->cpuset_obj[ 0 ] );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetKind_Supported: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` and ``cpuset`` parameter specify a
+ * processor set which is an affinity set supported by the home scheduler
+ * of the task specified by the ``id`` parameter at some point during the
+ * rtems_task_set_affinity() call.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetKind_Unsupported: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` and ``cpuset`` parameter specify a
+ * processor set which is an affinity set not supported by the home
+ * scheduler of the task specified by the ``id`` parameter at some point
+ * during the rtems_task_set_affinity() call.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
+ CPU_CLR( 0, &ctx->cpuset_obj[ 0 ] );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetKind_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_CPUSet state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_CPUSet_Valid: {
+ /*
+ * While the ``cpuset`` parameter references an object of type cpu_set_t.
+ */
+ ctx->cpuset = &ctx->cpuset_obj[ 0 ];
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSet_Null: {
+ /*
+ * While the ``cpuset`` parameter is equal to NULL.
+ */
+ ctx->cpuset = NULL;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSet_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Post_Status_Check(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_InvNum: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_INVALID_NUMBER.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Post_SetAffinity state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Post_SetAffinity_Yes: {
+ /*
+ * The affinity set of the task specified by the ``id`` parameter shall
+ * be set with respect to the home scheduler of the task at some point
+ * during the rtems_task_set_affinity() call.
+ */
+ #if defined(RTEMS_SMP)
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_SET_AFFINITY
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].set_affinity.status,
+ STATUS_SUCCESSFUL
+ );
+ #else
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ #endif
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_SetAffinity_Nop: {
+ /*
+ * No task affinity shall be modified by the rtems_task_set_affinity()
+ * call.
+ */
+ #if defined(RTEMS_SMP)
+ if ( ctx->scheduler_log.header.recorded == 1 ) {
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_SET_AFFINITY
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].set_affinity.status,
+ STATUS_INVALID_NUMBER
+ );
+ } else {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ }
+ #else
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ #endif
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_SetAffinity_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx
+)
+{
+ CPU_FILL_S( sizeof( ctx->cpuset_obj ), &ctx->cpuset_obj[ 0 ] );
+}
+
+static void RtemsTaskReqSetAffinity_Action(
+ RtemsTaskReqSetAffinity_Context *ctx
+)
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_set_affinity(
+ ctx->id,
+ ctx->cpusetsize,
+ ctx->cpuset
+ );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+}
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_CPUSetKind_NA : 1;
+ uint16_t Pre_CPUSet_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_SetAffinity : 2;
+} RtemsTaskReqSetAffinity_Entry;
+
+static const RtemsTaskReqSetAffinity_Entry
+RtemsTaskReqSetAffinity_Entries[] = {
+ { 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Yes }
+};
+
+static const uint8_t
+RtemsTaskReqSetAffinity_Map[] = {
+ 1, 0, 1, 0, 1, 0, 1, 0, 2, 0, 2, 0, 3, 0, 2, 0
+};
+
+static size_t RtemsTaskReqSetAffinity_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSetAffinity_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqSetAffinity_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSetAffinity_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqSetAffinity_Scope,
+ .initial_context = &RtemsTaskReqSetAffinity_Instance
+};
+
+static inline RtemsTaskReqSetAffinity_Entry RtemsTaskReqSetAffinity_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqSetAffinity_Entries[
+ RtemsTaskReqSetAffinity_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSetAffinity( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqSetAffinity,
+ &RtemsTaskReqSetAffinity_Fixture
+)
+{
+ RtemsTaskReqSetAffinity_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqSetAffinity_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqSetAffinity_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqSetAffinity_Pre_CPUSetKind_Askew;
+ ctx->pcs[ 1 ] < RtemsTaskReqSetAffinity_Pre_CPUSetKind_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ for (
+ ctx->pcs[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSet_Valid;
+ ctx->pcs[ 2 ] < RtemsTaskReqSetAffinity_Pre_CPUSet_NA;
+ ++ctx->pcs[ 2 ]
+ ) {
+ RtemsTaskReqSetAffinity_Entry entry;
+ size_t pcs[ 3 ];
+
+ entry = RtemsTaskReqSetAffinity_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_CPUSetKind_NA ) {
+ ctx->pcs[ 1 ] = RtemsTaskReqSetAffinity_Pre_CPUSetKind_NA;
+ }
+
+ RtemsTaskReqSetAffinity_Prepare( ctx );
+ RtemsTaskReqSetAffinity_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqSetAffinity_Pre_CPUSetKind_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->pcs[ 2 ] );
+ RtemsTaskReqSetAffinity_Action( ctx );
+ RtemsTaskReqSetAffinity_Post_Status_Check( ctx, entry.Post_Status );
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
+ ctx,
+ entry.Post_SetAffinity
+ );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-set-priority.c b/testsuites/validation/tc-task-set-priority.c
new file mode 100644
index 0000000000..c301a01d49
--- /dev/null
+++ b/testsuites/validation/tc-task-set-priority.c
@@ -0,0 +1,550 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqSetPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqSetPriority \
+ * spec:/rtems/task/req/set-priority
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_Id_Invalid,
+ RtemsTaskReqSetPriority_Pre_Id_Task,
+ RtemsTaskReqSetPriority_Pre_Id_NA
+} RtemsTaskReqSetPriority_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_NewPriority_Current,
+ RtemsTaskReqSetPriority_Pre_NewPriority_Valid,
+ RtemsTaskReqSetPriority_Pre_NewPriority_Invalid,
+ RtemsTaskReqSetPriority_Pre_NewPriority_NA
+} RtemsTaskReqSetPriority_Pre_NewPriority;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_OldPriority_Valid,
+ RtemsTaskReqSetPriority_Pre_OldPriority_Null,
+ RtemsTaskReqSetPriority_Pre_OldPriority_NA
+} RtemsTaskReqSetPriority_Pre_OldPriority;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Post_Status_Ok,
+ RtemsTaskReqSetPriority_Post_Status_InvAddr,
+ RtemsTaskReqSetPriority_Post_Status_InvId,
+ RtemsTaskReqSetPriority_Post_Status_InvPrio,
+ RtemsTaskReqSetPriority_Post_Status_NA
+} RtemsTaskReqSetPriority_Post_Status;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Post_Priority_Set,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_Priority_NA
+} RtemsTaskReqSetPriority_Post_Priority;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_NA
+} RtemsTaskReqSetPriority_Post_OldPriorityObj;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/set-priority test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the worker task identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member provides the object referenced by the ``old_priority``
+ * parameter.
+ */
+ rtems_task_priority old_priority_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_set_priority() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``new_priority`` parameter value.
+ */
+ rtems_task_priority new_priority;
+
+ /**
+ * @brief This member specifies if the ``old_priority`` parameter value.
+ */
+ rtems_task_priority *old_priority;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqSetPriority_Context;
+
+static RtemsTaskReqSetPriority_Context
+ RtemsTaskReqSetPriority_Instance;
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_NewPriority[] = {
+ "Current",
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_OldPriority[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSetPriority_PreDesc[] = {
+ RtemsTaskReqSetPriority_PreDesc_Id,
+ RtemsTaskReqSetPriority_PreDesc_NewPriority,
+ RtemsTaskReqSetPriority_PreDesc_OldPriority,
+ NULL
+};
+
+static void RtemsTaskReqSetPriority_Pre_Id_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Pre_NewPriority_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_NewPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_NewPriority_Current: {
+ /*
+ * While the value of the ``new_priority`` parameter is equal to
+ * RTEMS_CURRENT_PRIORITY.
+ */
+ ctx->new_priority = RTEMS_CURRENT_PRIORITY;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_NewPriority_Valid: {
+ /*
+ * While the value of the ``new_priority`` parameter is not equal to
+ * RTEMS_CURRENT_PRIORITY, while the value of the ``new_priority``
+ * parameter is a valid task priority with respect to the home scheduler
+ * of the task specified by the ``id`` parameter at some point during the
+ * rtems_task_set_priority() call.
+ */
+ ctx->new_priority = PRIO_HIGH;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_NewPriority_Invalid: {
+ /*
+ * While the value of the ``new_priority`` parameter is not equal to
+ * RTEMS_CURRENT_PRIORITY, while the value of the ``new_priority``
+ * parameter is an invalid task priority with respect to the home
+ * scheduler of the task specified by the ``id`` parameter at some point
+ * during the rtems_task_set_priority() call.
+ */
+ ctx->new_priority = PRIO_INVALID;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_NewPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Pre_OldPriority_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_OldPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_OldPriority_Valid: {
+ /*
+ * While the ``old_priority`` parameter references an object of type
+ * rtems_task_priority.
+ */
+ ctx->old_priority = &ctx->old_priority_obj;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_OldPriority_Null: {
+ /*
+ * While the ``old_priority`` parameter is equal to NULL.
+ */
+ ctx->old_priority = NULL;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_OldPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Post_Status_Check(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Post_Priority_Check(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Post_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Post_Priority_Set: {
+ /*
+ * The real priority of the task specified by the ``id`` parameter shall
+ * be set to the value specified by the ``new_priority`` parameter at
+ * some point during the rtems_task_set_priority() call.
+ */
+ T_eq_u32( GetPriority( ctx->worker_id ), PRIO_HIGH );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Priority_Nop: {
+ /*
+ * No real priority of a task shall be modified by the
+ * rtems_task_set_priority() call.
+ */
+ T_eq_u32( GetPriority( ctx->worker_id ), PRIO_LOW );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Post_OldPriorityObj_Check(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Post_OldPriorityObj_Set: {
+ /*
+ * The value of the object referenced by the ``old_priority`` parameter
+ * shall be set after the return of the rtems_task_set_priority() call to
+ * the current priority of the task specified by the ``id`` parameter at
+ * some point during the call and before the real priority is modified by
+ * the call if it is modified by the call.
+ */
+ T_eq_u32( ctx->old_priority_obj, PRIO_LOW );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop: {
+ /*
+ * Objects referenced by the ``old_priority`` parameter in past calls to
+ * rtems_task_set_priority() shall not be accessed by the
+ * rtems_task_set_priority() call.
+ */
+ T_eq_u32( ctx->old_priority_obj, PRIO_INVALID );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_OldPriorityObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ ctx->old_priority_obj = PRIO_INVALID; ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+}
+
+static void RtemsTaskReqSetPriority_Action(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ ctx->status = rtems_task_set_priority(
+ ctx->id,
+ ctx->new_priority,
+ ctx->old_priority
+ );
+}
+
+static void RtemsTaskReqSetPriority_Cleanup(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_NewPriority_NA : 1;
+ uint16_t Pre_OldPriority_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Priority : 2;
+ uint16_t Post_OldPriorityObj : 2;
+} RtemsTaskReqSetPriority_Entry;
+
+static const RtemsTaskReqSetPriority_Entry
+RtemsTaskReqSetPriority_Entries[] = {
+ { 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvId,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
+ { 0, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
+ { 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
+ RtemsTaskReqSetPriority_Post_Priority_Set,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
+ { 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvPrio,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set }
+};
+
+static const uint8_t
+RtemsTaskReqSetPriority_Map[] = {
+ 0, 1, 0, 1, 0, 1, 3, 2, 4, 2, 5, 2
+};
+
+static size_t RtemsTaskReqSetPriority_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSetPriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqSetPriority_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSetPriority_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqSetPriority_Scope,
+ .initial_context = &RtemsTaskReqSetPriority_Instance
+};
+
+static inline RtemsTaskReqSetPriority_Entry RtemsTaskReqSetPriority_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqSetPriority_Entries[
+ RtemsTaskReqSetPriority_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSetPriority( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqSetPriority,
+ &RtemsTaskReqSetPriority_Fixture
+)
+{
+ RtemsTaskReqSetPriority_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqSetPriority_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqSetPriority_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqSetPriority_Pre_NewPriority_Current;
+ ctx->pcs[ 1 ] < RtemsTaskReqSetPriority_Pre_NewPriority_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ for (
+ ctx->pcs[ 2 ] = RtemsTaskReqSetPriority_Pre_OldPriority_Valid;
+ ctx->pcs[ 2 ] < RtemsTaskReqSetPriority_Pre_OldPriority_NA;
+ ++ctx->pcs[ 2 ]
+ ) {
+ RtemsTaskReqSetPriority_Entry entry;
+ size_t pcs[ 3 ];
+
+ entry = RtemsTaskReqSetPriority_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_NewPriority_NA ) {
+ ctx->pcs[ 1 ] = RtemsTaskReqSetPriority_Pre_NewPriority_NA;
+ }
+
+ RtemsTaskReqSetPriority_Prepare( ctx );
+ RtemsTaskReqSetPriority_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqSetPriority_Pre_NewPriority_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqSetPriority_Pre_OldPriority_Prepare( ctx, ctx->pcs[ 2 ] );
+ RtemsTaskReqSetPriority_Action( ctx );
+ RtemsTaskReqSetPriority_Post_Status_Check( ctx, entry.Post_Status );
+ RtemsTaskReqSetPriority_Post_Priority_Check(
+ ctx,
+ entry.Post_Priority
+ );
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Check(
+ ctx,
+ entry.Post_OldPriorityObj
+ );
+ RtemsTaskReqSetPriority_Cleanup( ctx );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-set-scheduler.c b/testsuites/validation/tc-task-set-scheduler.c
new file mode 100644
index 0000000000..7771cbf629
--- /dev/null
+++ b/testsuites/validation/tc-task-set-scheduler.c
@@ -0,0 +1,1454 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqSetScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/threadimpl.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqSetScheduler \
+ * spec:/rtems/task/req/set-scheduler
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_TaskId_Task,
+ RtemsTaskReqSetScheduler_Pre_TaskId_Invalid,
+ RtemsTaskReqSetScheduler_Pre_TaskId_NA
+} RtemsTaskReqSetScheduler_Pre_TaskId;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_Scheduler_Home,
+ RtemsTaskReqSetScheduler_Pre_Scheduler_Other,
+ RtemsTaskReqSetScheduler_Pre_Scheduler_NA
+} RtemsTaskReqSetScheduler_Pre_Scheduler;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes,
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_No,
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA
+} RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler,
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_Invalid,
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_NA
+} RtemsTaskReqSetScheduler_Pre_SchedulerId;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_Priority_Valid,
+ RtemsTaskReqSetScheduler_Pre_Priority_Invalid,
+ RtemsTaskReqSetScheduler_Pre_Priority_NA
+} RtemsTaskReqSetScheduler_Pre_Priority;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_HomePriority_Real,
+ RtemsTaskReqSetScheduler_Pre_HomePriority_More,
+ RtemsTaskReqSetScheduler_Pre_HomePriority_NA
+} RtemsTaskReqSetScheduler_Pre_HomePriority;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne,
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_More,
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA
+} RtemsTaskReqSetScheduler_Pre_EligiblePriorities;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_Pinned_Yes,
+ RtemsTaskReqSetScheduler_Pre_Pinned_No,
+ RtemsTaskReqSetScheduler_Pre_Pinned_NA
+} RtemsTaskReqSetScheduler_Pre_Pinned;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_TaskState_Ready,
+ RtemsTaskReqSetScheduler_Pre_TaskState_Blocked,
+ RtemsTaskReqSetScheduler_Pre_TaskState_Enqueued,
+ RtemsTaskReqSetScheduler_Pre_TaskState_NA
+} RtemsTaskReqSetScheduler_Pre_TaskState;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes,
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_No,
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA
+} RtemsTaskReqSetScheduler_Pre_AffinitySupported;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Post_Status_Ok,
+ RtemsTaskReqSetScheduler_Post_Status_InvAddr,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Status_InUse,
+ RtemsTaskReqSetScheduler_Post_Status_Unsat,
+ RtemsTaskReqSetScheduler_Post_Status_NA
+} RtemsTaskReqSetScheduler_Post_Status;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Post_Scheduler_Set,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA
+} RtemsTaskReqSetScheduler_Post_Scheduler;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Post_Priority_Set,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_NA
+} RtemsTaskReqSetScheduler_Post_Priority;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/set-scheduler test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the runner task identifier.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the scheduler A identifier.
+ */
+ rtems_id scheduler_a_id;
+
+ /**
+ * @brief This member contains the scheduler B identifier.
+ */
+ rtems_id scheduler_b_id;
+
+ /**
+ * @brief This member contains the scheduler D identifier.
+ */
+ rtems_id scheduler_d_id;
+
+ /**
+ * @brief This member contains the worker task identifiers.
+ */
+ rtems_id worker_id[ 3 ];
+
+ /**
+ * @brief This member contains the mutex identifiers.
+ */
+ rtems_id mutex_id[ 2 ];
+
+ /**
+ * @brief If this member is true, then the task shall have an additional
+ * priority for the home scheduler.
+ */
+ bool additional_home_priority;
+
+ /**
+ * @brief If this member is true, then the task shall have a second eligible
+ * scheduler.
+ */
+ bool second_eligible_scheduler;
+
+ /**
+ * @brief If this member is true, then the task shall be pinned to a
+ * processor.
+ */
+ bool pinned;
+
+ /**
+ * @brief If this member is true, then the task shall be blocked.
+ */
+ bool blocked;
+
+ /**
+ * @brief If this member is true, then the task shall be enqueued on a thread
+ * queue.
+ */
+ bool enqueued;
+
+ /**
+ * @brief This member specifies the scheduler identifier to set.
+ */
+ rtems_id scheduler_to_set_id;
+
+ /**
+ * @brief If this member is true, then the affinity of the task shall be
+ * supported by the scheduler.
+ */
+ bool affinity_supported;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_set_scheduler() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``task_id`` parameter value.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member specifies if the ``priority`` parameter value.
+ */
+ rtems_task_priority priority;
+
+ /**
+ * @brief This member contains the identifier of the new scheduler.
+ */
+ rtems_id new_scheduler;;
+
+ /**
+ * @brief This member contains the new priorities of the task.
+ */
+ rtems_task_priority new_priority[ 2 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 10 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqSetScheduler_Context;
+
+static RtemsTaskReqSetScheduler_Context
+ RtemsTaskReqSetScheduler_Instance;
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_TaskId[] = {
+ "Task",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_Scheduler[] = {
+ "Home",
+ "Other",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_SchedulerHasCPU[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_SchedulerId[] = {
+ "Scheduler",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_Priority[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_HomePriority[] = {
+ "Real",
+ "More",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_EligiblePriorities[] = {
+ "OnlyOne",
+ "More",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_Pinned[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_TaskState[] = {
+ "Ready",
+ "Blocked",
+ "Enqueued",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_AffinitySupported[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSetScheduler_PreDesc[] = {
+ RtemsTaskReqSetScheduler_PreDesc_TaskId,
+ RtemsTaskReqSetScheduler_PreDesc_Scheduler,
+ RtemsTaskReqSetScheduler_PreDesc_SchedulerHasCPU,
+ RtemsTaskReqSetScheduler_PreDesc_SchedulerId,
+ RtemsTaskReqSetScheduler_PreDesc_Priority,
+ RtemsTaskReqSetScheduler_PreDesc_HomePriority,
+ RtemsTaskReqSetScheduler_PreDesc_EligiblePriorities,
+ RtemsTaskReqSetScheduler_PreDesc_Pinned,
+ RtemsTaskReqSetScheduler_PreDesc_TaskState,
+ RtemsTaskReqSetScheduler_PreDesc_AffinitySupported,
+ NULL
+};
+
+typedef RtemsTaskReqSetScheduler_Context Context;
+
+#define EVENT_OBTAIN_MUTEX_A RTEMS_EVENT_0
+
+#define EVENT_RELEASE_MUTEX_A RTEMS_EVENT_1
+
+#define EVENT_OBTAIN_MUTEX_B RTEMS_EVENT_2
+
+#define EVENT_RELEASE_MUTEX_B RTEMS_EVENT_3
+
+#define EVENT_PIN RTEMS_EVENT_4
+
+#define EVENT_UNPIN RTEMS_EVENT_5
+
+#define EVENT_SET_LOW_PRIO RTEMS_EVENT_6
+
+#define EVENT_RUNNER_SYNC_0 RTEMS_EVENT_7
+
+#define EVENT_RUNNER_SYNC_1 RTEMS_EVENT_8
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+ Thread_Control *executing;
+
+ ctx = (Context *) arg;
+ executing = _Thread_Get_executing();
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_RUNNER_SYNC_0 ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_0 );
+ }
+
+ if ( ( events & EVENT_OBTAIN_MUTEX_A ) != 0 ) {
+ ObtainMutex( ctx->mutex_id[ 0 ] );
+ }
+
+ if ( ( events & EVENT_RELEASE_MUTEX_A ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id[ 0 ] );
+ }
+
+ if ( ( events & EVENT_OBTAIN_MUTEX_B ) != 0 ) {
+ ObtainMutex( ctx->mutex_id[ 1 ] );
+ }
+
+ if ( ( events & EVENT_RELEASE_MUTEX_B ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id[ 1 ] );
+ }
+
+ if ( ( events & EVENT_PIN ) != 0 ) {
+ _Thread_Pin( executing );
+ }
+
+ if ( ( events & EVENT_UNPIN ) != 0 ) {
+ _Thread_Unpin( executing, _Per_CPU_Get_snapshot() );
+ }
+
+ if ( ( events & EVENT_SET_LOW_PRIO ) != 0 ) {
+ SetSelfPriority( PRIO_LOW );
+ }
+
+ if ( ( events & EVENT_RUNNER_SYNC_1 ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_1 );
+ }
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_TaskId_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_TaskId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_TaskId_Task: {
+ /*
+ * While the ``task_id`` parameter is associated with a task.
+ */
+ ctx->task_id = ctx->worker_id[ 0 ];
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskId_Invalid: {
+ /*
+ * While the ``task_id`` parameter is not associated with a task.
+ */
+ ctx->task_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_Scheduler_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_Scheduler_Home: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter is the
+ * home scheduler of the task specified by the ``task_id`` parameter.
+ */
+ ctx->scheduler_to_set_id = ctx->scheduler_a_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Scheduler_Other: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter is not
+ * the home scheduler of the task specified by the ``task_id`` parameter.
+ */
+ ctx->scheduler_to_set_id = ctx->scheduler_b_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter owns
+ * at least one processor.
+ */
+ /* Already set by Scheduler pre-condition */
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_No: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter owns
+ * no processor.
+ */
+ ctx->scheduler_to_set_id = ctx->scheduler_d_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_SchedulerId_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_SchedulerId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->scheduler_id = ctx->scheduler_to_set_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerId_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->scheduler_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_Priority_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_Priority_Valid: {
+ /*
+ * While the task priority specified by the ``priority`` parameter is
+ * valid with respect to the scheduler specified by the ``scheduler_id``
+ * parameter.
+ */
+ ctx->priority = PRIO_VERY_LOW;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Priority_Invalid: {
+ /*
+ * While the task priority specified by the ``priority`` parameter is
+ * invalid with respect to the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->priority = PRIO_INVALID;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_HomePriority_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_HomePriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_HomePriority_Real: {
+ /*
+ * While the current priority of the task specified by the ``task_id``
+ * parameter consists only of the real priority.
+ */
+ ctx->additional_home_priority = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_HomePriority_More: {
+ /*
+ * While the current priority of the task specified by the ``task_id``
+ * parameter consists of more than the real priority.
+ */
+ ctx->additional_home_priority = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_HomePriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_EligiblePriorities_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne: {
+ /*
+ * While the set of eligible priorities of the task specified by the
+ * ``task_id`` parameter consists of exactly the current priority.
+ */
+ ctx->second_eligible_scheduler = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_More: {
+ /*
+ * While the set of eligible priorities of the task specified by the
+ * ``task_id`` parameter consists of more than the current priority.
+ */
+ ctx->second_eligible_scheduler = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_Pinned_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_Pinned state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_Pinned_Yes: {
+ /*
+ * While the task specified by the ``task_id`` parameter is pinned.
+ */
+ ctx->pinned = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Pinned_No: {
+ /*
+ * While the task specified by the ``task_id`` parameter is not pinned.
+ */
+ ctx->pinned = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Pinned_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_TaskState_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_TaskState state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_TaskState_Ready: {
+ /*
+ * While the task specified by the ``task_id`` parameter is ready.
+ */
+ ctx->blocked = false;
+ ctx->enqueued = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskState_Blocked: {
+ /*
+ * While the task specified by the ``task_id`` parameter is blocked,
+ * while the task specified by the ``task_id`` parameter is not enqueued
+ * on a wait queue.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskState_Enqueued: {
+ /*
+ * While the task specified by the ``task_id`` parameter is blocked,
+ * while the task specified by the ``task_id`` parameter is enqueued on a
+ * wait queue.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskState_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_AffinitySupported_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes: {
+ /*
+ * While the affinity set of the task specified by the ``task_id``
+ * parameter is supported by the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->affinity_supported = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_AffinitySupported_No: {
+ /*
+ * While the affinity set of the task specified by the ``task_id``
+ * parameter is not supported by the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->affinity_supported = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Post_Status_Check(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InUse: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_RESOURCE_IN_USE.
+ */
+ T_rsc( ctx->status, RTEMS_RESOURCE_IN_USE );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_Unsat: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_UNSATISFIED.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Post_Scheduler_Check(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Post_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Post_Scheduler_Set: {
+ /*
+ * The home scheduler of the task specified by the ``task_id`` parameter
+ * shall be set to the scheduler specified by the ``scheduler_id``
+ * parameter at some point during the rtems_task_set_scheduler() call.
+ */
+ T_eq_u32( ctx->new_scheduler, ctx->scheduler_to_set_id );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Scheduler_Nop: {
+ /*
+ * No home scheduler of a task shall be modified by the
+ * rtems_task_set_scheduler() call.
+ */
+ T_eq_u32( ctx->new_scheduler, ctx->scheduler_a_id );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Post_Priority_Check(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Post_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Post_Priority_Set: {
+ /*
+ * The real priority of the task specified by the ``task_id`` parameter
+ * shall be set to the priority specified by the ``priority`` parameter
+ * at some point during the rtems_task_set_scheduler() call.
+ */
+ if ( ctx->scheduler_to_set_id == ctx->scheduler_a_id ) {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_VERY_LOW );
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
+ } else {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_INVALID );
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_VERY_LOW );
+ }
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Priority_Nop: {
+ /*
+ * No task priority shall be modified by the rtems_task_set_scheduler()
+ * call.
+ */
+ if ( ctx->blocked ) {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_HIGH );
+ } else {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_LOW );
+ }
+
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Setup(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ rtems_status_code sc;
+ size_t i;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->runner_id = rtems_task_self();
+ SetSelfPriority( PRIO_NORMAL );
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_a_id
+ );
+ T_rsc_success( sc );
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ ctx->mutex_id[ i ] = CreateMutex();
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ ctx->worker_id[ i ] = CreateTask( "WORK", PRIO_HIGH - i );
+ StartTask( ctx->worker_id[ i ], Worker, ctx );
+ }
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &ctx->scheduler_b_id );
+ T_rsc_success( sc );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_D_NAME, &ctx->scheduler_d_id );
+ T_rsc_success( sc );
+
+ SetScheduler( ctx->worker_id[ 2 ], ctx->scheduler_b_id, PRIO_NORMAL );
+ #else
+ ctx->scheduler_b_id = INVALID_ID;
+ #endif
+}
+
+static void RtemsTaskReqSetScheduler_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqSetScheduler_Setup( ctx );
+}
+
+static void RtemsTaskReqSetScheduler_Teardown(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ DeleteTask( ctx->worker_id[ i ] );
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ DeleteMutex( ctx->mutex_id[ i ] );
+ }
+
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqSetScheduler_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqSetScheduler_Teardown( ctx );
+}
+
+static void RtemsTaskReqSetScheduler_Action(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_A );
+
+ if ( ctx->additional_home_priority ) {
+ SendEvents( ctx->worker_id[ 1 ], EVENT_OBTAIN_MUTEX_A );
+ }
+
+ if ( ctx->second_eligible_scheduler ) {
+ SendEvents(
+ ctx->worker_id[ 2 ],
+ EVENT_RUNNER_SYNC_0 | EVENT_OBTAIN_MUTEX_A
+ );
+ ReceiveAllEvents( EVENT_RUNNER_SYNC_0 );
+ WaitForExecutionStop( ctx->worker_id[ 2 ] );
+ }
+ }
+
+ if ( ctx->blocked && ctx->enqueued ) {
+ ObtainMutex( ctx->mutex_id[ 1 ] );
+ SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_B );
+ }
+
+ if ( !ctx->affinity_supported ) {
+ SetAffinityOne( ctx->worker_id[ 0 ], 0 );
+ }
+
+ if ( ctx->pinned ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_PIN );
+ }
+
+ if ( !ctx->blocked ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_SET_LOW_PRIO );
+ }
+
+ ctx->status = rtems_task_set_scheduler(
+ ctx->task_id,
+ ctx->scheduler_id,
+ ctx->priority
+ );
+
+ ctx->new_scheduler = GetScheduler( ctx->worker_id[ 0 ] );
+
+ if ( ctx->pinned ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_UNPIN );
+ }
+
+ if ( !ctx->affinity_supported ) {
+ SetAffinityAll( ctx->worker_id[ 0 ] );
+ }
+
+ if ( ctx->blocked && ctx->enqueued ) {
+ ReleaseMutex( ctx->mutex_id[ 1 ] );
+ SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_B );
+ }
+
+ if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_A );
+
+ if ( ctx->additional_home_priority ) {
+ SendEvents( ctx->worker_id[ 1 ], EVENT_RELEASE_MUTEX_A );
+ }
+
+ if ( ctx->second_eligible_scheduler ) {
+ SendEvents(
+ ctx->worker_id[ 2 ],
+ EVENT_RELEASE_MUTEX_A | EVENT_RUNNER_SYNC_1
+ );
+ ReceiveAllEvents( EVENT_RUNNER_SYNC_1 );
+ }
+ }
+
+ sc = rtems_task_get_priority(
+ ctx->worker_id[ 0 ],
+ ctx->scheduler_a_id,
+ &ctx->new_priority[ 0 ]
+ );
+
+ if ( sc == RTEMS_NOT_DEFINED ) {
+ ctx->new_priority[ 0 ] = PRIO_INVALID;
+ } else {
+ T_rsc_success( sc );
+ }
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_task_get_priority(
+ ctx->worker_id[ 0 ],
+ ctx->scheduler_b_id,
+ &ctx->new_priority[ 1 ]
+ );
+
+ if ( sc == RTEMS_NOT_DEFINED ) {
+ ctx->new_priority[ 1 ] = PRIO_INVALID;
+ } else {
+ T_rsc_success( sc );
+ }
+ #else
+ ctx->new_priority[ 1 ] = PRIO_INVALID;
+ #endif
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ SetScheduler( ctx->worker_id[ 0 ], ctx->scheduler_a_id, PRIO_HIGH );
+ } else if ( !ctx->blocked ) {
+ SetPriority( ctx->worker_id[ 0 ], PRIO_HIGH );
+ }
+}
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_TaskId_NA : 1;
+ uint32_t Pre_Scheduler_NA : 1;
+ uint32_t Pre_SchedulerHasCPU_NA : 1;
+ uint32_t Pre_SchedulerId_NA : 1;
+ uint32_t Pre_Priority_NA : 1;
+ uint32_t Pre_HomePriority_NA : 1;
+ uint32_t Pre_EligiblePriorities_NA : 1;
+ uint32_t Pre_Pinned_NA : 1;
+ uint32_t Pre_TaskState_NA : 1;
+ uint32_t Pre_AffinitySupported_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Scheduler : 2;
+ uint32_t Post_Priority : 2;
+} RtemsTaskReqSetScheduler_Entry;
+
+static const RtemsTaskReqSetScheduler_Entry
+RtemsTaskReqSetScheduler_Entries[] = {
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InUse,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_Unsat,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InUse,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_Ok,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Set,
+ RtemsTaskReqSetScheduler_Post_Priority_Set },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA }
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_Ok,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Set,
+ RtemsTaskReqSetScheduler_Post_Priority_Set }
+#endif
+};
+
+static const uint8_t
+RtemsTaskReqSetScheduler_Map[] = {
+ 7, 0, 7, 0, 7, 0, 15, 3, 15, 3, 14, 3, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7,
+ 0, 7, 0, 7, 0, 14, 3, 14, 3, 14, 3, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 4, 0,
+ 4, 0, 4, 0, 10, 3, 10, 3, 10, 3, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4,
+ 0, 4, 0, 10, 3, 10, 3, 10, 3, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 1, 0, 1, 0,
+ 1, 0, 8, 3, 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 8, 3, 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 8, 3,
+ 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 8, 3, 8, 3,
+ 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 16, 11, 16, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 11, 11, 11, 11, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 5, 0,
+ 5, 0, 12, 3, 12, 3, 12, 3, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5,
+ 0, 12, 3, 12, 3, 12, 3, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 6, 0, 6, 0, 6, 0,
+ 13, 3, 13, 3, 13, 3, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0,
+ 13, 3, 13, 3, 13, 3, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 2, 0, 2, 0, 2, 0, 9,
+ 3, 9, 3, 9, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9,
+ 3, 9, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9, 3, 9,
+ 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9, 3, 9, 3, 2,
+ 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+};
+
+static size_t RtemsTaskReqSetScheduler_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqSetScheduler_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSetScheduler_Fixture = {
+ .setup = RtemsTaskReqSetScheduler_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqSetScheduler_Teardown_Wrap,
+ .scope = RtemsTaskReqSetScheduler_Scope,
+ .initial_context = &RtemsTaskReqSetScheduler_Instance
+};
+
+static inline RtemsTaskReqSetScheduler_Entry RtemsTaskReqSetScheduler_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqSetScheduler_Entries[
+ RtemsTaskReqSetScheduler_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSetScheduler( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqSetScheduler,
+ &RtemsTaskReqSetScheduler_Fixture
+)
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqSetScheduler_Pre_TaskId_Task;
+ ctx->pcs[ 0 ] < RtemsTaskReqSetScheduler_Pre_TaskId_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqSetScheduler_Pre_Scheduler_Home;
+ ctx->pcs[ 1 ] < RtemsTaskReqSetScheduler_Pre_Scheduler_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ for (
+ ctx->pcs[ 2 ] = RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes;
+ ctx->pcs[ 2 ] < RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA;
+ ++ctx->pcs[ 2 ]
+ ) {
+ for (
+ ctx->pcs[ 3 ] = RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler;
+ ctx->pcs[ 3 ] < RtemsTaskReqSetScheduler_Pre_SchedulerId_NA;
+ ++ctx->pcs[ 3 ]
+ ) {
+ for (
+ ctx->pcs[ 4 ] = RtemsTaskReqSetScheduler_Pre_Priority_Valid;
+ ctx->pcs[ 4 ] < RtemsTaskReqSetScheduler_Pre_Priority_NA;
+ ++ctx->pcs[ 4 ]
+ ) {
+ for (
+ ctx->pcs[ 5 ] = RtemsTaskReqSetScheduler_Pre_HomePriority_Real;
+ ctx->pcs[ 5 ] < RtemsTaskReqSetScheduler_Pre_HomePriority_NA;
+ ++ctx->pcs[ 5 ]
+ ) {
+ for (
+ ctx->pcs[ 6 ] = RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne;
+ ctx->pcs[ 6 ] < RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA;
+ ++ctx->pcs[ 6 ]
+ ) {
+ for (
+ ctx->pcs[ 7 ] = RtemsTaskReqSetScheduler_Pre_Pinned_Yes;
+ ctx->pcs[ 7 ] < RtemsTaskReqSetScheduler_Pre_Pinned_NA;
+ ++ctx->pcs[ 7 ]
+ ) {
+ for (
+ ctx->pcs[ 8 ] = RtemsTaskReqSetScheduler_Pre_TaskState_Ready;
+ ctx->pcs[ 8 ] < RtemsTaskReqSetScheduler_Pre_TaskState_NA;
+ ++ctx->pcs[ 8 ]
+ ) {
+ for (
+ ctx->pcs[ 9 ] = RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes;
+ ctx->pcs[ 9 ] < RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA;
+ ++ctx->pcs[ 9 ]
+ ) {
+ RtemsTaskReqSetScheduler_Entry entry;
+ size_t pcs[ 10 ];
+
+ entry = RtemsTaskReqSetScheduler_GetEntry( index );
+ ++index;
+
+ if ( entry.Skip ) {
+ continue;
+ }
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Scheduler_NA ) {
+ ctx->pcs[ 1 ] = RtemsTaskReqSetScheduler_Pre_Scheduler_NA;
+ }
+
+ if ( entry.Pre_SchedulerHasCPU_NA ) {
+ ctx->pcs[ 2 ] = RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA;
+ }
+
+ if ( entry.Pre_Priority_NA ) {
+ ctx->pcs[ 4 ] = RtemsTaskReqSetScheduler_Pre_Priority_NA;
+ }
+
+ if ( entry.Pre_HomePriority_NA ) {
+ ctx->pcs[ 5 ] = RtemsTaskReqSetScheduler_Pre_HomePriority_NA;
+ }
+
+ if ( entry.Pre_EligiblePriorities_NA ) {
+ ctx->pcs[ 6 ] = RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA;
+ }
+
+ if ( entry.Pre_Pinned_NA ) {
+ ctx->pcs[ 7 ] = RtemsTaskReqSetScheduler_Pre_Pinned_NA;
+ }
+
+ if ( entry.Pre_TaskState_NA ) {
+ ctx->pcs[ 8 ] = RtemsTaskReqSetScheduler_Pre_TaskState_NA;
+ }
+
+ if ( entry.Pre_AffinitySupported_NA ) {
+ ctx->pcs[ 9 ] = RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA;
+ }
+
+ RtemsTaskReqSetScheduler_Pre_TaskId_Prepare(
+ ctx,
+ ctx->pcs[ 0 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_Scheduler_Prepare(
+ ctx,
+ ctx->pcs[ 1 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Prepare(
+ ctx,
+ ctx->pcs[ 2 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_Prepare(
+ ctx,
+ ctx->pcs[ 3 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_Priority_Prepare(
+ ctx,
+ ctx->pcs[ 4 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_HomePriority_Prepare(
+ ctx,
+ ctx->pcs[ 5 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_Prepare(
+ ctx,
+ ctx->pcs[ 6 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_Pinned_Prepare(
+ ctx,
+ ctx->pcs[ 7 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_TaskState_Prepare(
+ ctx,
+ ctx->pcs[ 8 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_Prepare(
+ ctx,
+ ctx->pcs[ 9 ]
+ );
+ RtemsTaskReqSetScheduler_Action( ctx );
+ RtemsTaskReqSetScheduler_Post_Status_Check(
+ ctx,
+ entry.Post_Status
+ );
+ RtemsTaskReqSetScheduler_Post_Scheduler_Check(
+ ctx,
+ entry.Post_Scheduler
+ );
+ RtemsTaskReqSetScheduler_Post_Priority_Check(
+ ctx,
+ entry.Post_Priority
+ );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-start.c b/testsuites/validation/tc-task-start.c
new file mode 100644
index 0000000000..b90df1b4d8
--- /dev/null
+++ b/testsuites/validation/tc-task-start.c
@@ -0,0 +1,822 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqStart
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqStart spec:/rtems/task/req/start
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Id_Invalid,
+ RtemsTaskReqStart_Pre_Id_Task,
+ RtemsTaskReqStart_Pre_Id_NA
+} RtemsTaskReqStart_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_EntryPoint_Valid,
+ RtemsTaskReqStart_Pre_EntryPoint_Null,
+ RtemsTaskReqStart_Pre_EntryPoint_NA
+} RtemsTaskReqStart_Pre_EntryPoint;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Argument_Pointer,
+ RtemsTaskReqStart_Pre_Argument_Number,
+ RtemsTaskReqStart_Pre_Argument_NA
+} RtemsTaskReqStart_Pre_Argument;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Dormant_Yes,
+ RtemsTaskReqStart_Pre_Dormant_No,
+ RtemsTaskReqStart_Pre_Dormant_NA
+} RtemsTaskReqStart_Pre_Dormant;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Suspended_Yes,
+ RtemsTaskReqStart_Pre_Suspended_No,
+ RtemsTaskReqStart_Pre_Suspended_NA
+} RtemsTaskReqStart_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqStart_Post_Status_Ok,
+ RtemsTaskReqStart_Post_Status_InvAddr,
+ RtemsTaskReqStart_Post_Status_InvId,
+ RtemsTaskReqStart_Post_Status_IncStat,
+ RtemsTaskReqStart_Post_Status_NA
+} RtemsTaskReqStart_Post_Status;
+
+typedef enum {
+ RtemsTaskReqStart_Post_EntryPoint_Set,
+ RtemsTaskReqStart_Post_EntryPoint_Nop,
+ RtemsTaskReqStart_Post_EntryPoint_NA
+} RtemsTaskReqStart_Post_EntryPoint;
+
+typedef enum {
+ RtemsTaskReqStart_Post_Argument_Set,
+ RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Argument_NA
+} RtemsTaskReqStart_Post_Argument;
+
+typedef enum {
+ RtemsTaskReqStart_Post_Unblock_Yes,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_Unblock_NA
+} RtemsTaskReqStart_Post_Unblock;
+
+typedef enum {
+ RtemsTaskReqStart_Post_StartExtensions_Yes,
+ RtemsTaskReqStart_Post_StartExtensions_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_NA
+} RtemsTaskReqStart_Post_StartExtensions;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/start test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_2 scheduler_log;
+
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the identifier of the test user extensions.
+ */
+ rtems_id extension_id;
+
+ /**
+ * @brief This member contains the count of thread start extension calls.
+ */
+ uint32_t start_extension_calls;
+
+ /**
+ * @brief This member contains the actual argument passed to the entry point.
+ */
+ rtems_task_argument actual_argument;
+
+ /**
+ * @brief This member contains the entry point counter.
+ */
+ uint32_t counter;
+
+ /**
+ * @brief If this member is true, then the worker is started before the
+ * rtems_task_start() call.
+ */
+ bool start;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_start() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_start()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``entry_point`` parameter value.
+ */
+ rtems_task_entry entry_point;
+
+ /**
+ * @brief This member specifies if the ``argument`` parameter value.
+ */
+ rtems_task_argument argument;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqStart_Context;
+
+static RtemsTaskReqStart_Context
+ RtemsTaskReqStart_Instance;
+
+static const char * const RtemsTaskReqStart_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_EntryPoint[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_Argument[] = {
+ "Pointer",
+ "Number",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_Dormant[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqStart_PreDesc[] = {
+ RtemsTaskReqStart_PreDesc_Id,
+ RtemsTaskReqStart_PreDesc_EntryPoint,
+ RtemsTaskReqStart_PreDesc_Argument,
+ RtemsTaskReqStart_PreDesc_Dormant,
+ RtemsTaskReqStart_PreDesc_Suspended,
+ NULL
+};
+
+typedef RtemsTaskReqStart_Context Context;
+
+static void WorkerA( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = &RtemsTaskReqStart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ ++ctx->counter;
+ Yield();
+ }
+}
+
+static void WorkerB( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = &RtemsTaskReqStart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ Yield();
+ }
+}
+
+static void ThreadStart( rtems_tcb *executing, rtems_tcb *started )
+{
+ (void) executing;
+ (void) started;
+
+ ++RtemsTaskReqStart_Instance.start_extension_calls;
+}
+
+static const rtems_extensions_table extensions = {
+ .thread_start = ThreadStart
+};
+
+static void RtemsTaskReqStart_Pre_Id_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_EntryPoint_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_EntryPoint state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_EntryPoint_Valid: {
+ /*
+ * While the task entry point specified by the ``entry_point`` parameter
+ * is valid.
+ */
+ ctx->entry_point = WorkerA;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_EntryPoint_Null: {
+ /*
+ * While the task entry point specified by the ``entry_point`` parameter
+ * is equal to NULL.
+ */
+ ctx->entry_point = NULL;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_EntryPoint_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_Argument_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Argument state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Argument_Pointer: {
+ /*
+ * While the entry point argument specified by the ``argument`` parameter
+ * is a pointer.
+ */
+ ctx->argument = (rtems_task_argument) ctx;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Argument_Number: {
+ /*
+ * While the entry point argument specified by the ``argument`` parameter
+ * is a 32-bit number.
+ */
+ ctx->argument = UINT32_C( 0x87654321 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Argument_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_Dormant_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Dormant state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Dormant_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is dormant.
+ */
+ ctx->start = false;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Dormant_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not dormant.
+ */
+ ctx->start = true;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Dormant_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_Suspended_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_Status_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_start() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_start() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_start() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_task_start() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_EntryPoint_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_EntryPoint state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_EntryPoint_Set: {
+ /*
+ * The entry point of the task specified by the ``id`` parameter shall be
+ * set to the function specified by the ``entry_point`` parameter before
+ * the task is unblocked by the rtems_task_start() call.
+ */
+ T_eq_u32( ctx->counter, 1 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_EntryPoint_Nop: {
+ /*
+ * No entry point of a task shall be modified by the rtems_task_start()
+ * call.
+ */
+ T_eq_u32( ctx->counter, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_EntryPoint_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_Argument_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_Argument state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_Argument_Set: {
+ /*
+ * The entry point argument of the task specified by the ``id`` parameter
+ * shall be set to the value specified by the ``argument`` parameter
+ * before the task is unblocked by the rtems_task_start() call.
+ */
+ T_eq_u32( ctx->actual_argument, ctx->argument );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Argument_Nop: {
+ /*
+ * No entry point argument of a task shall be modified by the
+ * rtems_task_start() call.
+ */
+ T_eq_u32( ctx->actual_argument, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Argument_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_Unblock_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_Unblock state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_Unblock_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be unblocked by the
+ * rtems_task_start() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Unblock_Nop: {
+ /*
+ * No task shall be unblocked by the rtems_task_start() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_StartExtensions_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_StartExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_StartExtensions_Yes: {
+ /*
+ * The thread start user extensions shall be invoked by the
+ * rtems_task_start() call.
+ */
+ T_eq_u32( ctx->start_extension_calls, 1 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_StartExtensions_Nop: {
+ /*
+ * The thread start user extensions shall not be invoked by the
+ * rtems_task_start() call.
+ */
+ T_eq_u32( ctx->start_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_StartExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Setup( RtemsTaskReqStart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsTaskReqStart_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqStart_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqStart_Setup( ctx );
+}
+
+static void RtemsTaskReqStart_Teardown( RtemsTaskReqStart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+}
+
+static void RtemsTaskReqStart_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqStart_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqStart_Teardown( ctx );
+}
+
+static void RtemsTaskReqStart_Prepare( RtemsTaskReqStart_Context *ctx )
+{
+ ctx->actual_argument = 0;
+ ctx->counter = 0;
+ ctx->worker_id = CreateTask( "WORK", PRIO_DEFAULT );
+}
+
+static void RtemsTaskReqStart_Action( RtemsTaskReqStart_Context *ctx )
+{
+ T_scheduler_log *log;
+
+ if ( ctx->start ) {
+ StartTask( ctx->worker_id, WorkerB, 0 );
+ }
+
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->start_extension_calls = 0;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_start( ctx->id, ctx->entry_point, ctx->argument );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ Yield();
+}
+
+static void RtemsTaskReqStart_Cleanup( RtemsTaskReqStart_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_EntryPoint_NA : 1;
+ uint32_t Pre_Argument_NA : 1;
+ uint32_t Pre_Dormant_NA : 1;
+ uint32_t Pre_Suspended_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_EntryPoint : 2;
+ uint32_t Post_Argument : 2;
+ uint32_t Post_Unblock : 2;
+ uint32_t Post_StartExtensions : 2;
+} RtemsTaskReqStart_Entry;
+
+static const RtemsTaskReqStart_Entry
+RtemsTaskReqStart_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_InvAddr,
+ RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_Nop },
+ { 0, 0, 0, 0, 1, 1, RtemsTaskReqStart_Post_Status_InvId,
+ RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_Ok,
+ RtemsTaskReqStart_Post_EntryPoint_Set, RtemsTaskReqStart_Post_Argument_Set,
+ RtemsTaskReqStart_Post_Unblock_Yes,
+ RtemsTaskReqStart_Post_StartExtensions_Yes },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_IncStat,
+ RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_Nop }
+};
+
+static const uint8_t
+RtemsTaskReqStart_Map[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+static size_t RtemsTaskReqStart_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqStart_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqStart_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqStart_Fixture = {
+ .setup = RtemsTaskReqStart_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqStart_Teardown_Wrap,
+ .scope = RtemsTaskReqStart_Scope,
+ .initial_context = &RtemsTaskReqStart_Instance
+};
+
+static inline RtemsTaskReqStart_Entry RtemsTaskReqStart_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqStart_Entries[
+ RtemsTaskReqStart_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqStart( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqStart, &RtemsTaskReqStart_Fixture )
+{
+ RtemsTaskReqStart_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqStart_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqStart_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqStart_Pre_EntryPoint_Valid;
+ ctx->pcs[ 1 ] < RtemsTaskReqStart_Pre_EntryPoint_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ for (
+ ctx->pcs[ 2 ] = RtemsTaskReqStart_Pre_Argument_Pointer;
+ ctx->pcs[ 2 ] < RtemsTaskReqStart_Pre_Argument_NA;
+ ++ctx->pcs[ 2 ]
+ ) {
+ for (
+ ctx->pcs[ 3 ] = RtemsTaskReqStart_Pre_Dormant_Yes;
+ ctx->pcs[ 3 ] < RtemsTaskReqStart_Pre_Dormant_NA;
+ ++ctx->pcs[ 3 ]
+ ) {
+ for (
+ ctx->pcs[ 4 ] = RtemsTaskReqStart_Pre_Suspended_Yes;
+ ctx->pcs[ 4 ] < RtemsTaskReqStart_Pre_Suspended_NA;
+ ++ctx->pcs[ 4 ]
+ ) {
+ RtemsTaskReqStart_Entry entry;
+ size_t pcs[ 5 ];
+
+ entry = RtemsTaskReqStart_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Dormant_NA ) {
+ ctx->pcs[ 3 ] = RtemsTaskReqStart_Pre_Dormant_NA;
+ }
+
+ if ( entry.Pre_Suspended_NA ) {
+ ctx->pcs[ 4 ] = RtemsTaskReqStart_Pre_Suspended_NA;
+ }
+
+ RtemsTaskReqStart_Prepare( ctx );
+ RtemsTaskReqStart_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqStart_Pre_EntryPoint_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqStart_Pre_Argument_Prepare( ctx, ctx->pcs[ 2 ] );
+ RtemsTaskReqStart_Pre_Dormant_Prepare( ctx, ctx->pcs[ 3 ] );
+ RtemsTaskReqStart_Pre_Suspended_Prepare( ctx, ctx->pcs[ 4 ] );
+ RtemsTaskReqStart_Action( ctx );
+ RtemsTaskReqStart_Post_Status_Check( ctx, entry.Post_Status );
+ RtemsTaskReqStart_Post_EntryPoint_Check(
+ ctx,
+ entry.Post_EntryPoint
+ );
+ RtemsTaskReqStart_Post_Argument_Check( ctx, entry.Post_Argument );
+ RtemsTaskReqStart_Post_Unblock_Check( ctx, entry.Post_Unblock );
+ RtemsTaskReqStart_Post_StartExtensions_Check(
+ ctx,
+ entry.Post_StartExtensions
+ );
+ RtemsTaskReqStart_Cleanup( ctx );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-storage-size.c b/testsuites/validation/tc-task-storage-size.c
new file mode 100644
index 0000000000..47523f7252
--- /dev/null
+++ b/testsuites/validation/tc-task-storage-size.c
@@ -0,0 +1,388 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqStorageSize
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqStorageSize \
+ * spec:/rtems/task/req/storage-size
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqStorageSize_Pre_Id_Invalid,
+ RtemsTaskReqStorageSize_Pre_Id_Task,
+ RtemsTaskReqStorageSize_Pre_Id_NA
+} RtemsTaskReqStorageSize_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqStorageSize_Pre_Suspended_Yes,
+ RtemsTaskReqStorageSize_Pre_Suspended_No,
+ RtemsTaskReqStorageSize_Pre_Suspended_NA
+} RtemsTaskReqStorageSize_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqStorageSize_Post_Status_Ok,
+ RtemsTaskReqStorageSize_Post_Status_InvId,
+ RtemsTaskReqStorageSize_Post_Status_AlrdySus,
+ RtemsTaskReqStorageSize_Post_Status_NA
+} RtemsTaskReqStorageSize_Post_Status;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/storage-size test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_suspend() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_suspend()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqStorageSize_Context;
+
+static RtemsTaskReqStorageSize_Context
+ RtemsTaskReqStorageSize_Instance;
+
+static const char * const RtemsTaskReqStorageSize_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStorageSize_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqStorageSize_PreDesc[] = {
+ RtemsTaskReqStorageSize_PreDesc_Id,
+ RtemsTaskReqStorageSize_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqStorageSize_Pre_Id_Prepare(
+ RtemsTaskReqStorageSize_Context *ctx,
+ RtemsTaskReqStorageSize_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStorageSize_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStorageSize_Pre_Suspended_Prepare(
+ RtemsTaskReqStorageSize_Context *ctx,
+ RtemsTaskReqStorageSize_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStorageSize_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStorageSize_Post_Status_Check(
+ RtemsTaskReqStorageSize_Context *ctx,
+ RtemsTaskReqStorageSize_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStorageSize_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Post_Status_AlrdySus: {
+ /*
+ * The return status of rtems_task_suspend() shall be
+ * RTEMS_ALREADY_SUSPENDED.
+ */
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStorageSize_Setup(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqStorageSize_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqStorageSize_Setup( ctx );
+}
+
+static void RtemsTaskReqStorageSize_Teardown(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqStorageSize_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqStorageSize_Teardown( ctx );
+}
+
+static void RtemsTaskReqStorageSize_Action(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_suspend( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqStorageSize_Entry;
+
+static const RtemsTaskReqStorageSize_Entry
+RtemsTaskReqStorageSize_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqStorageSize_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqStorageSize_Post_Status_AlrdySus },
+ { 0, 0, 0, RtemsTaskReqStorageSize_Post_Status_Ok }
+};
+
+static const uint8_t
+RtemsTaskReqStorageSize_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqStorageSize_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqStorageSize_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqStorageSize_Fixture = {
+ .setup = RtemsTaskReqStorageSize_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqStorageSize_Teardown_Wrap,
+ .scope = RtemsTaskReqStorageSize_Scope,
+ .initial_context = &RtemsTaskReqStorageSize_Instance
+};
+
+static inline RtemsTaskReqStorageSize_Entry RtemsTaskReqStorageSize_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqStorageSize_Entries[
+ RtemsTaskReqStorageSize_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqStorageSize( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqStorageSize,
+ &RtemsTaskReqStorageSize_Fixture
+)
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqStorageSize_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqStorageSize_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_Yes;
+ ctx->pcs[ 1 ] < RtemsTaskReqStorageSize_Pre_Suspended_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ RtemsTaskReqStorageSize_Entry entry;
+ size_t pcs[ 2 ];
+
+ entry = RtemsTaskReqStorageSize_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Suspended_NA ) {
+ ctx->pcs[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_NA;
+ }
+
+ RtemsTaskReqStorageSize_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqStorageSize_Pre_Suspended_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqStorageSize_Action( ctx );
+ RtemsTaskReqStorageSize_Post_Status_Check( ctx, entry.Post_Status );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-suspend.c b/testsuites/validation/tc-task-suspend.c
new file mode 100644
index 0000000000..8b720d212e
--- /dev/null
+++ b/testsuites/validation/tc-task-suspend.c
@@ -0,0 +1,378 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskReqSuspend
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskReqSuspend spec:/rtems/task/req/suspend
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSuspend_Pre_Id_Invalid,
+ RtemsTaskReqSuspend_Pre_Id_Task,
+ RtemsTaskReqSuspend_Pre_Id_NA
+} RtemsTaskReqSuspend_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqSuspend_Pre_Suspended_Yes,
+ RtemsTaskReqSuspend_Pre_Suspended_No,
+ RtemsTaskReqSuspend_Pre_Suspended_NA
+} RtemsTaskReqSuspend_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqSuspend_Post_Status_Ok,
+ RtemsTaskReqSuspend_Post_Status_InvId,
+ RtemsTaskReqSuspend_Post_Status_AlrdySus,
+ RtemsTaskReqSuspend_Post_Status_NA
+} RtemsTaskReqSuspend_Post_Status;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/suspend test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_suspend() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_suspend()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief This member indicates if the test action loop is currently
+ * executed.
+ */
+ bool in_action_loop;
+} RtemsTaskReqSuspend_Context;
+
+static RtemsTaskReqSuspend_Context
+ RtemsTaskReqSuspend_Instance;
+
+static const char * const RtemsTaskReqSuspend_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSuspend_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSuspend_PreDesc[] = {
+ RtemsTaskReqSuspend_PreDesc_Id,
+ RtemsTaskReqSuspend_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqSuspend_Pre_Id_Prepare(
+ RtemsTaskReqSuspend_Context *ctx,
+ RtemsTaskReqSuspend_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSuspend_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSuspend_Pre_Suspended_Prepare(
+ RtemsTaskReqSuspend_Context *ctx,
+ RtemsTaskReqSuspend_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSuspend_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSuspend_Post_Status_Check(
+ RtemsTaskReqSuspend_Context *ctx,
+ RtemsTaskReqSuspend_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSuspend_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Post_Status_AlrdySus: {
+ /*
+ * The return status of rtems_task_suspend() shall be
+ * RTEMS_ALREADY_SUSPENDED.
+ */
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSuspend_Setup( RtemsTaskReqSuspend_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqSuspend_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqSuspend_Setup( ctx );
+}
+
+static void RtemsTaskReqSuspend_Teardown( RtemsTaskReqSuspend_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqSuspend_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+
+ ctx = arg;
+ ctx->in_action_loop = false;
+ RtemsTaskReqSuspend_Teardown( ctx );
+}
+
+static void RtemsTaskReqSuspend_Action( RtemsTaskReqSuspend_Context *ctx )
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_suspend( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqSuspend_Entry;
+
+static const RtemsTaskReqSuspend_Entry
+RtemsTaskReqSuspend_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqSuspend_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqSuspend_Post_Status_AlrdySus },
+ { 0, 0, 0, RtemsTaskReqSuspend_Post_Status_Ok }
+};
+
+static const uint8_t
+RtemsTaskReqSuspend_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqSuspend_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->in_action_loop ) {
+ return T_get_scope( RtemsTaskReqSuspend_PreDesc, buf, n, ctx->pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSuspend_Fixture = {
+ .setup = RtemsTaskReqSuspend_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqSuspend_Teardown_Wrap,
+ .scope = RtemsTaskReqSuspend_Scope,
+ .initial_context = &RtemsTaskReqSuspend_Instance
+};
+
+static inline RtemsTaskReqSuspend_Entry RtemsTaskReqSuspend_GetEntry(
+ size_t index
+)
+{
+ return RtemsTaskReqSuspend_Entries[
+ RtemsTaskReqSuspend_Map[ index ]
+ ];
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSuspend( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqSuspend, &RtemsTaskReqSuspend_Fixture )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+ size_t index;
+
+ ctx = T_fixture_context();
+ ctx->in_action_loop = true;
+ index = 0;
+
+ for (
+ ctx->pcs[ 0 ] = RtemsTaskReqSuspend_Pre_Id_Invalid;
+ ctx->pcs[ 0 ] < RtemsTaskReqSuspend_Pre_Id_NA;
+ ++ctx->pcs[ 0 ]
+ ) {
+ for (
+ ctx->pcs[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_Yes;
+ ctx->pcs[ 1 ] < RtemsTaskReqSuspend_Pre_Suspended_NA;
+ ++ctx->pcs[ 1 ]
+ ) {
+ RtemsTaskReqSuspend_Entry entry;
+ size_t pcs[ 2 ];
+
+ entry = RtemsTaskReqSuspend_GetEntry( index );
+ ++index;
+
+ memcpy( pcs, ctx->pcs, sizeof( pcs ) );
+
+ if ( entry.Pre_Suspended_NA ) {
+ ctx->pcs[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_NA;
+ }
+
+ RtemsTaskReqSuspend_Pre_Id_Prepare( ctx, ctx->pcs[ 0 ] );
+ RtemsTaskReqSuspend_Pre_Suspended_Prepare( ctx, ctx->pcs[ 1 ] );
+ RtemsTaskReqSuspend_Action( ctx );
+ RtemsTaskReqSuspend_Post_Status_Check( ctx, entry.Post_Status );
+ memcpy( ctx->pcs, pcs, sizeof( ctx->pcs ) );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task.c b/testsuites/validation/tc-task.c
new file mode 100644
index 0000000000..40fc309b6c
--- /dev/null
+++ b/testsuites/validation/tc-task.c
@@ -0,0 +1,207 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestCaseRtemsTaskValTask
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+#include <rtems/score/apimutex.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestCaseRtemsTaskValTask spec:/rtems/task/val/task
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ *
+ * @brief This test case collection provides validation test cases for
+ * requirements of the @ref RTEMSAPIClassicTasks.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call rtems_task_self() check the returned value.
+ *
+ * - Check that the returned value is equal to the object identifier of the
+ * calling task.
+ *
+ * - Call rtems_task_iterate() with a visitor which always returns false.
+ *
+ * - Check that the all counter is equal to the count of tasks. Check that
+ * the calling task was visited exacly once. Firstly, this shows that
+ * rtems_task_iterate() used the parameters specified by ``visitor`` and
+ * ``arg``. Secondly, this shows that the iteration was done over all
+ * tasks.
+ *
+ * - Check that the object alloctor mutex was not owned before and after the
+ * call. Check that the object alloctor mutex was owned during the
+ * iteration.
+ *
+ * - Call rtems_task_iterate() with a visitor which returns true.
+ *
+ * - Check that the all counter is equal to one. This shows that the
+ * iteration stops when the visitor returns true.
+ *
+ * @{
+ */
+
+typedef struct {
+ bool owner_before;
+ bool owner_in_visitor;
+ bool owner_after;
+ uint32_t counter_all;
+ uint32_t counter_self;
+ bool done;
+} TaskIterateContext;
+
+static bool TaskVisitor( rtems_tcb *tcb, void *arg )
+{
+ TaskIterateContext *ctx;
+
+ ctx = arg;
+ ++ctx->counter_all;
+
+ if ( rtems_task_self() == tcb->Object.id ) {
+ ++ctx->counter_self;
+ }
+
+ ctx->owner_in_visitor = _RTEMS_Allocator_is_owner();
+
+ return ctx->done;
+}
+
+/**
+ * @brief Call rtems_task_self() check the returned value.
+ */
+static void RtemsTaskValTask_Action_0( void )
+{
+ rtems_id id;
+
+ id = rtems_task_self();
+
+ /*
+ * Check that the returned value is equal to the object identifier of the
+ * calling task.
+ */
+ T_step_eq_u32( 0, id, 0x0a010001 );
+}
+
+/**
+ * @brief Call rtems_task_iterate() with a visitor which always returns false.
+ */
+static void RtemsTaskValTask_Action_1( void )
+{
+ TaskIterateContext ctx;
+ uint32_t task_count;
+
+ task_count = rtems_scheduler_get_processor_maximum();
+
+ if ( task_count > 4 ) {
+ task_count = 4;
+ }
+
+ ++task_count;
+
+ memset( &ctx, 0, sizeof( ctx ) );
+ ctx.owner_before = _RTEMS_Allocator_is_owner();
+ rtems_task_iterate( TaskVisitor, &ctx );
+ ctx.owner_after = _RTEMS_Allocator_is_owner();
+
+ /*
+ * Check that the all counter is equal to the count of tasks. Check that the
+ * calling task was visited exacly once. Firstly, this shows that
+ * rtems_task_iterate() used the parameters specified by ``visitor`` and
+ * ``arg``. Secondly, this shows that the iteration was done over all tasks.
+ */
+ T_step_eq_u32( 1, ctx.counter_all, task_count );
+ T_step_eq_u32( 2, ctx.counter_self, 1 );
+
+ /*
+ * Check that the object alloctor mutex was not owned before and after the
+ * call. Check that the object alloctor mutex was owned during the
+ * iteration.
+ */
+ T_step_false( 3, ctx.owner_before );
+ T_step_true( 4, ctx.owner_in_visitor );
+ T_step_false( 5, ctx.owner_after );
+}
+
+/**
+ * @brief Call rtems_task_iterate() with a visitor which returns true.
+ */
+static void RtemsTaskValTask_Action_2( void )
+{
+ TaskIterateContext ctx;
+
+ memset( &ctx, 0, sizeof( ctx ) );
+ ctx.done = true;
+ rtems_task_iterate( TaskVisitor, &ctx );
+
+ /*
+ * Check that the all counter is equal to one. This shows that the iteration
+ * stops when the visitor returns true.
+ */
+ T_step_eq_u32( 6, ctx.counter_all, 1 );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskValTask( void )
+ */
+T_TEST_CASE( RtemsTaskValTask )
+{
+ T_plan( 7 );
+
+ RtemsTaskValTask_Action_0();
+ RtemsTaskValTask_Action_1();
+ RtemsTaskValTask_Action_2();
+}
+
+/** @} */