forked from Imagelibrary/rtems
validation: Test Task Manager
The test source code is generated from specification items by the "./spec2modules.py" script contained in the git://git.rtems.org/rtems-central.git Git repository. Please read the "How-To" section in the "Software Requirements Engineering" chapter of the RTEMS Software Engineering manual to get more information about the process. Update #3716.
This commit is contained in:
@@ -50,6 +50,8 @@ links:
|
||||
uid: validation-non-smp
|
||||
- role: build-dependency
|
||||
uid: validation-one-cpu-0
|
||||
- role: build-dependency
|
||||
uid: validation-one-cpu-1
|
||||
- role: build-dependency
|
||||
uid: validation-smp-only-0
|
||||
- role: build-dependency
|
||||
|
||||
@@ -16,6 +16,7 @@ source:
|
||||
- testsuites/validation/tc-message-performance.c
|
||||
- testsuites/validation/tc-part-performance.c
|
||||
- testsuites/validation/tc-sem-performance.c
|
||||
- testsuites/validation/tc-task-performance.c
|
||||
- testsuites/validation/ts-performance-no-clock-0.c
|
||||
stlib: []
|
||||
target: testsuites/validation/ts-performance-no-clock-0.exe
|
||||
|
||||
@@ -14,8 +14,6 @@ source:
|
||||
- testsuites/validation/tc-acfg-appl-needs-clock-driver.c
|
||||
- testsuites/validation/tc-event-send-receive.c
|
||||
- testsuites/validation/tc-object.c
|
||||
- testsuites/validation/tc-task-construct-errors.c
|
||||
- testsuites/validation/tc-task-create-errors.c
|
||||
- testsuites/validation/tr-event-send-receive.c
|
||||
- testsuites/validation/ts-validation-0.c
|
||||
stlib: []
|
||||
|
||||
@@ -11,8 +11,7 @@ includes: []
|
||||
ldflags: []
|
||||
links: []
|
||||
source:
|
||||
- testsuites/validation/tc-task-construct-errors.c
|
||||
- testsuites/validation/tc-task-create-errors.c
|
||||
- testsuites/validation/tc-task-construct.c
|
||||
- testsuites/validation/ts-validation-1.c
|
||||
stlib: []
|
||||
target: testsuites/validation/ts-validation-1.exe
|
||||
|
||||
@@ -73,6 +73,26 @@ source:
|
||||
- testsuites/validation/tc-signal-catch.c
|
||||
- testsuites/validation/tc-signals.c
|
||||
- testsuites/validation/tc-signal-send.c
|
||||
- testsuites/validation/tc-task.c
|
||||
- testsuites/validation/tc-task-create-errors.c
|
||||
- testsuites/validation/tc-task-delete.c
|
||||
- testsuites/validation/tc-task-exit.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-task-wake-after.c
|
||||
- testsuites/validation/tc-task-wake-when.c
|
||||
- testsuites/validation/tr-event-constant.c
|
||||
- testsuites/validation/tr-mtx-seize-try.c
|
||||
- testsuites/validation/tr-mtx-seize-wait.c
|
||||
|
||||
@@ -22,6 +22,11 @@ source:
|
||||
- testsuites/validation/tc-signal-catch.c
|
||||
- testsuites/validation/tc-signal-send.c
|
||||
- testsuites/validation/tc-score-fatal.c
|
||||
- testsuites/validation/tc-task-create-errors.c
|
||||
- testsuites/validation/tc-task-mode.c
|
||||
- testsuites/validation/tc-task-set-affinity.c
|
||||
- testsuites/validation/tc-task-set-priority.c
|
||||
- testsuites/validation/tc-task-wake-after.c
|
||||
- testsuites/validation/ts-validation-one-cpu-0.c
|
||||
stlib: []
|
||||
target: testsuites/validation/ts-validation-one-cpu-0.exe
|
||||
|
||||
20
spec/build/testsuites/validation/validation-one-cpu-1.yml
Normal file
20
spec/build/testsuites/validation/validation-one-cpu-1.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
|
||||
build-type: test-program
|
||||
cflags: []
|
||||
copyrights:
|
||||
- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
|
||||
cppflags: []
|
||||
cxxflags: []
|
||||
enabled-by: true
|
||||
features: c cprogram
|
||||
includes: []
|
||||
ldflags: []
|
||||
links: []
|
||||
source:
|
||||
- testsuites/validation/tc-task-construct.c
|
||||
- testsuites/validation/ts-validation-one-cpu-1.c
|
||||
stlib: []
|
||||
target: testsuites/validation/ts-validation-one-cpu-1.exe
|
||||
type: build
|
||||
use-after: []
|
||||
use-before: []
|
||||
File diff suppressed because it is too large
Load Diff
4950
testsuites/validation/tc-task-construct.c
Normal file
4950
testsuites/validation/tc-task-construct.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -57,14 +57,16 @@
|
||||
#include <rtems/score/apimutex.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/test.h>
|
||||
|
||||
/**
|
||||
* @defgroup RTEMSTestCaseRtemsTaskReqCreateErrors \
|
||||
* spec:/rtems/task/req/create-errors
|
||||
*
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidation0
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidation1
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
@@ -280,8 +282,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 )
|
||||
@@ -419,7 +419,7 @@ static void RtemsTaskReqCreateErrors_Pre_Prio_Prepare(
|
||||
/*
|
||||
* While the ``initial_priority`` parameter is valid and non-zero.
|
||||
*/
|
||||
ctx->initial_priority = 254;
|
||||
ctx->initial_priority = RTEMS_MAXIMUM_PRIORITY - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
4870
testsuites/validation/tc-task-delete.c
Normal file
4870
testsuites/validation/tc-task-delete.c
Normal file
File diff suppressed because it is too large
Load Diff
979
testsuites/validation/tc-task-exit.c
Normal file
979
testsuites/validation/tc-task-exit.c
Normal file
@@ -0,0 +1,979 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestCaseRtemsTaskReqExit
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <rtems/score/apimutex.h>
|
||||
#include <rtems/score/threaddispatch.h>
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/test.h>
|
||||
|
||||
/**
|
||||
* @defgroup RTEMSTestCaseRtemsTaskReqExit spec:/rtems/task/req/exit
|
||||
*
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Pre_Restarting_Yes,
|
||||
RtemsTaskReqExit_Pre_Restarting_No,
|
||||
RtemsTaskReqExit_Pre_Restarting_NA
|
||||
} RtemsTaskReqExit_Pre_Restarting;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Pre_Terminating_Yes,
|
||||
RtemsTaskReqExit_Pre_Terminating_No,
|
||||
RtemsTaskReqExit_Pre_Terminating_NA
|
||||
} RtemsTaskReqExit_Pre_Terminating;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Pre_Protected_Yes,
|
||||
RtemsTaskReqExit_Pre_Protected_No,
|
||||
RtemsTaskReqExit_Pre_Protected_NA
|
||||
} RtemsTaskReqExit_Pre_Protected;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Pre_ThreadDispatch_Enabled,
|
||||
RtemsTaskReqExit_Pre_ThreadDispatch_Disabled,
|
||||
RtemsTaskReqExit_Pre_ThreadDispatch_NA
|
||||
} RtemsTaskReqExit_Pre_ThreadDispatch;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Post_FatalError_Yes,
|
||||
RtemsTaskReqExit_Post_FatalError_Nop,
|
||||
RtemsTaskReqExit_Post_FatalError_NA
|
||||
} RtemsTaskReqExit_Post_FatalError;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Post_DeleteExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_DeleteExtensions_NA
|
||||
} RtemsTaskReqExit_Post_DeleteExtensions;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Post_RestartExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_RestartExtensions_NA
|
||||
} RtemsTaskReqExit_Post_RestartExtensions;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Post_TerminateExtensions_Yes,
|
||||
RtemsTaskReqExit_Post_TerminateExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_TerminateExtensions_NA
|
||||
} RtemsTaskReqExit_Post_TerminateExtensions;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Post_Block_Yes,
|
||||
RtemsTaskReqExit_Post_Block_Nop,
|
||||
RtemsTaskReqExit_Post_Block_NA
|
||||
} RtemsTaskReqExit_Post_Block;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Post_ID_Valid,
|
||||
RtemsTaskReqExit_Post_ID_Invalid,
|
||||
RtemsTaskReqExit_Post_ID_NA
|
||||
} RtemsTaskReqExit_Post_ID;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqExit_Post_Delete_NextAllocate,
|
||||
RtemsTaskReqExit_Post_Delete_Nop,
|
||||
RtemsTaskReqExit_Post_Delete_NA
|
||||
} RtemsTaskReqExit_Post_Delete;
|
||||
|
||||
typedef struct {
|
||||
uint32_t Skip : 1;
|
||||
uint32_t Pre_Restarting_NA : 1;
|
||||
uint32_t Pre_Terminating_NA : 1;
|
||||
uint32_t Pre_Protected_NA : 1;
|
||||
uint32_t Pre_ThreadDispatch_NA : 1;
|
||||
uint32_t Post_FatalError : 2;
|
||||
uint32_t Post_DeleteExtensions : 1;
|
||||
uint32_t Post_RestartExtensions : 1;
|
||||
uint32_t Post_TerminateExtensions : 2;
|
||||
uint32_t Post_Block : 2;
|
||||
uint32_t Post_ID : 2;
|
||||
uint32_t Post_Delete : 2;
|
||||
} RtemsTaskReqExit_Entry;
|
||||
|
||||
/**
|
||||
* @brief Test context for spec:/rtems/task/req/exit test case.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief This member provides the scheduler operation records.
|
||||
*/
|
||||
T_scheduler_log_4 scheduler_log;
|
||||
|
||||
/**
|
||||
* @brief This member contains the identifier of the runner task.
|
||||
*/
|
||||
rtems_id runner_id;
|
||||
|
||||
/**
|
||||
* @brief This member contains the identifier of the worker task.
|
||||
*/
|
||||
rtems_id worker_id;
|
||||
|
||||
/**
|
||||
* @brief This member contains the identifier of the deleter task.
|
||||
*/
|
||||
rtems_id deleter_id;
|
||||
|
||||
/**
|
||||
* @brief This member contains the identifier of the test user extensions.
|
||||
*/
|
||||
rtems_id extension_id;
|
||||
|
||||
/**
|
||||
* @brief This member contains the count of fatal extension calls.
|
||||
*/
|
||||
uint32_t fatal_extension_calls;
|
||||
|
||||
/**
|
||||
* @brief This member contains the count of thread delete extension calls.
|
||||
*/
|
||||
uint32_t delete_extension_calls;
|
||||
|
||||
/**
|
||||
* @brief This member contains the count of thread restart extension calls.
|
||||
*/
|
||||
uint32_t restart_extension_calls;
|
||||
|
||||
/**
|
||||
* @brief This member contains the count of thread terminate extension calls.
|
||||
*/
|
||||
uint32_t terminate_extension_calls;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the thread life of the worker is
|
||||
* protected before the rtems_task_exit() call.
|
||||
*/
|
||||
bool protected;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the worker locked the allocator.
|
||||
*/
|
||||
bool allocator_locked;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the worker is restarting before the
|
||||
* rtems_task_exit() call.
|
||||
*/
|
||||
bool restarting;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the worker is terminating before the
|
||||
* rtems_task_exit() call.
|
||||
*/
|
||||
bool terminating;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then thread dispatching is disabled by the
|
||||
* worker task before the rtems_task_exit() call.
|
||||
*/
|
||||
bool dispatch_disabled;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then it is expected to delete the worker.
|
||||
*/
|
||||
bool delete_worker_expected;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 4 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqExit_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} RtemsTaskReqExit_Context;
|
||||
|
||||
static RtemsTaskReqExit_Context
|
||||
RtemsTaskReqExit_Instance;
|
||||
|
||||
static const char * const RtemsTaskReqExit_PreDesc_Restarting[] = {
|
||||
"Yes",
|
||||
"No",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqExit_PreDesc_Terminating[] = {
|
||||
"Yes",
|
||||
"No",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqExit_PreDesc_Protected[] = {
|
||||
"Yes",
|
||||
"No",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqExit_PreDesc_ThreadDispatch[] = {
|
||||
"Enabled",
|
||||
"Disabled",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const * const RtemsTaskReqExit_PreDesc[] = {
|
||||
RtemsTaskReqExit_PreDesc_Restarting,
|
||||
RtemsTaskReqExit_PreDesc_Terminating,
|
||||
RtemsTaskReqExit_PreDesc_Protected,
|
||||
RtemsTaskReqExit_PreDesc_ThreadDispatch,
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef RtemsTaskReqExit_Context Context;
|
||||
|
||||
static void Signal( rtems_signal_set signals )
|
||||
{
|
||||
Context *ctx;
|
||||
T_scheduler_log *log;
|
||||
Thread_Life_state life_state;
|
||||
|
||||
(void) signals;
|
||||
ctx = T_fixture_context();
|
||||
|
||||
if ( ctx->dispatch_disabled ) {
|
||||
_Thread_Dispatch_disable();
|
||||
}
|
||||
|
||||
/* Check that the thread life state was prepared correctly */
|
||||
life_state = GetExecuting()->Life.state;
|
||||
T_eq( ctx->protected, ( life_state & THREAD_LIFE_PROTECTED ) != 0 );
|
||||
T_eq( ctx->restarting, ( life_state & THREAD_LIFE_RESTARTING ) != 0 );
|
||||
T_eq( ctx->terminating, ( life_state & THREAD_LIFE_TERMINATING ) != 0 );
|
||||
|
||||
log = T_scheduler_record_4( &ctx->scheduler_log );
|
||||
T_null( log );
|
||||
|
||||
ctx->delete_extension_calls = 0;
|
||||
ctx->fatal_extension_calls = 0;
|
||||
ctx->restart_extension_calls = 0;
|
||||
ctx->terminate_extension_calls = 0;
|
||||
|
||||
rtems_task_exit();
|
||||
}
|
||||
|
||||
static void Deleter( rtems_task_argument arg )
|
||||
{
|
||||
Context *ctx;
|
||||
|
||||
ctx = (Context *) arg;
|
||||
|
||||
if ( ctx != NULL ) {
|
||||
DeleteTask( ctx->worker_id );
|
||||
}
|
||||
|
||||
SuspendSelf();
|
||||
}
|
||||
|
||||
static void Worker( rtems_task_argument arg )
|
||||
{
|
||||
Context *ctx;
|
||||
rtems_status_code sc;
|
||||
|
||||
ctx = (Context *) arg;
|
||||
|
||||
sc = rtems_signal_catch( Signal, RTEMS_NO_ASR );
|
||||
T_rsc_success( sc );
|
||||
|
||||
if ( ctx->protected ) {
|
||||
_RTEMS_Lock_allocator();
|
||||
ctx->allocator_locked = true;
|
||||
}
|
||||
|
||||
Yield();
|
||||
}
|
||||
|
||||
static void UnlockAllocator( Context *ctx )
|
||||
{
|
||||
if ( ctx->allocator_locked ) {
|
||||
ctx->allocator_locked = false;
|
||||
_RTEMS_Unlock_allocator();
|
||||
}
|
||||
}
|
||||
|
||||
static void Fatal(
|
||||
rtems_fatal_source source,
|
||||
rtems_fatal_code code,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
Context *ctx;
|
||||
T_scheduler_log *log;
|
||||
Per_CPU_Control *cpu_self;
|
||||
|
||||
ctx = arg;
|
||||
++ctx->fatal_extension_calls;
|
||||
|
||||
T_eq_int( source, INTERNAL_ERROR_CORE );
|
||||
T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
|
||||
T_assert_eq_int( ctx->fatal_extension_calls, 1 );
|
||||
|
||||
log = T_scheduler_record( NULL );
|
||||
T_eq_ptr( &log->header, &ctx->scheduler_log.header );
|
||||
|
||||
UnlockAllocator( ctx );
|
||||
SuspendSelf();
|
||||
|
||||
cpu_self = _Per_CPU_Get();
|
||||
_Thread_Dispatch_unnest( cpu_self );
|
||||
_Thread_Dispatch_direct_no_return( cpu_self );
|
||||
}
|
||||
|
||||
static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
|
||||
{
|
||||
Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
++ctx->delete_extension_calls;
|
||||
|
||||
T_eq_u32( executing->Object.id, ctx->runner_id );
|
||||
|
||||
if ( ctx->delete_worker_expected ) {
|
||||
T_eq_u32( deleted->Object.id, ctx->worker_id );
|
||||
}
|
||||
}
|
||||
|
||||
static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
|
||||
{
|
||||
Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
++ctx->restart_extension_calls;
|
||||
}
|
||||
|
||||
static void ThreadTerminate( rtems_tcb *executing )
|
||||
{
|
||||
Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
++ctx->terminate_extension_calls;
|
||||
|
||||
T_eq_u32( executing->Object.id, ctx->worker_id );
|
||||
|
||||
UnlockAllocator( ctx );
|
||||
}
|
||||
|
||||
static const rtems_extensions_table extensions = {
|
||||
.thread_delete = ThreadDelete,
|
||||
.thread_restart = ThreadRestart,
|
||||
.thread_terminate = ThreadTerminate
|
||||
};
|
||||
|
||||
static void RtemsTaskReqExit_Pre_Restarting_Prepare(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Pre_Restarting state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Pre_Restarting_Yes: {
|
||||
/*
|
||||
* While the calling task is restarting.
|
||||
*/
|
||||
ctx->restarting = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_Restarting_No: {
|
||||
/*
|
||||
* While the calling task is not restarting.
|
||||
*/
|
||||
ctx->restarting = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_Restarting_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Pre_Terminating_Prepare(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Pre_Terminating state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Pre_Terminating_Yes: {
|
||||
/*
|
||||
* While the calling task is terminating.
|
||||
*/
|
||||
ctx->terminating = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_Terminating_No: {
|
||||
/*
|
||||
* While the calling task is not terminating.
|
||||
*/
|
||||
ctx->terminating = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_Terminating_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Pre_Protected_Prepare(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Pre_Protected state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Pre_Protected_Yes: {
|
||||
/*
|
||||
* While the thread life of the calling task is protected.
|
||||
*/
|
||||
ctx->protected = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_Protected_No: {
|
||||
/*
|
||||
* While the thread life of the calling task is not protected.
|
||||
*/
|
||||
ctx->protected = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_Protected_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Pre_ThreadDispatch_Prepare(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Pre_ThreadDispatch state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Pre_ThreadDispatch_Enabled: {
|
||||
/*
|
||||
* While thread dispatching is enabled for the calling task.
|
||||
*/
|
||||
ctx->dispatch_disabled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_ThreadDispatch_Disabled: {
|
||||
/*
|
||||
* While thread dispatching is disabled for the calling task.
|
||||
*/
|
||||
ctx->dispatch_disabled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Pre_ThreadDispatch_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Post_FatalError_Check(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Post_FatalError state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Post_FatalError_Yes: {
|
||||
/*
|
||||
* The fatal error with a fatal source of INTERNAL_ERROR_CORE and a fatal
|
||||
* code of INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL shall occur
|
||||
* by the rtems_task_exit() call.
|
||||
*/
|
||||
T_eq_u32( ctx->fatal_extension_calls, 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_FatalError_Nop: {
|
||||
/*
|
||||
* No fatal error shall occur by the rtems_task_exit() call.
|
||||
*/
|
||||
T_eq_u32( ctx->fatal_extension_calls, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_FatalError_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Post_DeleteExtensions_Check(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Post_DeleteExtensions state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Post_DeleteExtensions_Nop: {
|
||||
/*
|
||||
* The thread delete user extensions shall not be invoked by the
|
||||
* rtems_task_exit() call.
|
||||
*/
|
||||
T_eq_u32( ctx->delete_extension_calls, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_DeleteExtensions_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Post_RestartExtensions_Check(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Post_RestartExtensions state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Post_RestartExtensions_Nop: {
|
||||
/*
|
||||
* The thread restart user extensions shall not be invoked by the
|
||||
* rtems_task_exit() call.
|
||||
*/
|
||||
T_eq_u32( ctx->restart_extension_calls, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_RestartExtensions_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Post_TerminateExtensions_Check(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Post_TerminateExtensions state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Post_TerminateExtensions_Yes: {
|
||||
/*
|
||||
* The thread terminate user extensions shall be invoked by the
|
||||
* rtems_task_exit() call.
|
||||
*/
|
||||
if ( ctx->protected ) {
|
||||
T_eq_u32( ctx->terminate_extension_calls, 2 );
|
||||
} else {
|
||||
T_eq_u32( ctx->terminate_extension_calls, 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_TerminateExtensions_Nop: {
|
||||
/*
|
||||
* The thread terminate user extensions shall not be invoked by the
|
||||
* rtems_task_exit() call.
|
||||
*/
|
||||
T_eq_u32( ctx->terminate_extension_calls, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_TerminateExtensions_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Post_Block_Check(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Post_Block state
|
||||
)
|
||||
{
|
||||
const T_scheduler_event *event;
|
||||
size_t index;
|
||||
|
||||
index = 0;
|
||||
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Post_Block_Yes: {
|
||||
/*
|
||||
* The calling task shall be blocked exactly once by the
|
||||
* rtems_task_exit() call.
|
||||
*/
|
||||
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
|
||||
T_eq_int( event->operation, T_SCHEDULER_BLOCK );
|
||||
T_eq_u32( event->thread->Object.id, ctx->worker_id );
|
||||
|
||||
if ( ctx->terminating ) {
|
||||
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
|
||||
T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
|
||||
T_eq_u32( event->thread->Object.id, ctx->deleter_id );
|
||||
|
||||
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
|
||||
T_eq_int( event->operation, T_SCHEDULER_BLOCK );
|
||||
T_eq_u32( event->thread->Object.id, ctx->deleter_id );
|
||||
}
|
||||
|
||||
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
|
||||
T_eq_int( event->operation, T_SCHEDULER_NOP );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_Block_Nop: {
|
||||
/*
|
||||
* No task shall be blocked by the rtems_task_exit() call.
|
||||
*/
|
||||
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_Block_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Post_ID_Check(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Post_ID state
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id id;
|
||||
|
||||
sc = rtems_task_get_scheduler( ctx->worker_id, &id );
|
||||
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Post_ID_Valid: {
|
||||
/*
|
||||
* The object identifier of the calling task shall be valid.
|
||||
*/
|
||||
T_rsc_success( sc );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_ID_Invalid: {
|
||||
/*
|
||||
* The object identifier of the calling task shall be invalid.
|
||||
*/
|
||||
T_rsc( sc, RTEMS_INVALID_ID );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_ID_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Post_Delete_Check(
|
||||
RtemsTaskReqExit_Context *ctx,
|
||||
RtemsTaskReqExit_Post_Delete state
|
||||
)
|
||||
{
|
||||
rtems_id id;
|
||||
|
||||
id = CreateTask( "TEMP", PRIO_LOW );
|
||||
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqExit_Post_Delete_NextAllocate: {
|
||||
/*
|
||||
* The calling task shall be deleted by the next directive which
|
||||
* allocates a task.
|
||||
*/
|
||||
T_eq_u32( ctx->delete_extension_calls, 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_Delete_Nop: {
|
||||
/*
|
||||
* The calling task shall not be deleted by the next directive which
|
||||
* allocates a task.
|
||||
*/
|
||||
T_eq_u32( ctx->delete_extension_calls, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqExit_Post_Delete_NA:
|
||||
break;
|
||||
}
|
||||
|
||||
DeleteTask( id );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Setup( RtemsTaskReqExit_Context *ctx )
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
ctx->runner_id = rtems_task_self();
|
||||
|
||||
sc = rtems_extension_create(
|
||||
rtems_build_name( 'T', 'E', 'S', 'T' ),
|
||||
&extensions,
|
||||
&ctx->extension_id
|
||||
);
|
||||
T_rsc_success( sc );
|
||||
|
||||
SetFatalHandler( Fatal, ctx );
|
||||
SetSelfPriority( PRIO_NORMAL );
|
||||
|
||||
ctx->deleter_id = CreateTask( "DELE", PRIO_HIGH );
|
||||
StartTask( ctx->deleter_id, Deleter, NULL );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Setup_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqExit_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqExit_Setup( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Teardown( RtemsTaskReqExit_Context *ctx )
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_extension_delete( ctx->extension_id );
|
||||
T_rsc_success( sc );
|
||||
|
||||
SetFatalHandler( NULL, NULL );
|
||||
DeleteTask( ctx->deleter_id );
|
||||
RestoreRunnerASR();
|
||||
RestoreRunnerPriority();
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Teardown_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqExit_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqExit_Teardown( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Action( RtemsTaskReqExit_Context *ctx )
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
ctx->delete_worker_expected = false;
|
||||
ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
|
||||
ctx->delete_worker_expected = true;
|
||||
|
||||
StartTask( ctx->worker_id, Worker, ctx );
|
||||
|
||||
/* Let the worker catch signals and set the thread life protection state */
|
||||
Yield();
|
||||
|
||||
sc = rtems_signal_send( ctx->worker_id, RTEMS_SIGNAL_0 );
|
||||
T_rsc_success( sc );
|
||||
|
||||
if ( ctx->restarting ) {
|
||||
sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
|
||||
T_rsc_success( sc );
|
||||
}
|
||||
|
||||
if ( ctx->terminating ) {
|
||||
sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx );
|
||||
T_rsc_success( sc );
|
||||
} else {
|
||||
Yield();
|
||||
}
|
||||
|
||||
if ( !ctx->dispatch_disabled ) {
|
||||
T_scheduler_log *log;
|
||||
|
||||
log = T_scheduler_record( NULL );
|
||||
T_eq_ptr( &log->header, &ctx->scheduler_log.header );
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_Cleanup( RtemsTaskReqExit_Context *ctx )
|
||||
{
|
||||
if ( ctx->dispatch_disabled ) {
|
||||
DeleteTask( ctx->worker_id );
|
||||
}
|
||||
}
|
||||
|
||||
static const RtemsTaskReqExit_Entry
|
||||
RtemsTaskReqExit_Entries[] = {
|
||||
{ 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Nop,
|
||||
RtemsTaskReqExit_Post_DeleteExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_RestartExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_TerminateExtensions_Yes,
|
||||
RtemsTaskReqExit_Post_Block_Yes, RtemsTaskReqExit_Post_ID_Invalid,
|
||||
RtemsTaskReqExit_Post_Delete_NextAllocate },
|
||||
{ 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Yes,
|
||||
RtemsTaskReqExit_Post_DeleteExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_RestartExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_TerminateExtensions_Nop,
|
||||
RtemsTaskReqExit_Post_Block_Nop, RtemsTaskReqExit_Post_ID_Valid,
|
||||
RtemsTaskReqExit_Post_Delete_Nop }
|
||||
};
|
||||
|
||||
static const uint8_t
|
||||
RtemsTaskReqExit_Map[] = {
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
|
||||
};
|
||||
|
||||
static size_t RtemsTaskReqExit_Scope( void *arg, char *buf, size_t n )
|
||||
{
|
||||
RtemsTaskReqExit_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
|
||||
if ( ctx->Map.in_action_loop ) {
|
||||
return T_get_scope( RtemsTaskReqExit_PreDesc, buf, n, ctx->Map.pcs );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static T_fixture RtemsTaskReqExit_Fixture = {
|
||||
.setup = RtemsTaskReqExit_Setup_Wrap,
|
||||
.stop = NULL,
|
||||
.teardown = RtemsTaskReqExit_Teardown_Wrap,
|
||||
.scope = RtemsTaskReqExit_Scope,
|
||||
.initial_context = &RtemsTaskReqExit_Instance
|
||||
};
|
||||
|
||||
static inline RtemsTaskReqExit_Entry RtemsTaskReqExit_PopEntry(
|
||||
RtemsTaskReqExit_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqExit_Entries[
|
||||
RtemsTaskReqExit_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqExit_TestVariant( RtemsTaskReqExit_Context *ctx )
|
||||
{
|
||||
RtemsTaskReqExit_Pre_Restarting_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqExit_Pre_Terminating_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqExit_Pre_Protected_Prepare( ctx, ctx->Map.pcs[ 2 ] );
|
||||
RtemsTaskReqExit_Pre_ThreadDispatch_Prepare( ctx, ctx->Map.pcs[ 3 ] );
|
||||
RtemsTaskReqExit_Action( ctx );
|
||||
RtemsTaskReqExit_Post_FatalError_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_FatalError
|
||||
);
|
||||
RtemsTaskReqExit_Post_DeleteExtensions_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_DeleteExtensions
|
||||
);
|
||||
RtemsTaskReqExit_Post_RestartExtensions_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_RestartExtensions
|
||||
);
|
||||
RtemsTaskReqExit_Post_TerminateExtensions_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_TerminateExtensions
|
||||
);
|
||||
RtemsTaskReqExit_Post_Block_Check( ctx, ctx->Map.entry.Post_Block );
|
||||
RtemsTaskReqExit_Post_ID_Check( ctx, ctx->Map.entry.Post_ID );
|
||||
RtemsTaskReqExit_Post_Delete_Check( ctx, ctx->Map.entry.Post_Delete );
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqExit( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE( RtemsTaskReqExit, &RtemsTaskReqExit_Fixture )
|
||||
{
|
||||
RtemsTaskReqExit_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pcs[ 0 ] = RtemsTaskReqExit_Pre_Restarting_Yes;
|
||||
ctx->Map.pcs[ 0 ] < RtemsTaskReqExit_Pre_Restarting_NA;
|
||||
++ctx->Map.pcs[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqExit_Pre_Terminating_Yes;
|
||||
ctx->Map.pcs[ 1 ] < RtemsTaskReqExit_Pre_Terminating_NA;
|
||||
++ctx->Map.pcs[ 1 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pcs[ 2 ] = RtemsTaskReqExit_Pre_Protected_Yes;
|
||||
ctx->Map.pcs[ 2 ] < RtemsTaskReqExit_Pre_Protected_NA;
|
||||
++ctx->Map.pcs[ 2 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pcs[ 3 ] = RtemsTaskReqExit_Pre_ThreadDispatch_Enabled;
|
||||
ctx->Map.pcs[ 3 ] < RtemsTaskReqExit_Pre_ThreadDispatch_NA;
|
||||
++ctx->Map.pcs[ 3 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqExit_PopEntry( ctx );
|
||||
RtemsTaskReqExit_TestVariant( ctx );
|
||||
RtemsTaskReqExit_Cleanup( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
520
testsuites/validation/tc-task-get-affinity.c
Normal file
520
testsuites/validation/tc-task-get-affinity.c
Normal file
@@ -0,0 +1,520 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 3 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqGetAffinity_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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
|
||||
);
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope(
|
||||
RtemsTaskReqGetAffinity_PreDesc,
|
||||
buf,
|
||||
n,
|
||||
ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqGetAffinity_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqGetAffinity_Entries[
|
||||
RtemsTaskReqGetAffinity_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqGetAffinity_TestVariant(
|
||||
RtemsTaskReqGetAffinity_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqGetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] );
|
||||
RtemsTaskReqGetAffinity_Action( ctx );
|
||||
RtemsTaskReqGetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_CPUSetObj
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqGetAffinity( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE(
|
||||
RtemsTaskReqGetAffinity,
|
||||
&RtemsTaskReqGetAffinity_Fixture
|
||||
)
|
||||
{
|
||||
RtemsTaskReqGetAffinity_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pcs[ 0 ] = RtemsTaskReqGetAffinity_Pre_Id_Invalid;
|
||||
ctx->Map.pcs[ 0 ] < RtemsTaskReqGetAffinity_Pre_Id_NA;
|
||||
++ctx->Map.pcs[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid;
|
||||
ctx->Map.pcs[ 1 ] < RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA;
|
||||
++ctx->Map.pcs[ 1 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pcs[ 2 ] = RtemsTaskReqGetAffinity_Pre_CPUSet_Valid;
|
||||
ctx->Map.pcs[ 2 ] < RtemsTaskReqGetAffinity_Pre_CPUSet_NA;
|
||||
++ctx->Map.pcs[ 2 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqGetAffinity_PopEntry( ctx );
|
||||
RtemsTaskReqGetAffinity_Prepare( ctx );
|
||||
RtemsTaskReqGetAffinity_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
620
testsuites/validation/tc-task-get-priority.c
Normal file
620
testsuites/validation/tc-task-get-priority.c
Normal file
@@ -0,0 +1,620 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 4 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 4 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqGetPriority_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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->Map.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
|
||||
);
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope(
|
||||
RtemsTaskReqGetPriority_PreDesc,
|
||||
buf,
|
||||
n,
|
||||
ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqGetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqGetPriority_Entries[
|
||||
RtemsTaskReqGetPriority_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqGetPriority_SetPreConditionStates(
|
||||
RtemsTaskReqGetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_Scheduler_NA ) {
|
||||
ctx->Map.pcs[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
|
||||
}
|
||||
|
||||
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqGetPriority_TestVariant(
|
||||
RtemsTaskReqGetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqGetPriority_Pre_TaskId_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqGetPriority_Pre_SchedulerId_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqGetPriority_Pre_Scheduler_Prepare( ctx, ctx->Map.pcs[ 2 ] );
|
||||
RtemsTaskReqGetPriority_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 3 ] );
|
||||
RtemsTaskReqGetPriority_Action( ctx );
|
||||
RtemsTaskReqGetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
RtemsTaskReqGetPriority_Post_PriorityObj_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_PriorityObj
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqGetPriority( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE(
|
||||
RtemsTaskReqGetPriority,
|
||||
&RtemsTaskReqGetPriority_Fixture
|
||||
)
|
||||
{
|
||||
RtemsTaskReqGetPriority_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqGetPriority_Pre_TaskId_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqGetPriority_Pre_TaskId_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqGetPriority_Pre_SchedulerId_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_Eligible;
|
||||
ctx->Map.pci[ 2 ] < RtemsTaskReqGetPriority_Pre_Scheduler_NA;
|
||||
++ctx->Map.pci[ 2 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 3 ] = RtemsTaskReqGetPriority_Pre_Priority_Valid;
|
||||
ctx->Map.pci[ 3 ] < RtemsTaskReqGetPriority_Pre_Priority_NA;
|
||||
++ctx->Map.pci[ 3 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqGetPriority_PopEntry( ctx );
|
||||
|
||||
if ( ctx->Map.entry.Skip ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RtemsTaskReqGetPriority_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqGetPriority_Prepare( ctx );
|
||||
RtemsTaskReqGetPriority_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
420
testsuites/validation/tc-task-get-scheduler.c
Normal file
420
testsuites/validation/tc-task-get-scheduler.c
Normal file
@@ -0,0 +1,420 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqGetScheduler_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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 );
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope(
|
||||
RtemsTaskReqGetScheduler_PreDesc,
|
||||
buf,
|
||||
n,
|
||||
ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqGetScheduler_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqGetScheduler_Entries[
|
||||
RtemsTaskReqGetScheduler_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqGetScheduler_TestVariant(
|
||||
RtemsTaskReqGetScheduler_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqGetScheduler_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqGetScheduler_Pre_SchedulerID_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqGetScheduler_Action( ctx );
|
||||
RtemsTaskReqGetScheduler_Post_Status_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_Status
|
||||
);
|
||||
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_SchedulerIDObj
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqGetScheduler( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE(
|
||||
RtemsTaskReqGetScheduler,
|
||||
&RtemsTaskReqGetScheduler_Fixture
|
||||
)
|
||||
{
|
||||
RtemsTaskReqGetScheduler_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pcs[ 0 ] = RtemsTaskReqGetScheduler_Pre_Id_Invalid;
|
||||
ctx->Map.pcs[ 0 ] < RtemsTaskReqGetScheduler_Pre_Id_NA;
|
||||
++ctx->Map.pcs[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid;
|
||||
ctx->Map.pcs[ 1 ] < RtemsTaskReqGetScheduler_Pre_SchedulerID_NA;
|
||||
++ctx->Map.pcs[ 1 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqGetScheduler_PopEntry( ctx );
|
||||
RtemsTaskReqGetScheduler_Prepare( ctx );
|
||||
RtemsTaskReqGetScheduler_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
359
testsuites/validation/tc-task-ident.c
Normal file
359
testsuites/validation/tc-task-ident.c
Normal file
@@ -0,0 +1,359 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestCaseRtemsTaskReqIdent
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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 "tr-object-ident.h"
|
||||
#include "ts-config.h"
|
||||
|
||||
#include <rtems/test.h>
|
||||
|
||||
/**
|
||||
* @defgroup RTEMSTestCaseRtemsTaskReqIdent spec:/rtems/task/req/ident
|
||||
*
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqIdent_Pre_Name_WhoAmI,
|
||||
RtemsTaskReqIdent_Pre_Name_NotWhoAmI,
|
||||
RtemsTaskReqIdent_Pre_Name_NA
|
||||
} RtemsTaskReqIdent_Pre_Name;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqIdent_Post_Status_OkAndWhoAmI,
|
||||
RtemsTaskReqIdent_Post_Status_Skip,
|
||||
RtemsTaskReqIdent_Post_Status_NA
|
||||
} RtemsTaskReqIdent_Post_Status;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Skip : 1;
|
||||
uint8_t Pre_Name_NA : 1;
|
||||
uint8_t Post_Status : 2;
|
||||
} RtemsTaskReqIdent_Entry;
|
||||
|
||||
/**
|
||||
* @brief Test context for spec:/rtems/task/req/ident test case.
|
||||
*/
|
||||
typedef struct {
|
||||
rtems_status_code status;
|
||||
|
||||
rtems_id *id;
|
||||
|
||||
rtems_id id_value;
|
||||
|
||||
rtems_id id_local_object;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 1 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqIdent_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} RtemsTaskReqIdent_Context;
|
||||
|
||||
static RtemsTaskReqIdent_Context
|
||||
RtemsTaskReqIdent_Instance;
|
||||
|
||||
static const char * const RtemsTaskReqIdent_PreDesc_Name[] = {
|
||||
"WhoAmI",
|
||||
"NotWhoAmI",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const * const RtemsTaskReqIdent_PreDesc[] = {
|
||||
RtemsTaskReqIdent_PreDesc_Name,
|
||||
NULL
|
||||
};
|
||||
|
||||
static rtems_status_code ClassicTaskIdentAction(
|
||||
rtems_name name,
|
||||
uint32_t node,
|
||||
rtems_id *id
|
||||
)
|
||||
{
|
||||
return rtems_task_ident( name, node, id );
|
||||
}
|
||||
|
||||
#define TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
|
||||
|
||||
#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT )
|
||||
|
||||
RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT )
|
||||
static char ClassicTaskIdentStorage[
|
||||
RTEMS_TASK_STORAGE_SIZE(
|
||||
MAX_TLS_SIZE + TEST_MINIMUM_STACK_SIZE,
|
||||
TASK_ATTRIBUTES
|
||||
)
|
||||
];
|
||||
|
||||
static const rtems_task_config ClassicTaskIdentConfig = {
|
||||
.name = ClassicObjectIdentName,
|
||||
.initial_priority = 1,
|
||||
.storage_area = ClassicTaskIdentStorage,
|
||||
.storage_size = sizeof( ClassicTaskIdentStorage ),
|
||||
.maximum_thread_local_storage_size = MAX_TLS_SIZE,
|
||||
.initial_modes = RTEMS_DEFAULT_MODES,
|
||||
.attributes = TASK_ATTRIBUTES
|
||||
};
|
||||
|
||||
static void RtemsTaskReqIdent_Pre_Name_Prepare(
|
||||
RtemsTaskReqIdent_Context *ctx,
|
||||
RtemsTaskReqIdent_Pre_Name state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqIdent_Pre_Name_WhoAmI: {
|
||||
/*
|
||||
* While the ``name`` parameter is equal to RTEMS_WHO_AM_I, while ``id``
|
||||
* parameter is not equal to NULL.
|
||||
*/
|
||||
ctx->id_value = 0xffffffff;
|
||||
ctx->id = &ctx->id_value;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqIdent_Pre_Name_NotWhoAmI: {
|
||||
/*
|
||||
* While the ``name`` is not equal to RTEMS_WHO_AM_I or ``id`` parameter
|
||||
* is equal to NULL, the behaviour of rtems_task_ident() shall be
|
||||
* specified by /rtems/req/ident.
|
||||
*/
|
||||
ctx->id = NULL;
|
||||
/* Preparation performed by RtemsReqIdent_Run() */
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqIdent_Pre_Name_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIdent_Post_Status_Check(
|
||||
RtemsTaskReqIdent_Context *ctx,
|
||||
RtemsTaskReqIdent_Post_Status state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqIdent_Post_Status_OkAndWhoAmI: {
|
||||
/*
|
||||
* The return status of rtems_task_ident() shall be RTEMS_SUCCESSFUL.
|
||||
* The value of the object identifier referenced by the ``name``
|
||||
* parameter shall be the identifier of the executing thread.
|
||||
*/
|
||||
T_rsc( ctx->status, RTEMS_SUCCESSFUL );
|
||||
T_eq_ptr( ctx->id, &ctx->id_value );
|
||||
T_eq_u32( ctx->id_value, rtems_task_self() );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqIdent_Post_Status_Skip: {
|
||||
/*
|
||||
* There is no status to validate.
|
||||
*/
|
||||
/* Checks performed by RtemsReqIdent_Run() */
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqIdent_Post_Status_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIdent_Setup( RtemsTaskReqIdent_Context *ctx )
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_task_construct(
|
||||
&ClassicTaskIdentConfig,
|
||||
&ctx->id_local_object
|
||||
);
|
||||
T_assert_rsc_success( sc );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIdent_Setup_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqIdent_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqIdent_Setup( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIdent_Teardown( RtemsTaskReqIdent_Context *ctx )
|
||||
{
|
||||
if ( ctx->id_local_object != 0 ) {
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_task_delete( ctx->id_local_object );
|
||||
T_rsc_success( sc );
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIdent_Teardown_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqIdent_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqIdent_Teardown( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIdent_Action( RtemsTaskReqIdent_Context *ctx )
|
||||
{
|
||||
if ( ctx->id != NULL ) {
|
||||
ctx->status = rtems_task_ident( RTEMS_SELF, 0xdeadbeef, ctx->id );
|
||||
} else {
|
||||
RtemsReqIdent_Run(
|
||||
ctx->id_local_object,
|
||||
ClassicTaskIdentAction
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static const RtemsTaskReqIdent_Entry
|
||||
RtemsTaskReqIdent_Entries[] = {
|
||||
{ 0, 0, RtemsTaskReqIdent_Post_Status_OkAndWhoAmI },
|
||||
{ 0, 0, RtemsTaskReqIdent_Post_Status_Skip }
|
||||
};
|
||||
|
||||
static const uint8_t
|
||||
RtemsTaskReqIdent_Map[] = {
|
||||
0, 1
|
||||
};
|
||||
|
||||
static size_t RtemsTaskReqIdent_Scope( void *arg, char *buf, size_t n )
|
||||
{
|
||||
RtemsTaskReqIdent_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
|
||||
if ( ctx->Map.in_action_loop ) {
|
||||
return T_get_scope( RtemsTaskReqIdent_PreDesc, buf, n, ctx->Map.pcs );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static T_fixture RtemsTaskReqIdent_Fixture = {
|
||||
.setup = RtemsTaskReqIdent_Setup_Wrap,
|
||||
.stop = NULL,
|
||||
.teardown = RtemsTaskReqIdent_Teardown_Wrap,
|
||||
.scope = RtemsTaskReqIdent_Scope,
|
||||
.initial_context = &RtemsTaskReqIdent_Instance
|
||||
};
|
||||
|
||||
static inline RtemsTaskReqIdent_Entry RtemsTaskReqIdent_PopEntry(
|
||||
RtemsTaskReqIdent_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqIdent_Entries[
|
||||
RtemsTaskReqIdent_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIdent_TestVariant( RtemsTaskReqIdent_Context *ctx )
|
||||
{
|
||||
RtemsTaskReqIdent_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqIdent_Action( ctx );
|
||||
RtemsTaskReqIdent_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqIdent( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE( RtemsTaskReqIdent, &RtemsTaskReqIdent_Fixture )
|
||||
{
|
||||
RtemsTaskReqIdent_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pcs[ 0 ] = RtemsTaskReqIdent_Pre_Name_WhoAmI;
|
||||
ctx->Map.pcs[ 0 ] < RtemsTaskReqIdent_Pre_Name_NA;
|
||||
++ctx->Map.pcs[ 0 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqIdent_PopEntry( ctx );
|
||||
RtemsTaskReqIdent_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
430
testsuites/validation/tc-task-is-suspended.c
Normal file
430
testsuites/validation/tc-task-is-suspended.c
Normal file
@@ -0,0 +1,430 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqIsSuspended_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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->Map.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->Map.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 );
|
||||
}
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope(
|
||||
RtemsTaskReqIsSuspended_PreDesc,
|
||||
buf,
|
||||
n,
|
||||
ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqIsSuspended_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqIsSuspended_Entries[
|
||||
RtemsTaskReqIsSuspended_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIsSuspended_SetPreConditionStates(
|
||||
RtemsTaskReqIsSuspended_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_Suspended_NA ) {
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqIsSuspended_TestVariant(
|
||||
RtemsTaskReqIsSuspended_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqIsSuspended_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqIsSuspended_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqIsSuspended_Action( ctx );
|
||||
RtemsTaskReqIsSuspended_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqIsSuspended( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE(
|
||||
RtemsTaskReqIsSuspended,
|
||||
&RtemsTaskReqIsSuspended_Fixture
|
||||
)
|
||||
{
|
||||
RtemsTaskReqIsSuspended_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqIsSuspended_Pre_Id_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqIsSuspended_Pre_Id_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_Yes;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqIsSuspended_Pre_Suspended_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqIsSuspended_PopEntry( ctx );
|
||||
RtemsTaskReqIsSuspended_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqIsSuspended_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
2019
testsuites/validation/tc-task-mode.c
Normal file
2019
testsuites/validation/tc-task-mode.c
Normal file
File diff suppressed because it is too large
Load Diff
1066
testsuites/validation/tc-task-performance.c
Normal file
1066
testsuites/validation/tc-task-performance.c
Normal file
File diff suppressed because it is too large
Load Diff
2760
testsuites/validation/tc-task-restart.c
Normal file
2760
testsuites/validation/tc-task-restart.c
Normal file
File diff suppressed because it is too large
Load Diff
411
testsuites/validation/tc-task-resume.c
Normal file
411
testsuites/validation/tc-task-resume.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqResume_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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->Map.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->Map.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 );
|
||||
}
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope( RtemsTaskReqResume_PreDesc, buf, n, ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqResume_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqResume_Entries[
|
||||
RtemsTaskReqResume_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqResume_SetPreConditionStates(
|
||||
RtemsTaskReqResume_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_Suspended_NA ) {
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqResume_Pre_Suspended_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqResume_TestVariant( RtemsTaskReqResume_Context *ctx )
|
||||
{
|
||||
RtemsTaskReqResume_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqResume_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqResume_Action( ctx );
|
||||
RtemsTaskReqResume_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqResume( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE( RtemsTaskReqResume, &RtemsTaskReqResume_Fixture )
|
||||
{
|
||||
RtemsTaskReqResume_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqResume_Pre_Id_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqResume_Pre_Id_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqResume_Pre_Suspended_Yes;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqResume_Pre_Suspended_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqResume_PopEntry( ctx );
|
||||
RtemsTaskReqResume_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqResume_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
684
testsuites/validation/tc-task-set-affinity.c
Normal file
684
testsuites/validation/tc-task-set-affinity.c
Normal file
@@ -0,0 +1,684 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetAffinity_Pre_Id_Invalid,
|
||||
RtemsTaskReqSetAffinity_Pre_Id_Task,
|
||||
RtemsTaskReqSetAffinity_Pre_Id_NA
|
||||
} RtemsTaskReqSetAffinity_Pre_Id;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA
|
||||
} RtemsTaskReqSetAffinity_Pre_CPUSetSize;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA
|
||||
} RtemsTaskReqSetAffinity_Pre_CPUSetOnline;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA
|
||||
} RtemsTaskReqSetAffinity_Pre_CPUSetHuge;
|
||||
|
||||
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_Set,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_NA
|
||||
} RtemsTaskReqSetAffinity_Post_SetAffinity;
|
||||
|
||||
typedef struct {
|
||||
uint16_t Skip : 1;
|
||||
uint16_t Pre_Id_NA : 1;
|
||||
uint16_t Pre_CPUSetSize_NA : 1;
|
||||
uint16_t Pre_CPUSetOnline_NA : 1;
|
||||
uint16_t Pre_CPUSetHuge_NA : 1;
|
||||
uint16_t Pre_CPUSet_NA : 1;
|
||||
uint16_t Post_Status : 3;
|
||||
uint16_t Post_SetAffinity : 2;
|
||||
} RtemsTaskReqSetAffinity_Entry;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 5 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 5 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqSetAffinity_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} RtemsTaskReqSetAffinity_Context;
|
||||
|
||||
static RtemsTaskReqSetAffinity_Context
|
||||
RtemsTaskReqSetAffinity_Instance;
|
||||
|
||||
static const char * const RtemsTaskReqSetAffinity_PreDesc_Id[] = {
|
||||
"Invalid",
|
||||
"Task",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetSize[] = {
|
||||
"Askew",
|
||||
"Normal",
|
||||
"Huge",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline[] = {
|
||||
"Supported",
|
||||
"Unsupported",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge[] = {
|
||||
"NotZero",
|
||||
"Zero",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSet[] = {
|
||||
"Valid",
|
||||
"Null",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const * const RtemsTaskReqSetAffinity_PreDesc[] = {
|
||||
RtemsTaskReqSetAffinity_PreDesc_Id,
|
||||
RtemsTaskReqSetAffinity_PreDesc_CPUSetSize,
|
||||
RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline,
|
||||
RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge,
|
||||
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_CPUSetSize_Prepare(
|
||||
RtemsTaskReqSetAffinity_Context *ctx,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetSize state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew: {
|
||||
/*
|
||||
* While the ``cpusetsize`` parameter is not an integral multiple of the
|
||||
* size of long.
|
||||
*/
|
||||
ctx->cpusetsize = SIZE_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal: {
|
||||
/*
|
||||
* While the ``cpusetsize`` parameter is an integral multiple of the size
|
||||
* of long, while the ``cpusetsize`` parameter is less than or equal to
|
||||
* the maximum processor set size storable in the system.
|
||||
*/
|
||||
ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge: {
|
||||
/*
|
||||
* While the ``cpusetsize`` parameter is an integral multiple of the size
|
||||
* of long, while the ``cpusetsize`` parameter is greater than the
|
||||
* maximum processor set size storable in the system.
|
||||
*/
|
||||
ctx->cpusetsize = sizeof( ctx->cpuset_obj );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare(
|
||||
RtemsTaskReqSetAffinity_Context *ctx,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetOnline state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported: {
|
||||
/*
|
||||
* While the intersection of the processor set specified by the
|
||||
* ``cpusetsize`` and ``cpuset`` parameters and the set of online
|
||||
* processors represents 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.
|
||||
*/
|
||||
/* Already prepared */
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported: {
|
||||
/*
|
||||
* While the intersection of the processor set specified by the
|
||||
* ``cpusetsize`` and ``cpuset`` parameters and the set of online
|
||||
* processors represents 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.
|
||||
*/
|
||||
CPU_CLR( 0, &ctx->cpuset_obj[ 0 ] );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare(
|
||||
RtemsTaskReqSetAffinity_Context *ctx,
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetHuge state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero: {
|
||||
/*
|
||||
* While the processor set specified by the ``cpusetsize`` and ``cpuset``
|
||||
* parameters contains at least one processor which is not storable in a
|
||||
* processor set supported by the system.
|
||||
*/
|
||||
/* Already prepared */
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero: {
|
||||
/*
|
||||
* While the processor set specified by the ``cpusetsize`` and ``cpuset``
|
||||
* parameters contains no processor which is not storable in a processor
|
||||
* set supported by the system.
|
||||
*/
|
||||
CPU_ZERO( &ctx->cpuset_obj[ 1 ] );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_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_Set: {
|
||||
/*
|
||||
* 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 );
|
||||
}
|
||||
|
||||
static const RtemsTaskReqSetAffinity_Entry
|
||||
RtemsTaskReqSetAffinity_Entries[] = {
|
||||
{ 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvAddr,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
|
||||
{ 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
|
||||
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
|
||||
{ 0, 0, 0, 1, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
|
||||
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
|
||||
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
|
||||
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop }
|
||||
};
|
||||
|
||||
static const uint8_t
|
||||
RtemsTaskReqSetAffinity_Map[] = {
|
||||
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0,
|
||||
2, 0, 2, 0, 2, 0, 4, 0, 4, 0, 2, 0, 2, 0, 5, 0, 5, 0, 6, 0, 6, 0
|
||||
};
|
||||
|
||||
static size_t RtemsTaskReqSetAffinity_Scope( void *arg, char *buf, size_t n )
|
||||
{
|
||||
RtemsTaskReqSetAffinity_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
|
||||
if ( ctx->Map.in_action_loop ) {
|
||||
return T_get_scope(
|
||||
RtemsTaskReqSetAffinity_PreDesc,
|
||||
buf,
|
||||
n,
|
||||
ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqSetAffinity_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqSetAffinity_Entries[
|
||||
RtemsTaskReqSetAffinity_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetAffinity_SetPreConditionStates(
|
||||
RtemsTaskReqSetAffinity_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_CPUSetOnline_NA ) {
|
||||
ctx->Map.pcs[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
|
||||
}
|
||||
|
||||
if ( ctx->Map.entry.Pre_CPUSetHuge_NA ) {
|
||||
ctx->Map.pcs[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
|
||||
}
|
||||
|
||||
ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetAffinity_TestVariant(
|
||||
RtemsTaskReqSetAffinity_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqSetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare( ctx, ctx->Map.pcs[ 2 ] );
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare( ctx, ctx->Map.pcs[ 3 ] );
|
||||
RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 4 ] );
|
||||
RtemsTaskReqSetAffinity_Action( ctx );
|
||||
RtemsTaskReqSetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_SetAffinity
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqSetAffinity( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE(
|
||||
RtemsTaskReqSetAffinity,
|
||||
&RtemsTaskReqSetAffinity_Fixture
|
||||
)
|
||||
{
|
||||
RtemsTaskReqSetAffinity_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqSetAffinity_Pre_Id_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqSetAffinity_Pre_Id_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported;
|
||||
ctx->Map.pci[ 2 ] < RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
|
||||
++ctx->Map.pci[ 2 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero;
|
||||
ctx->Map.pci[ 3 ] < RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
|
||||
++ctx->Map.pci[ 3 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 4 ] = RtemsTaskReqSetAffinity_Pre_CPUSet_Valid;
|
||||
ctx->Map.pci[ 4 ] < RtemsTaskReqSetAffinity_Pre_CPUSet_NA;
|
||||
++ctx->Map.pci[ 4 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqSetAffinity_PopEntry( ctx );
|
||||
RtemsTaskReqSetAffinity_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqSetAffinity_Prepare( ctx );
|
||||
RtemsTaskReqSetAffinity_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
816
testsuites/validation/tc-task-set-priority.c
Normal file
816
testsuites/validation/tc-task-set-priority.c
Normal file
@@ -0,0 +1,816 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetPriority_Pre_Id_Invalid,
|
||||
RtemsTaskReqSetPriority_Pre_Id_Task,
|
||||
RtemsTaskReqSetPriority_Pre_Id_NA
|
||||
} RtemsTaskReqSetPriority_Pre_Id;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetPriority_Pre_State_Dormant,
|
||||
RtemsTaskReqSetPriority_Pre_State_Ready,
|
||||
RtemsTaskReqSetPriority_Pre_State_Scheduled,
|
||||
RtemsTaskReqSetPriority_Pre_State_Blocked,
|
||||
RtemsTaskReqSetPriority_Pre_State_NA
|
||||
} RtemsTaskReqSetPriority_Pre_State;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetPriority_Pre_NewPriority_Current,
|
||||
RtemsTaskReqSetPriority_Pre_NewPriority_Other,
|
||||
RtemsTaskReqSetPriority_Pre_NewPriority_NA
|
||||
} RtemsTaskReqSetPriority_Pre_NewPriority;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqSetPriority_Pre_TaskPriority_High,
|
||||
RtemsTaskReqSetPriority_Pre_TaskPriority_Equal,
|
||||
RtemsTaskReqSetPriority_Pre_TaskPriority_Low,
|
||||
RtemsTaskReqSetPriority_Pre_TaskPriority_Invalid,
|
||||
RtemsTaskReqSetPriority_Pre_TaskPriority_NA
|
||||
} RtemsTaskReqSetPriority_Pre_TaskPriority;
|
||||
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
uint16_t Skip : 1;
|
||||
uint16_t Pre_Id_NA : 1;
|
||||
uint16_t Pre_State_NA : 1;
|
||||
uint16_t Pre_NewPriority_NA : 1;
|
||||
uint16_t Pre_TaskPriority_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;
|
||||
|
||||
/**
|
||||
* @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 If this member is true, then the task shall be started.
|
||||
*/
|
||||
bool started;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the task shall be blocked.
|
||||
*/
|
||||
bool blocked;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 5 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 5 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqSetPriority_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} RtemsTaskReqSetPriority_Context;
|
||||
|
||||
static RtemsTaskReqSetPriority_Context
|
||||
RtemsTaskReqSetPriority_Instance;
|
||||
|
||||
static const char * const RtemsTaskReqSetPriority_PreDesc_Id[] = {
|
||||
"Invalid",
|
||||
"Task",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetPriority_PreDesc_State[] = {
|
||||
"Dormant",
|
||||
"Ready",
|
||||
"Scheduled",
|
||||
"Blocked",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetPriority_PreDesc_NewPriority[] = {
|
||||
"Current",
|
||||
"Other",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetPriority_PreDesc_TaskPriority[] = {
|
||||
"High",
|
||||
"Equal",
|
||||
"Low",
|
||||
"Invalid",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqSetPriority_PreDesc_OldPriority[] = {
|
||||
"Valid",
|
||||
"Null",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const * const RtemsTaskReqSetPriority_PreDesc[] = {
|
||||
RtemsTaskReqSetPriority_PreDesc_Id,
|
||||
RtemsTaskReqSetPriority_PreDesc_State,
|
||||
RtemsTaskReqSetPriority_PreDesc_NewPriority,
|
||||
RtemsTaskReqSetPriority_PreDesc_TaskPriority,
|
||||
RtemsTaskReqSetPriority_PreDesc_OldPriority,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void Worker( rtems_task_argument arg )
|
||||
{
|
||||
(void) ReceiveAnyEvents();
|
||||
(void) ReceiveAnyEvents();
|
||||
}
|
||||
|
||||
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_State_Prepare(
|
||||
RtemsTaskReqSetPriority_Context *ctx,
|
||||
RtemsTaskReqSetPriority_Pre_State state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqSetPriority_Pre_State_Dormant: {
|
||||
/*
|
||||
* While the task specified by the ``id`` parameter is dormant.
|
||||
*/
|
||||
ctx->started = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_State_Ready: {
|
||||
/*
|
||||
* While the task specified by the ``id`` parameter is ready.
|
||||
*/
|
||||
ctx->started = true;
|
||||
ctx->blocked = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_State_Scheduled: {
|
||||
/*
|
||||
* While the task specified by the ``id`` parameter is scheduled.
|
||||
*/
|
||||
ctx->started = false;
|
||||
ctx->id = rtems_task_self();
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_State_Blocked: {
|
||||
/*
|
||||
* While the task specified by the ``id`` parameter is blocked.
|
||||
*/
|
||||
ctx->started = true;
|
||||
ctx->blocked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_State_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_Other: {
|
||||
/*
|
||||
* While the value of the ``new_priority`` parameter is not equal to
|
||||
* RTEMS_CURRENT_PRIORITY.
|
||||
*/
|
||||
ctx->new_priority = PRIO_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_NewPriority_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_Pre_TaskPriority_Prepare(
|
||||
RtemsTaskReqSetPriority_Context *ctx,
|
||||
RtemsTaskReqSetPriority_Pre_TaskPriority state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqSetPriority_Pre_TaskPriority_High: {
|
||||
/*
|
||||
* 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 when the new priority is set, while the value of
|
||||
* the ``new_priority`` parameter is higher than the task priority with
|
||||
* respect to the home scheduler of the task specified by the ``id``
|
||||
* parameter at time when the scheduler evaluates the new priority.
|
||||
*/
|
||||
ctx->new_priority = PRIO_HIGH;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_TaskPriority_Equal: {
|
||||
/*
|
||||
* 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 when the new priority is set, while the value of
|
||||
* the ``new_priority`` parameter is equal to the task priority with
|
||||
* respect to the home scheduler of the task specified by the ``id``
|
||||
* parameter at time when the scheduler evaluates the new priority.
|
||||
*/
|
||||
ctx->new_priority = PRIO_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_TaskPriority_Low: {
|
||||
/*
|
||||
* 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 when the new priority is set, while the value of
|
||||
* the ``new_priority`` parameter is lower than the task priority with
|
||||
* respect to the home scheduler of the task specified by the ``id``
|
||||
* parameter at time when the scheduler evaluates the new priority.
|
||||
*/
|
||||
ctx->new_priority = PRIO_LOW;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_TaskPriority_Invalid: {
|
||||
/*
|
||||
* 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 when the new priority is evaluated.
|
||||
*/
|
||||
ctx->new_priority = PRIO_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqSetPriority_Pre_TaskPriority_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->id ), ctx->new_priority );
|
||||
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_NORMAL );
|
||||
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_NORMAL );
|
||||
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_Setup(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
SetSelfPriority( PRIO_ULTRA_HIGH );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_Setup_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqSetPriority_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqSetPriority_Setup( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_Teardown(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
RestoreRunnerPriority();
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_Teardown_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqSetPriority_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqSetPriority_Teardown( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_Prepare(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->old_priority_obj = PRIO_INVALID;
|
||||
ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
|
||||
ctx->started = false;
|
||||
ctx->blocked = false;
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_Action(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
if ( ctx->started ) {
|
||||
SetSelfPriority( PRIO_ULTRA_HIGH );
|
||||
StartTask( ctx->worker_id, Worker, NULL );
|
||||
|
||||
if ( ctx->blocked ) {
|
||||
SetSelfPriority( PRIO_ULTRA_LOW );
|
||||
SetSelfPriority( PRIO_ULTRA_HIGH );
|
||||
}
|
||||
} else {
|
||||
SetSelfPriority( PRIO_NORMAL );
|
||||
}
|
||||
|
||||
ctx->status = rtems_task_set_priority(
|
||||
ctx->id,
|
||||
ctx->new_priority,
|
||||
ctx->old_priority
|
||||
);
|
||||
|
||||
if ( ctx->started ) {
|
||||
SendEvents( ctx->worker_id, RTEMS_EVENT_0 );
|
||||
SetSelfPriority( PRIO_ULTRA_LOW );
|
||||
SetSelfPriority( PRIO_ULTRA_HIGH );
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_Cleanup(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
DeleteTask( ctx->worker_id );
|
||||
}
|
||||
|
||||
static const RtemsTaskReqSetPriority_Entry
|
||||
RtemsTaskReqSetPriority_Entries[] = {
|
||||
{ 0, 0, 1, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvId,
|
||||
RtemsTaskReqSetPriority_Post_Priority_Nop,
|
||||
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
|
||||
{ 0, 0, 1, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
|
||||
RtemsTaskReqSetPriority_Post_Priority_Nop,
|
||||
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
|
||||
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
|
||||
RtemsTaskReqSetPriority_Post_Priority_Nop,
|
||||
RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
|
||||
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
|
||||
RtemsTaskReqSetPriority_Post_Priority_Nop,
|
||||
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
|
||||
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
|
||||
RtemsTaskReqSetPriority_Post_Priority_Nop,
|
||||
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
|
||||
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
|
||||
RtemsTaskReqSetPriority_Post_Priority_Set,
|
||||
RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
|
||||
{ 0, 0, 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, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4,
|
||||
6, 4, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4, 6, 4, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
5, 4, 5, 4, 5, 4, 6, 4, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4, 6, 4
|
||||
};
|
||||
|
||||
static size_t RtemsTaskReqSetPriority_Scope( void *arg, char *buf, size_t n )
|
||||
{
|
||||
RtemsTaskReqSetPriority_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
|
||||
if ( ctx->Map.in_action_loop ) {
|
||||
return T_get_scope(
|
||||
RtemsTaskReqSetPriority_PreDesc,
|
||||
buf,
|
||||
n,
|
||||
ctx->Map.pcs
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static T_fixture RtemsTaskReqSetPriority_Fixture = {
|
||||
.setup = RtemsTaskReqSetPriority_Setup_Wrap,
|
||||
.stop = NULL,
|
||||
.teardown = RtemsTaskReqSetPriority_Teardown_Wrap,
|
||||
.scope = RtemsTaskReqSetPriority_Scope,
|
||||
.initial_context = &RtemsTaskReqSetPriority_Instance
|
||||
};
|
||||
|
||||
static inline RtemsTaskReqSetPriority_Entry RtemsTaskReqSetPriority_PopEntry(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqSetPriority_Entries[
|
||||
RtemsTaskReqSetPriority_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_SetPreConditionStates(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_State_NA ) {
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqSetPriority_Pre_State_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
}
|
||||
|
||||
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_TaskPriority_NA ) {
|
||||
ctx->Map.pcs[ 3 ] = RtemsTaskReqSetPriority_Pre_TaskPriority_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
|
||||
}
|
||||
|
||||
ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSetPriority_TestVariant(
|
||||
RtemsTaskReqSetPriority_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqSetPriority_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqSetPriority_Pre_State_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqSetPriority_Pre_NewPriority_Prepare( ctx, ctx->Map.pcs[ 2 ] );
|
||||
RtemsTaskReqSetPriority_Pre_TaskPriority_Prepare( ctx, ctx->Map.pcs[ 3 ] );
|
||||
RtemsTaskReqSetPriority_Pre_OldPriority_Prepare( ctx, ctx->Map.pcs[ 4 ] );
|
||||
RtemsTaskReqSetPriority_Action( ctx );
|
||||
RtemsTaskReqSetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
RtemsTaskReqSetPriority_Post_Priority_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_Priority
|
||||
);
|
||||
RtemsTaskReqSetPriority_Post_OldPriorityObj_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_OldPriorityObj
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqSetPriority( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE(
|
||||
RtemsTaskReqSetPriority,
|
||||
&RtemsTaskReqSetPriority_Fixture
|
||||
)
|
||||
{
|
||||
RtemsTaskReqSetPriority_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqSetPriority_Pre_Id_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqSetPriority_Pre_Id_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqSetPriority_Pre_State_Dormant;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqSetPriority_Pre_State_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 2 ] = RtemsTaskReqSetPriority_Pre_NewPriority_Current;
|
||||
ctx->Map.pci[ 2 ] < RtemsTaskReqSetPriority_Pre_NewPriority_NA;
|
||||
++ctx->Map.pci[ 2 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 3 ] = RtemsTaskReqSetPriority_Pre_TaskPriority_High;
|
||||
ctx->Map.pci[ 3 ] < RtemsTaskReqSetPriority_Pre_TaskPriority_NA;
|
||||
++ctx->Map.pci[ 3 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 4 ] = RtemsTaskReqSetPriority_Pre_OldPriority_Valid;
|
||||
ctx->Map.pci[ 4 ] < RtemsTaskReqSetPriority_Pre_OldPriority_NA;
|
||||
++ctx->Map.pci[ 4 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqSetPriority_PopEntry( ctx );
|
||||
RtemsTaskReqSetPriority_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqSetPriority_Prepare( ctx );
|
||||
RtemsTaskReqSetPriority_TestVariant( ctx );
|
||||
RtemsTaskReqSetPriority_Cleanup( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
1492
testsuites/validation/tc-task-set-scheduler.c
Normal file
1492
testsuites/validation/tc-task-set-scheduler.c
Normal file
File diff suppressed because it is too large
Load Diff
859
testsuites/validation/tc-task-start.c
Normal file
859
testsuites/validation/tc-task-start.c
Normal file
@@ -0,0 +1,859 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 5 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 5 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqStart_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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->Map.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->Map.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 );
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope( RtemsTaskReqStart_PreDesc, buf, n, ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqStart_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqStart_Entries[
|
||||
RtemsTaskReqStart_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqStart_SetPreConditionStates(
|
||||
RtemsTaskReqStart_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_Dormant_NA ) {
|
||||
ctx->Map.pcs[ 3 ] = RtemsTaskReqStart_Pre_Dormant_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
|
||||
}
|
||||
|
||||
if ( ctx->Map.entry.Pre_Suspended_NA ) {
|
||||
ctx->Map.pcs[ 4 ] = RtemsTaskReqStart_Pre_Suspended_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqStart_TestVariant( RtemsTaskReqStart_Context *ctx )
|
||||
{
|
||||
RtemsTaskReqStart_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqStart_Pre_EntryPoint_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqStart_Pre_Argument_Prepare( ctx, ctx->Map.pcs[ 2 ] );
|
||||
RtemsTaskReqStart_Pre_Dormant_Prepare( ctx, ctx->Map.pcs[ 3 ] );
|
||||
RtemsTaskReqStart_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 4 ] );
|
||||
RtemsTaskReqStart_Action( ctx );
|
||||
RtemsTaskReqStart_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
RtemsTaskReqStart_Post_EntryPoint_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_EntryPoint
|
||||
);
|
||||
RtemsTaskReqStart_Post_Argument_Check( ctx, ctx->Map.entry.Post_Argument );
|
||||
RtemsTaskReqStart_Post_Unblock_Check( ctx, ctx->Map.entry.Post_Unblock );
|
||||
RtemsTaskReqStart_Post_StartExtensions_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_StartExtensions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqStart( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE( RtemsTaskReqStart, &RtemsTaskReqStart_Fixture )
|
||||
{
|
||||
RtemsTaskReqStart_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqStart_Pre_Id_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqStart_Pre_Id_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqStart_Pre_EntryPoint_Valid;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqStart_Pre_EntryPoint_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 2 ] = RtemsTaskReqStart_Pre_Argument_Pointer;
|
||||
ctx->Map.pci[ 2 ] < RtemsTaskReqStart_Pre_Argument_NA;
|
||||
++ctx->Map.pci[ 2 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 3 ] = RtemsTaskReqStart_Pre_Dormant_Yes;
|
||||
ctx->Map.pci[ 3 ] < RtemsTaskReqStart_Pre_Dormant_NA;
|
||||
++ctx->Map.pci[ 3 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 4 ] = RtemsTaskReqStart_Pre_Suspended_Yes;
|
||||
ctx->Map.pci[ 4 ] < RtemsTaskReqStart_Pre_Suspended_NA;
|
||||
++ctx->Map.pci[ 4 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqStart_PopEntry( ctx );
|
||||
RtemsTaskReqStart_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqStart_Prepare( ctx );
|
||||
RtemsTaskReqStart_TestVariant( ctx );
|
||||
RtemsTaskReqStart_Cleanup( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
428
testsuites/validation/tc-task-storage-size.c
Normal file
428
testsuites/validation/tc-task-storage-size.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqStorageSize_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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->Map.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->Map.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 );
|
||||
}
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope(
|
||||
RtemsTaskReqStorageSize_PreDesc,
|
||||
buf,
|
||||
n,
|
||||
ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqStorageSize_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqStorageSize_Entries[
|
||||
RtemsTaskReqStorageSize_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqStorageSize_SetPreConditionStates(
|
||||
RtemsTaskReqStorageSize_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_Suspended_NA ) {
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqStorageSize_TestVariant(
|
||||
RtemsTaskReqStorageSize_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqStorageSize_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqStorageSize_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqStorageSize_Action( ctx );
|
||||
RtemsTaskReqStorageSize_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqStorageSize( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE(
|
||||
RtemsTaskReqStorageSize,
|
||||
&RtemsTaskReqStorageSize_Fixture
|
||||
)
|
||||
{
|
||||
RtemsTaskReqStorageSize_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqStorageSize_Pre_Id_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqStorageSize_Pre_Id_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_Yes;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqStorageSize_Pre_Suspended_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqStorageSize_PopEntry( ctx );
|
||||
RtemsTaskReqStorageSize_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqStorageSize_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
411
testsuites/validation/tc-task-suspend.c
Normal file
411
testsuites/validation/tc-task-suspend.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqSuspend_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} 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->Map.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->Map.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 );
|
||||
}
|
||||
}
|
||||
|
||||
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->Map.in_action_loop ) {
|
||||
return T_get_scope( RtemsTaskReqSuspend_PreDesc, buf, n, ctx->Map.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_PopEntry(
|
||||
RtemsTaskReqSuspend_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqSuspend_Entries[
|
||||
RtemsTaskReqSuspend_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSuspend_SetPreConditionStates(
|
||||
RtemsTaskReqSuspend_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_Suspended_NA ) {
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqSuspend_TestVariant( RtemsTaskReqSuspend_Context *ctx )
|
||||
{
|
||||
RtemsTaskReqSuspend_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqSuspend_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqSuspend_Action( ctx );
|
||||
RtemsTaskReqSuspend_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqSuspend( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE( RtemsTaskReqSuspend, &RtemsTaskReqSuspend_Fixture )
|
||||
{
|
||||
RtemsTaskReqSuspend_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqSuspend_Pre_Id_Invalid;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqSuspend_Pre_Id_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_Yes;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqSuspend_Pre_Suspended_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqSuspend_PopEntry( ctx );
|
||||
RtemsTaskReqSuspend_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqSuspend_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
574
testsuites/validation/tc-task-wake-after.c
Normal file
574
testsuites/validation/tc-task-wake-after.c
Normal file
@@ -0,0 +1,574 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestCaseRtemsTaskReqWakeAfter
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <rtems/score/threaddispatch.h>
|
||||
#include <rtems/score/timecounter.h>
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/test.h>
|
||||
|
||||
/**
|
||||
* @defgroup RTEMSTestCaseRtemsTaskReqWakeAfter spec:/rtems/task/req/wake-after
|
||||
*
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeAfter_Pre_Ticks_Yield,
|
||||
RtemsTaskReqWakeAfter_Pre_Ticks_Interval,
|
||||
RtemsTaskReqWakeAfter_Pre_Ticks_NA
|
||||
} RtemsTaskReqWakeAfter_Pre_Ticks;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeAfter_Pre_Suspended_Yes,
|
||||
RtemsTaskReqWakeAfter_Pre_Suspended_No,
|
||||
RtemsTaskReqWakeAfter_Pre_Suspended_NA
|
||||
} RtemsTaskReqWakeAfter_Pre_Suspended;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeAfter_Post_Status_Ok,
|
||||
RtemsTaskReqWakeAfter_Post_Status_NA
|
||||
} RtemsTaskReqWakeAfter_Post_Status;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeAfter_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeAfter_Post_Timer_Ticks,
|
||||
RtemsTaskReqWakeAfter_Post_Timer_NA
|
||||
} RtemsTaskReqWakeAfter_Post_Timer;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeAfter_Post_Expire_Relative,
|
||||
RtemsTaskReqWakeAfter_Post_Expire_NA
|
||||
} RtemsTaskReqWakeAfter_Post_Expire;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Block,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Yield,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Nop,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_NA
|
||||
} RtemsTaskReqWakeAfter_Post_Scheduler;
|
||||
|
||||
typedef struct {
|
||||
uint16_t Skip : 1;
|
||||
uint16_t Pre_Ticks_NA : 1;
|
||||
uint16_t Pre_Suspended_NA : 1;
|
||||
uint16_t Post_Status : 1;
|
||||
uint16_t Post_Timer : 2;
|
||||
uint16_t Post_Expire : 1;
|
||||
uint16_t Post_Scheduler : 2;
|
||||
} RtemsTaskReqWakeAfter_Entry;
|
||||
|
||||
/**
|
||||
* @brief Test context for spec:/rtems/task/req/wake-after test case.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief This member provides the scheduler operation records.
|
||||
*/
|
||||
T_scheduler_log_4 scheduler_log;;
|
||||
|
||||
/**
|
||||
* @brief This member contains the clock tick value before the
|
||||
* rtems_task_wake_after() call.
|
||||
*/
|
||||
uint64_t now;;
|
||||
|
||||
/**
|
||||
* @brief This member contains the worker task identifier.
|
||||
*/
|
||||
rtems_id worker_id;;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the worker shall be suspended during
|
||||
* the rtems_task_wake_after() call.
|
||||
*/
|
||||
bool suspended;;
|
||||
|
||||
/**
|
||||
* @brief This member contains the timer information of the worker task.
|
||||
*/
|
||||
TaskTimerInfo timer_info;;
|
||||
|
||||
/**
|
||||
* @brief This member contains the return value of the
|
||||
* rtems_task_wake_after() call.
|
||||
*/
|
||||
rtems_status_code status;
|
||||
|
||||
/**
|
||||
* @brief This member specifies the ``ticks`` parameter value.
|
||||
*/
|
||||
rtems_interval ticks;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 2 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqWakeAfter_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} RtemsTaskReqWakeAfter_Context;
|
||||
|
||||
static RtemsTaskReqWakeAfter_Context
|
||||
RtemsTaskReqWakeAfter_Instance;
|
||||
|
||||
static const char * const RtemsTaskReqWakeAfter_PreDesc_Ticks[] = {
|
||||
"Yield",
|
||||
"Interval",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqWakeAfter_PreDesc_Suspended[] = {
|
||||
"Yes",
|
||||
"No",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const * const RtemsTaskReqWakeAfter_PreDesc[] = {
|
||||
RtemsTaskReqWakeAfter_PreDesc_Ticks,
|
||||
RtemsTaskReqWakeAfter_PreDesc_Suspended,
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef RtemsTaskReqWakeAfter_Context Context;
|
||||
|
||||
static void Worker( rtems_task_argument arg )
|
||||
{
|
||||
Context *ctx;
|
||||
|
||||
ctx = (Context *) arg;
|
||||
|
||||
while ( true ) {
|
||||
T_scheduler_log *log;
|
||||
|
||||
SuspendSelf();
|
||||
|
||||
ctx->now = rtems_clock_get_ticks_since_boot();
|
||||
|
||||
if ( ctx->suspended ) {
|
||||
Per_CPU_Control *cpu_self;
|
||||
|
||||
/*
|
||||
* The rtems_task_wake_after() disables thread dispatching to carry out
|
||||
* its operations. While thread dispatching is disabled, when an
|
||||
* interrupt suspends the calling task, the suspended task executes
|
||||
* until it enables thread dispatching. We simulate this situation
|
||||
* with the code below. Where the system was built with SMP support
|
||||
* enabled, other processors may suspend an executing task in parallel.
|
||||
* This case is also simulated by the code below.
|
||||
*/
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
SuspendSelf();
|
||||
cpu_self->dispatch_necessary = false;
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
}
|
||||
|
||||
log = T_scheduler_record_4( &ctx->scheduler_log );
|
||||
T_null( log );
|
||||
|
||||
ctx->status = rtems_task_wake_after( ctx->ticks );
|
||||
|
||||
(void) T_scheduler_record( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Pre_Ticks_Prepare(
|
||||
RtemsTaskReqWakeAfter_Context *ctx,
|
||||
RtemsTaskReqWakeAfter_Pre_Ticks state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeAfter_Pre_Ticks_Yield: {
|
||||
/*
|
||||
* While the ``ticks`` parameter is equal to RTEMS_YIELD_PROCESSOR.
|
||||
*/
|
||||
ctx->ticks = RTEMS_YIELD_PROCESSOR;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Pre_Ticks_Interval: {
|
||||
/*
|
||||
* While the ``ticks`` parameter is not equal to RTEMS_YIELD_PROCESSOR.
|
||||
*/
|
||||
ctx->ticks = UINT32_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Pre_Ticks_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Pre_Suspended_Prepare(
|
||||
RtemsTaskReqWakeAfter_Context *ctx,
|
||||
RtemsTaskReqWakeAfter_Pre_Suspended state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeAfter_Pre_Suspended_Yes: {
|
||||
/*
|
||||
* While the calling task is suspended.
|
||||
*/
|
||||
ctx->suspended = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Pre_Suspended_No: {
|
||||
/*
|
||||
* While the calling task is not suspended.
|
||||
*/
|
||||
ctx->suspended = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Pre_Suspended_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Post_Status_Check(
|
||||
RtemsTaskReqWakeAfter_Context *ctx,
|
||||
RtemsTaskReqWakeAfter_Post_Status state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeAfter_Post_Status_Ok: {
|
||||
/*
|
||||
* The return status of rtems_task_wake_after() shall be
|
||||
* RTEMS_SUCCESSFUL.
|
||||
*/
|
||||
T_rsc_success( ctx->status );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Post_Status_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Post_Timer_Check(
|
||||
RtemsTaskReqWakeAfter_Context *ctx,
|
||||
RtemsTaskReqWakeAfter_Post_Timer state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeAfter_Post_Timer_Inactive: {
|
||||
/*
|
||||
* The timer of the calling task shall be inactive.
|
||||
*/
|
||||
T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Post_Timer_Ticks: {
|
||||
/*
|
||||
* The timer of the calling task shall be active using the clock tick.
|
||||
*/
|
||||
T_eq_int( ctx->timer_info.state, TASK_TIMER_TICKS );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Post_Timer_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Post_Expire_Check(
|
||||
RtemsTaskReqWakeAfter_Context *ctx,
|
||||
RtemsTaskReqWakeAfter_Post_Expire state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeAfter_Post_Expire_Relative: {
|
||||
/*
|
||||
* The timer of the calling task shall expire at the time point specified
|
||||
* by the sum of the current clock tick and the interval specified by the
|
||||
* ``ticks`` parameter.
|
||||
*/
|
||||
T_eq_u64( ctx->timer_info.expire_ticks, ctx->now + UINT32_MAX );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Post_Expire_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Post_Scheduler_Check(
|
||||
RtemsTaskReqWakeAfter_Context *ctx,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeAfter_Post_Scheduler_Block: {
|
||||
/*
|
||||
* The calling task shall be blocked by the scheduler exactly once by the
|
||||
* rtems_task_wake_after() call.
|
||||
*/
|
||||
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
|
||||
T_eq_int(
|
||||
ctx->scheduler_log.events[ 0 ].operation,
|
||||
T_SCHEDULER_BLOCK
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Post_Scheduler_Yield: {
|
||||
/*
|
||||
* The calling task shall yield by the scheduler exactly once by the
|
||||
* rtems_task_wake_after() call.
|
||||
*/
|
||||
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
|
||||
T_eq_int(
|
||||
ctx->scheduler_log.events[ 0 ].operation,
|
||||
T_SCHEDULER_YIELD
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Post_Scheduler_Nop: {
|
||||
/*
|
||||
* The calling task shall not carry out a scheduler operation through the
|
||||
* rtems_task_wake_after() call.
|
||||
*/
|
||||
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeAfter_Post_Scheduler_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Setup( RtemsTaskReqWakeAfter_Context *ctx )
|
||||
{
|
||||
SetSelfPriority( PRIO_NORMAL );
|
||||
ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
|
||||
StartTask( ctx->worker_id, Worker, ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Setup_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqWakeAfter_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqWakeAfter_Setup( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Teardown(
|
||||
RtemsTaskReqWakeAfter_Context *ctx
|
||||
)
|
||||
{
|
||||
DeleteTask( ctx->worker_id );
|
||||
RestoreRunnerPriority();
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Teardown_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqWakeAfter_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqWakeAfter_Teardown( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Prepare( RtemsTaskReqWakeAfter_Context *ctx )
|
||||
{
|
||||
ctx->status = RTEMS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_Action( RtemsTaskReqWakeAfter_Context *ctx )
|
||||
{
|
||||
ResumeTask( ctx->worker_id );
|
||||
(void) T_scheduler_record( NULL );
|
||||
GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
|
||||
|
||||
if ( ctx->suspended ) {
|
||||
ResumeTask( ctx->worker_id );
|
||||
}
|
||||
|
||||
FinalClockTick();
|
||||
}
|
||||
|
||||
static const RtemsTaskReqWakeAfter_Entry
|
||||
RtemsTaskReqWakeAfter_Entries[] = {
|
||||
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
|
||||
RtemsTaskReqWakeAfter_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeAfter_Post_Expire_NA,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Nop },
|
||||
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
|
||||
RtemsTaskReqWakeAfter_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeAfter_Post_Expire_NA,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Yield },
|
||||
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
|
||||
RtemsTaskReqWakeAfter_Post_Timer_Ticks,
|
||||
RtemsTaskReqWakeAfter_Post_Expire_Relative,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Nop },
|
||||
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
|
||||
RtemsTaskReqWakeAfter_Post_Timer_Ticks,
|
||||
RtemsTaskReqWakeAfter_Post_Expire_Relative,
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Block }
|
||||
};
|
||||
|
||||
static const uint8_t
|
||||
RtemsTaskReqWakeAfter_Map[] = {
|
||||
0, 1, 2, 3
|
||||
};
|
||||
|
||||
static size_t RtemsTaskReqWakeAfter_Scope( void *arg, char *buf, size_t n )
|
||||
{
|
||||
RtemsTaskReqWakeAfter_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
|
||||
if ( ctx->Map.in_action_loop ) {
|
||||
return T_get_scope( RtemsTaskReqWakeAfter_PreDesc, buf, n, ctx->Map.pcs );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static T_fixture RtemsTaskReqWakeAfter_Fixture = {
|
||||
.setup = RtemsTaskReqWakeAfter_Setup_Wrap,
|
||||
.stop = NULL,
|
||||
.teardown = RtemsTaskReqWakeAfter_Teardown_Wrap,
|
||||
.scope = RtemsTaskReqWakeAfter_Scope,
|
||||
.initial_context = &RtemsTaskReqWakeAfter_Instance
|
||||
};
|
||||
|
||||
static inline RtemsTaskReqWakeAfter_Entry RtemsTaskReqWakeAfter_PopEntry(
|
||||
RtemsTaskReqWakeAfter_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqWakeAfter_Entries[
|
||||
RtemsTaskReqWakeAfter_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeAfter_TestVariant(
|
||||
RtemsTaskReqWakeAfter_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqWakeAfter_Pre_Ticks_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqWakeAfter_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqWakeAfter_Action( ctx );
|
||||
RtemsTaskReqWakeAfter_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
RtemsTaskReqWakeAfter_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
|
||||
RtemsTaskReqWakeAfter_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
|
||||
RtemsTaskReqWakeAfter_Post_Scheduler_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_Scheduler
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqWakeAfter( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE( RtemsTaskReqWakeAfter, &RtemsTaskReqWakeAfter_Fixture )
|
||||
{
|
||||
RtemsTaskReqWakeAfter_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pcs[ 0 ] = RtemsTaskReqWakeAfter_Pre_Ticks_Yield;
|
||||
ctx->Map.pcs[ 0 ] < RtemsTaskReqWakeAfter_Pre_Ticks_NA;
|
||||
++ctx->Map.pcs[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pcs[ 1 ] = RtemsTaskReqWakeAfter_Pre_Suspended_Yes;
|
||||
ctx->Map.pcs[ 1 ] < RtemsTaskReqWakeAfter_Pre_Suspended_NA;
|
||||
++ctx->Map.pcs[ 1 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqWakeAfter_PopEntry( ctx );
|
||||
RtemsTaskReqWakeAfter_Prepare( ctx );
|
||||
RtemsTaskReqWakeAfter_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
665
testsuites/validation/tc-task-wake-when.c
Normal file
665
testsuites/validation/tc-task-wake-when.c
Normal file
@@ -0,0 +1,665 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestCaseRtemsTaskReqWakeWhen
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/test-scheduler.h>
|
||||
#include <rtems/score/timecounter.h>
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/test.h>
|
||||
|
||||
/**
|
||||
* @defgroup RTEMSTestCaseRtemsTaskReqWakeWhen spec:/rtems/task/req/wake-when
|
||||
*
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeWhen_Pre_TODSet_Yes,
|
||||
RtemsTaskReqWakeWhen_Pre_TODSet_No,
|
||||
RtemsTaskReqWakeWhen_Pre_TODSet_NA
|
||||
} RtemsTaskReqWakeWhen_Pre_TODSet;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeWhen_Pre_TOD_Valid,
|
||||
RtemsTaskReqWakeWhen_Pre_TOD_Null,
|
||||
RtemsTaskReqWakeWhen_Pre_TOD_NA
|
||||
} RtemsTaskReqWakeWhen_Pre_TOD;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeWhen_Pre_TODObj_Future,
|
||||
RtemsTaskReqWakeWhen_Pre_TODObj_PastOrNow,
|
||||
RtemsTaskReqWakeWhen_Pre_TODObj_Invalid,
|
||||
RtemsTaskReqWakeWhen_Pre_TODObj_NA
|
||||
} RtemsTaskReqWakeWhen_Pre_TODObj;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeWhen_Post_Status_Ok,
|
||||
RtemsTaskReqWakeWhen_Post_Status_NotDef,
|
||||
RtemsTaskReqWakeWhen_Post_Status_InvAddr,
|
||||
RtemsTaskReqWakeWhen_Post_Status_InvClock,
|
||||
RtemsTaskReqWakeWhen_Post_Status_NA
|
||||
} RtemsTaskReqWakeWhen_Post_Status;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Realtime,
|
||||
RtemsTaskReqWakeWhen_Post_Timer_NA
|
||||
} RtemsTaskReqWakeWhen_Post_Timer;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeWhen_Post_Expire_Absolute,
|
||||
RtemsTaskReqWakeWhen_Post_Expire_NA
|
||||
} RtemsTaskReqWakeWhen_Post_Expire;
|
||||
|
||||
typedef enum {
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Block,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Nop,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_NA
|
||||
} RtemsTaskReqWakeWhen_Post_Scheduler;
|
||||
|
||||
typedef struct {
|
||||
uint16_t Skip : 1;
|
||||
uint16_t Pre_TODSet_NA : 1;
|
||||
uint16_t Pre_TOD_NA : 1;
|
||||
uint16_t Pre_TODObj_NA : 1;
|
||||
uint16_t Post_Status : 3;
|
||||
uint16_t Post_Timer : 2;
|
||||
uint16_t Post_Expire : 1;
|
||||
uint16_t Post_Scheduler : 2;
|
||||
} RtemsTaskReqWakeWhen_Entry;
|
||||
|
||||
/**
|
||||
* @brief Test context for spec:/rtems/task/req/wake-when test case.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief This member provides the scheduler operation records.
|
||||
*/
|
||||
T_scheduler_log_4 scheduler_log;;
|
||||
|
||||
/**
|
||||
* @brief This member contains the CLOCK_REALTIME value before the
|
||||
* rtems_task_wake_when() call.
|
||||
*/
|
||||
struct timespec now;;
|
||||
|
||||
/**
|
||||
* @brief This member contains the worker task identifier.
|
||||
*/
|
||||
rtems_id worker_id;;
|
||||
|
||||
/**
|
||||
* @brief This member contains the timer information of the worker task.
|
||||
*/
|
||||
TaskTimerInfo timer_info;;
|
||||
|
||||
/**
|
||||
* @brief This member provides the object referenced by the ``time_buffer``
|
||||
* parameter.
|
||||
*/
|
||||
rtems_time_of_day tod_obj;
|
||||
|
||||
/**
|
||||
* @brief This member contains the return value of the rtems_task_wake_when()
|
||||
* call.
|
||||
*/
|
||||
rtems_status_code status;
|
||||
|
||||
/**
|
||||
* @brief This member specifies the ``time_buffer`` parameter value.
|
||||
*/
|
||||
const rtems_time_of_day *tod;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @brief This member defines the pre-condition indices for the next
|
||||
* action.
|
||||
*/
|
||||
size_t pci[ 3 ];
|
||||
|
||||
/**
|
||||
* @brief This member defines the pre-condition states for the next action.
|
||||
*/
|
||||
size_t pcs[ 3 ];
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the test action loop is executed.
|
||||
*/
|
||||
bool in_action_loop;
|
||||
|
||||
/**
|
||||
* @brief This member contains the next transition map index.
|
||||
*/
|
||||
size_t index;
|
||||
|
||||
/**
|
||||
* @brief This member contains the current transition map entry.
|
||||
*/
|
||||
RtemsTaskReqWakeWhen_Entry entry;
|
||||
|
||||
/**
|
||||
* @brief If this member is true, then the current transition variant
|
||||
* should be skipped.
|
||||
*/
|
||||
bool skip;
|
||||
} Map;
|
||||
} RtemsTaskReqWakeWhen_Context;
|
||||
|
||||
static RtemsTaskReqWakeWhen_Context
|
||||
RtemsTaskReqWakeWhen_Instance;
|
||||
|
||||
static const char * const RtemsTaskReqWakeWhen_PreDesc_TODSet[] = {
|
||||
"Yes",
|
||||
"No",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqWakeWhen_PreDesc_TOD[] = {
|
||||
"Valid",
|
||||
"Null",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const RtemsTaskReqWakeWhen_PreDesc_TODObj[] = {
|
||||
"Future",
|
||||
"PastOrNow",
|
||||
"Invalid",
|
||||
"NA"
|
||||
};
|
||||
|
||||
static const char * const * const RtemsTaskReqWakeWhen_PreDesc[] = {
|
||||
RtemsTaskReqWakeWhen_PreDesc_TODSet,
|
||||
RtemsTaskReqWakeWhen_PreDesc_TOD,
|
||||
RtemsTaskReqWakeWhen_PreDesc_TODObj,
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef RtemsTaskReqWakeWhen_Context Context;
|
||||
|
||||
static void SetTOD( rtems_time_of_day *tod, uint32_t year )
|
||||
{
|
||||
memset( tod, 0, sizeof( *tod ) );
|
||||
tod->year = year;
|
||||
tod->month = 1;
|
||||
tod->day = 1;
|
||||
}
|
||||
|
||||
static void Worker( rtems_task_argument arg )
|
||||
{
|
||||
Context *ctx;
|
||||
|
||||
ctx = (Context *) arg;
|
||||
|
||||
while ( true ) {
|
||||
T_scheduler_log *log;
|
||||
|
||||
SuspendSelf();
|
||||
|
||||
log = T_scheduler_record_4( &ctx->scheduler_log );
|
||||
T_null( log );
|
||||
|
||||
_Timecounter_Getnanotime( &ctx->now );
|
||||
|
||||
ctx->status = rtems_task_wake_when( ctx->tod );
|
||||
|
||||
(void) T_scheduler_record( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Pre_TODSet_Prepare(
|
||||
RtemsTaskReqWakeWhen_Context *ctx,
|
||||
RtemsTaskReqWakeWhen_Pre_TODSet state
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_time_of_day tod;
|
||||
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeWhen_Pre_TODSet_Yes: {
|
||||
/*
|
||||
* While the CLOCK_REALTIME was set at least once.
|
||||
*/
|
||||
SetTOD( &tod, 2000 );
|
||||
sc = rtems_clock_set( &tod );
|
||||
T_rsc_success( sc );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Pre_TODSet_No: {
|
||||
/*
|
||||
* While the CLOCK_REALTIME was never set.
|
||||
*/
|
||||
UnsetClock();
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Pre_TODSet_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Pre_TOD_Prepare(
|
||||
RtemsTaskReqWakeWhen_Context *ctx,
|
||||
RtemsTaskReqWakeWhen_Pre_TOD state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeWhen_Pre_TOD_Valid: {
|
||||
/*
|
||||
* While the ``time_buffer`` parameter references an object of type
|
||||
* rtems_time_of_day.
|
||||
*/
|
||||
ctx->tod = &ctx->tod_obj;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Pre_TOD_Null: {
|
||||
/*
|
||||
* While the ``time_buffer`` parameter is equal to NULL.
|
||||
*/
|
||||
ctx->tod = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Pre_TOD_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Pre_TODObj_Prepare(
|
||||
RtemsTaskReqWakeWhen_Context *ctx,
|
||||
RtemsTaskReqWakeWhen_Pre_TODObj state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeWhen_Pre_TODObj_Future: {
|
||||
/*
|
||||
* While the object referenced by the ``time_buffer`` parameter specifies
|
||||
* a valid time of day in the future.
|
||||
*/
|
||||
SetTOD( &ctx->tod_obj, 2010 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Pre_TODObj_PastOrNow: {
|
||||
/*
|
||||
* While the object referenced by the ``time_buffer`` parameter specifies
|
||||
* a valid time of day in the past or at the time of the
|
||||
* rtems_task_wake_when() call.
|
||||
*/
|
||||
SetTOD( &ctx->tod_obj, 1990 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Pre_TODObj_Invalid: {
|
||||
/*
|
||||
* While the object referenced by the ``time_buffer`` parameter specifies
|
||||
* an invalid time of day.
|
||||
*/
|
||||
memset( &ctx->tod_obj, 0xff, sizeof( ctx->tod_obj ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Pre_TODObj_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Post_Status_Check(
|
||||
RtemsTaskReqWakeWhen_Context *ctx,
|
||||
RtemsTaskReqWakeWhen_Post_Status state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeWhen_Post_Status_Ok: {
|
||||
/*
|
||||
* The return status of rtems_task_wake_when() shall be RTEMS_SUCCESSFUL.
|
||||
*/
|
||||
T_rsc_success( ctx->status );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Status_NotDef: {
|
||||
/*
|
||||
* The return status of rtems_task_wake_when() shall be
|
||||
* RTEMS_NOT_DEFINED.
|
||||
*/
|
||||
T_rsc( ctx->status, RTEMS_NOT_DEFINED );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Status_InvAddr: {
|
||||
/*
|
||||
* The return status of rtems_task_wake_when() shall be
|
||||
* RTEMS_INVALID_ADDRESS.
|
||||
*/
|
||||
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Status_InvClock: {
|
||||
/*
|
||||
* The return status of rtems_task_wake_when() shall be
|
||||
* RTEMS_INVALID_CLOCK.
|
||||
*/
|
||||
T_rsc( ctx->status, RTEMS_INVALID_CLOCK );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Status_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Post_Timer_Check(
|
||||
RtemsTaskReqWakeWhen_Context *ctx,
|
||||
RtemsTaskReqWakeWhen_Post_Timer state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeWhen_Post_Timer_Inactive: {
|
||||
/*
|
||||
* The timer of the calling task shall be inactive.
|
||||
*/
|
||||
T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Timer_Realtime: {
|
||||
/*
|
||||
* The timer of the calling task shall be active using the
|
||||
* CLOCK_REALTIME.
|
||||
*/
|
||||
T_eq_int( ctx->timer_info.state, TASK_TIMER_REALTIME );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Timer_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Post_Expire_Check(
|
||||
RtemsTaskReqWakeWhen_Context *ctx,
|
||||
RtemsTaskReqWakeWhen_Post_Expire state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeWhen_Post_Expire_Absolute: {
|
||||
/*
|
||||
* The timer of the calling task shall expire at the time point specified
|
||||
* by the ``time_buffer`` parameter.
|
||||
*/
|
||||
T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, 1262304000 );
|
||||
T_eq_long( ctx->timer_info.expire_timespec.tv_nsec, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Expire_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Post_Scheduler_Check(
|
||||
RtemsTaskReqWakeWhen_Context *ctx,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler state
|
||||
)
|
||||
{
|
||||
switch ( state ) {
|
||||
case RtemsTaskReqWakeWhen_Post_Scheduler_Block: {
|
||||
/*
|
||||
* The calling task shall be blocked by the scheduler exactly once by the
|
||||
* rtems_task_wake_when() call.
|
||||
*/
|
||||
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
|
||||
T_eq_int(
|
||||
ctx->scheduler_log.events[ 0 ].operation,
|
||||
T_SCHEDULER_BLOCK
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Scheduler_Nop: {
|
||||
/*
|
||||
* The calling task shall not be altered by the scheduler by the
|
||||
* rtems_task_wake_when() call.
|
||||
*/
|
||||
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case RtemsTaskReqWakeWhen_Post_Scheduler_NA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Setup( RtemsTaskReqWakeWhen_Context *ctx )
|
||||
{
|
||||
SetSelfPriority( PRIO_NORMAL );
|
||||
ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
|
||||
StartTask( ctx->worker_id, Worker, ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Setup_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqWakeWhen_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqWakeWhen_Setup( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Teardown( RtemsTaskReqWakeWhen_Context *ctx )
|
||||
{
|
||||
DeleteTask( ctx->worker_id );
|
||||
RestoreRunnerPriority();
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Teardown_Wrap( void *arg )
|
||||
{
|
||||
RtemsTaskReqWakeWhen_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
ctx->Map.in_action_loop = false;
|
||||
RtemsTaskReqWakeWhen_Teardown( ctx );
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Prepare( RtemsTaskReqWakeWhen_Context *ctx )
|
||||
{
|
||||
ctx->status = RTEMS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_Action( RtemsTaskReqWakeWhen_Context *ctx )
|
||||
{
|
||||
ResumeTask( ctx->worker_id );
|
||||
(void) T_scheduler_record( NULL );
|
||||
GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
|
||||
FinalClockTick();
|
||||
}
|
||||
|
||||
static const RtemsTaskReqWakeWhen_Entry
|
||||
RtemsTaskReqWakeWhen_Entries[] = {
|
||||
{ 0, 0, 0, 1, RtemsTaskReqWakeWhen_Post_Status_InvAddr,
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeWhen_Post_Expire_NA,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
|
||||
{ 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_NotDef,
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeWhen_Post_Expire_NA,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
|
||||
{ 0, 0, 0, 1, RtemsTaskReqWakeWhen_Post_Status_NotDef,
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeWhen_Post_Expire_NA,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
|
||||
{ 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_InvClock,
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
|
||||
RtemsTaskReqWakeWhen_Post_Expire_NA,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
|
||||
{ 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_Ok,
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Realtime,
|
||||
RtemsTaskReqWakeWhen_Post_Expire_Absolute,
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Block }
|
||||
};
|
||||
|
||||
static const uint8_t
|
||||
RtemsTaskReqWakeWhen_Map[] = {
|
||||
4, 3, 3, 0, 0, 0, 1, 1, 1, 2, 2, 2
|
||||
};
|
||||
|
||||
static size_t RtemsTaskReqWakeWhen_Scope( void *arg, char *buf, size_t n )
|
||||
{
|
||||
RtemsTaskReqWakeWhen_Context *ctx;
|
||||
|
||||
ctx = arg;
|
||||
|
||||
if ( ctx->Map.in_action_loop ) {
|
||||
return T_get_scope( RtemsTaskReqWakeWhen_PreDesc, buf, n, ctx->Map.pcs );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static T_fixture RtemsTaskReqWakeWhen_Fixture = {
|
||||
.setup = RtemsTaskReqWakeWhen_Setup_Wrap,
|
||||
.stop = NULL,
|
||||
.teardown = RtemsTaskReqWakeWhen_Teardown_Wrap,
|
||||
.scope = RtemsTaskReqWakeWhen_Scope,
|
||||
.initial_context = &RtemsTaskReqWakeWhen_Instance
|
||||
};
|
||||
|
||||
static inline RtemsTaskReqWakeWhen_Entry RtemsTaskReqWakeWhen_PopEntry(
|
||||
RtemsTaskReqWakeWhen_Context *ctx
|
||||
)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
index = ctx->Map.index;
|
||||
ctx->Map.index = index + 1;
|
||||
return RtemsTaskReqWakeWhen_Entries[
|
||||
RtemsTaskReqWakeWhen_Map[ index ]
|
||||
];
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_SetPreConditionStates(
|
||||
RtemsTaskReqWakeWhen_Context *ctx
|
||||
)
|
||||
{
|
||||
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
|
||||
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
|
||||
|
||||
if ( ctx->Map.entry.Pre_TODObj_NA ) {
|
||||
ctx->Map.pcs[ 2 ] = RtemsTaskReqWakeWhen_Pre_TODObj_NA;
|
||||
} else {
|
||||
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
|
||||
}
|
||||
}
|
||||
|
||||
static void RtemsTaskReqWakeWhen_TestVariant(
|
||||
RtemsTaskReqWakeWhen_Context *ctx
|
||||
)
|
||||
{
|
||||
RtemsTaskReqWakeWhen_Pre_TODSet_Prepare( ctx, ctx->Map.pcs[ 0 ] );
|
||||
RtemsTaskReqWakeWhen_Pre_TOD_Prepare( ctx, ctx->Map.pcs[ 1 ] );
|
||||
RtemsTaskReqWakeWhen_Pre_TODObj_Prepare( ctx, ctx->Map.pcs[ 2 ] );
|
||||
RtemsTaskReqWakeWhen_Action( ctx );
|
||||
RtemsTaskReqWakeWhen_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
|
||||
RtemsTaskReqWakeWhen_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
|
||||
RtemsTaskReqWakeWhen_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
|
||||
RtemsTaskReqWakeWhen_Post_Scheduler_Check(
|
||||
ctx,
|
||||
ctx->Map.entry.Post_Scheduler
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskReqWakeWhen( void )
|
||||
*/
|
||||
T_TEST_CASE_FIXTURE( RtemsTaskReqWakeWhen, &RtemsTaskReqWakeWhen_Fixture )
|
||||
{
|
||||
RtemsTaskReqWakeWhen_Context *ctx;
|
||||
|
||||
ctx = T_fixture_context();
|
||||
ctx->Map.in_action_loop = true;
|
||||
ctx->Map.index = 0;
|
||||
|
||||
for (
|
||||
ctx->Map.pci[ 0 ] = RtemsTaskReqWakeWhen_Pre_TODSet_Yes;
|
||||
ctx->Map.pci[ 0 ] < RtemsTaskReqWakeWhen_Pre_TODSet_NA;
|
||||
++ctx->Map.pci[ 0 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 1 ] = RtemsTaskReqWakeWhen_Pre_TOD_Valid;
|
||||
ctx->Map.pci[ 1 ] < RtemsTaskReqWakeWhen_Pre_TOD_NA;
|
||||
++ctx->Map.pci[ 1 ]
|
||||
) {
|
||||
for (
|
||||
ctx->Map.pci[ 2 ] = RtemsTaskReqWakeWhen_Pre_TODObj_Future;
|
||||
ctx->Map.pci[ 2 ] < RtemsTaskReqWakeWhen_Pre_TODObj_NA;
|
||||
++ctx->Map.pci[ 2 ]
|
||||
) {
|
||||
ctx->Map.entry = RtemsTaskReqWakeWhen_PopEntry( ctx );
|
||||
RtemsTaskReqWakeWhen_SetPreConditionStates( ctx );
|
||||
RtemsTaskReqWakeWhen_Prepare( ctx );
|
||||
RtemsTaskReqWakeWhen_TestVariant( ctx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
305
testsuites/validation/tc-task.c
Normal file
305
testsuites/validation/tc-task.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/* 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 RTEMSTestSuiteTestsuitesValidationNoClock0
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* - Assert that RTEMS_TASK_STORAGE_ALIGNMENT is a constant expression which
|
||||
* evaluates to the expected value.
|
||||
*
|
||||
* - Assert that RTEMS_NO_PRIORITY is a constant expression which evaluates to
|
||||
* the expected value.
|
||||
*
|
||||
* - Assert that RTEMS_MINIMUM_STACK_SIZE is a constant expression which
|
||||
* evaluates to the expected value.
|
||||
*
|
||||
* - Assert that RTEMS_CONFIGURED_MINIMUM_STACK_SIZE is a constant expression
|
||||
* which evaluates to the expected value.
|
||||
*
|
||||
* - Assert that RTEMS_MINIMUM_PRIORITY is a constant expression which
|
||||
* evaluates to the expected value.
|
||||
*
|
||||
* - Validate RTEMS_SELF using a sample directive call.
|
||||
*
|
||||
* - Check that rtems_task_is_suspended() returns the expected status if
|
||||
* called with a task identifier parameter of RTEMS_SELF.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assert that RTEMS_TASK_STORAGE_ALIGNMENT is a constant expression
|
||||
* which evaluates to the expected value.
|
||||
*/
|
||||
static void RtemsTaskValTask_Action_3( void )
|
||||
{
|
||||
RTEMS_STATIC_ASSERT(
|
||||
RTEMS_TASK_STORAGE_ALIGNMENT == CPU_STACK_ALIGNMENT,
|
||||
STORAGE_ALIGNMENT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assert that RTEMS_NO_PRIORITY is a constant expression which
|
||||
* evaluates to the expected value.
|
||||
*/
|
||||
static void RtemsTaskValTask_Action_4( void )
|
||||
{
|
||||
RTEMS_STATIC_ASSERT(
|
||||
RTEMS_NO_PRIORITY == RTEMS_CURRENT_PRIORITY,
|
||||
NO_PRIORITY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assert that RTEMS_MINIMUM_STACK_SIZE is a constant expression which
|
||||
* evaluates to the expected value.
|
||||
*/
|
||||
static void RtemsTaskValTask_Action_5( void )
|
||||
{
|
||||
RTEMS_STATIC_ASSERT(
|
||||
RTEMS_MINIMUM_STACK_SIZE == STACK_MINIMUM_SIZE,
|
||||
MINIMUM_STACK_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assert that RTEMS_CONFIGURED_MINIMUM_STACK_SIZE is a constant
|
||||
* expression which evaluates to the expected value.
|
||||
*/
|
||||
static void RtemsTaskValTask_Action_6( void )
|
||||
{
|
||||
RTEMS_STATIC_ASSERT(
|
||||
RTEMS_CONFIGURED_MINIMUM_STACK_SIZE == 0,
|
||||
CONFIGURED_MINIMUM_STACK_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assert that RTEMS_MINIMUM_PRIORITY is a constant expression which
|
||||
* evaluates to the expected value.
|
||||
*/
|
||||
static void RtemsTaskValTask_Action_7( void )
|
||||
{
|
||||
RTEMS_STATIC_ASSERT( RTEMS_MINIMUM_PRIORITY == 1, MINIMUM_PRIORITY );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Validate RTEMS_SELF using a sample directive call.
|
||||
*/
|
||||
static void RtemsTaskValTask_Action_8( void )
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
/*
|
||||
* Check that rtems_task_is_suspended() returns the expected status if called
|
||||
* with a task identifier parameter of RTEMS_SELF.
|
||||
*/
|
||||
sc = rtems_task_is_suspended( RTEMS_SELF );
|
||||
T_step_rsc_success( 7, sc );
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void T_case_body_RtemsTaskValTask( void )
|
||||
*/
|
||||
T_TEST_CASE( RtemsTaskValTask )
|
||||
{
|
||||
T_plan( 8 );
|
||||
|
||||
RtemsTaskValTask_Action_0();
|
||||
RtemsTaskValTask_Action_1();
|
||||
RtemsTaskValTask_Action_2();
|
||||
RtemsTaskValTask_Action_3();
|
||||
RtemsTaskValTask_Action_4();
|
||||
RtemsTaskValTask_Action_5();
|
||||
RtemsTaskValTask_Action_6();
|
||||
RtemsTaskValTask_Action_7();
|
||||
RtemsTaskValTask_Action_8();
|
||||
}
|
||||
|
||||
/** @} */
|
||||
80
testsuites/validation/ts-validation-one-cpu-1.c
Normal file
80
testsuites/validation/ts-validation-one-cpu-1.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu1
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/test.h>
|
||||
|
||||
/**
|
||||
* @defgroup RTEMSTestSuiteTestsuitesValidationOneCpu1 \
|
||||
* spec:/testsuites/validation-one-cpu-1
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This general purpose validation test suite provides enough resources
|
||||
* to run basic tests with exactly one processor and without a Clock Driver.
|
||||
*
|
||||
* Two test suites of this configuration are provided to limit test run
|
||||
* duration.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
const char rtems_test_name[] = "ValidationOneCpu1";
|
||||
|
||||
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_PROCESSORS 1
|
||||
|
||||
#include "ts-default.h"
|
||||
|
||||
/** @} */
|
||||
Reference in New Issue
Block a user