mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-03 20:44:23 +08:00
@@ -20,5 +20,6 @@ links:
|
||||
uid: validation-1
|
||||
type: build
|
||||
use-after:
|
||||
- validation
|
||||
- rtemstest
|
||||
use-before: []
|
||||
|
||||
@@ -13,6 +13,13 @@ links: []
|
||||
source:
|
||||
- testsuites/validation/tx-call-within-isr.c
|
||||
- testsuites/validation/tx-interrupt.c
|
||||
- testsuites/validation/tx-io-relax.c
|
||||
- testsuites/validation/tx-memory-alloc.c
|
||||
- testsuites/validation/tx-preemption-intervention.c
|
||||
- testsuites/validation/tx-support.c
|
||||
- testsuites/validation/tx-thread-queue.c
|
||||
- testsuites/validation/tx-timecounter.c
|
||||
- testsuites/validation/tx-timer-server.c
|
||||
- testsuites/validation/tx-wrap-thread-queue.c
|
||||
target: validation
|
||||
type: build
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
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/ts-validation-no-clock-0.c
|
||||
stlib: []
|
||||
target: testsuites/validation/ts-validation-no-clock-0.exe
|
||||
type: build
|
||||
use-after: []
|
||||
use-before: []
|
||||
@@ -1041,7 +1041,7 @@ static void RtemsIntrReqEntryInstall_Setup(
|
||||
rtems_status_code sc;
|
||||
|
||||
ctx->initialized_during_setup = bsp_interrupt_is_initialized();
|
||||
ctx->test_vector = GetTestableInterruptVector();
|
||||
ctx->test_vector = GetTestableInterruptVector( NULL );
|
||||
sc = rtems_interrupt_get_attributes( ctx->test_vector, &ctx->attributes );
|
||||
T_rsc_success( sc );
|
||||
}
|
||||
|
||||
@@ -1081,7 +1081,7 @@ static void RtemsIntrReqEntryRemove_Setup(
|
||||
rtems_status_code sc;
|
||||
|
||||
ctx->initialized_during_setup = bsp_interrupt_is_initialized();
|
||||
ctx->test_vector = GetTestableInterruptVector();
|
||||
ctx->test_vector = GetTestableInterruptVector( NULL );
|
||||
sc = rtems_interrupt_get_attributes( ctx->test_vector, &ctx->attributes );
|
||||
T_rsc_success( sc );
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ static void RtemsIntrReqHandlerIterate_Setup(
|
||||
rtems_status_code sc;
|
||||
|
||||
ctx->initialized_during_setup = bsp_interrupt_is_initialized();
|
||||
ctx->test_vector = GetTestableInterruptVector();
|
||||
ctx->test_vector = GetTestableInterruptVector( NULL );
|
||||
rtems_interrupt_entry_initialize(
|
||||
&ctx->entry,
|
||||
EntryRoutine,
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This header file provides the constants used by the test suite
|
||||
* configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _TS_CONFIG_H
|
||||
#define _TS_CONFIG_H
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup RTEMSTestSuites
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define TEST_MICROSECONDS_PER_TICK 1000
|
||||
|
||||
#define TEST_RUNNER_NAME rtems_build_name( 'R', 'U', 'N', ' ' )
|
||||
|
||||
#define TEST_RUNNER_ARGUMENT 123456789
|
||||
|
||||
#define TEST_RUNNER_INITIAL_MODES RTEMS_NO_ASR
|
||||
|
||||
#define TEST_SCHEDULER_A_NAME rtems_build_name( 'A', ' ', ' ', ' ' )
|
||||
|
||||
#define TEST_SCHEDULER_B_NAME rtems_build_name( 'B', ' ', ' ', ' ' )
|
||||
|
||||
#define TEST_SCHEDULER_C_NAME rtems_build_name( 'C', ' ', ' ', ' ' )
|
||||
|
||||
#define TEST_SCHEDULER_D_NAME rtems_build_name( 'D', ' ', ' ', ' ' )
|
||||
|
||||
#if defined( __OPTIMIZE__ ) && !defined( RTEMS_COVERAGE )
|
||||
#define TEST_BASE_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE
|
||||
#else
|
||||
#define TEST_BASE_STACK_SIZE ( 4 * RTEMS_MINIMUM_STACK_SIZE )
|
||||
#endif
|
||||
|
||||
#define TEST_MAXIMUM_TLS_SIZE \
|
||||
RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT )
|
||||
|
||||
#define TEST_MINIMUM_STACK_SIZE \
|
||||
( TEST_BASE_STACK_SIZE + CPU_STACK_ALIGNMENT )
|
||||
|
||||
#define TEST_IDLE_STACK_SIZE \
|
||||
( TEST_BASE_STACK_SIZE + 2 * CPU_STACK_ALIGNMENT )
|
||||
|
||||
#define TEST_INTERRUPT_STACK_SIZE \
|
||||
( TEST_BASE_STACK_SIZE + 4 * CPU_INTERRUPT_STACK_ALIGNMENT )
|
||||
|
||||
#define TEST_MAXIMUM_BARRIERS 7
|
||||
|
||||
#define TEST_MAXIMUM_MESSAGE_QUEUES 3
|
||||
|
||||
#define TEST_MAXIMUM_PARTITIONS 4
|
||||
|
||||
#define TEST_MAXIMUM_PERIODS 2
|
||||
|
||||
#define TEST_MAXIMUM_SEMAPHORES 7
|
||||
|
||||
#define TEST_MAXIMUM_TASKS 32
|
||||
|
||||
#define TEST_MAXIMUM_TIMERS 10
|
||||
|
||||
#define TEST_MAXIMUM_USER_EXTENSIONS 5
|
||||
|
||||
/*
|
||||
* Use at least two so that the CPU time budget decrement in
|
||||
* _Scheduler_default_Tick() does not always result in a zero.
|
||||
*/
|
||||
#define TEST_TICKS_PER_TIMESLICE 2
|
||||
|
||||
void *test_task_stack_allocate( size_t size );
|
||||
|
||||
void test_task_stack_deallocate( void *stack );
|
||||
|
||||
void *test_idle_task_stack_allocate( uint32_t cpu_index, size_t size );
|
||||
|
||||
extern rtems_task_argument test_runner_argument;
|
||||
|
||||
extern rtems_task_priority test_runner_initial_priority;
|
||||
|
||||
extern rtems_mode test_runner_initial_modes;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TS_CONFIG_H */
|
||||
@@ -45,6 +45,30 @@
|
||||
|
||||
#include <bsp/irq-generic.h>
|
||||
|
||||
static bool HasRequiredAttributes(
|
||||
const rtems_interrupt_attributes *required,
|
||||
const rtems_interrupt_attributes *actual
|
||||
)
|
||||
{
|
||||
if ( required == NULL ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( required->can_get_affinity && !actual->can_get_affinity ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( required->can_raise && !actual->can_raise ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( required->can_raise_on && !actual->can_raise_on ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
rtems_vector_number GetValidInterruptVectorNumber(
|
||||
const rtems_interrupt_attributes *required
|
||||
)
|
||||
@@ -57,11 +81,7 @@ rtems_vector_number GetValidInterruptVectorNumber(
|
||||
|
||||
sc = rtems_interrupt_get_attributes( vector, &attr );
|
||||
|
||||
if (
|
||||
sc == RTEMS_SUCCESSFUL &&
|
||||
( required == NULL ||
|
||||
!required->can_get_affinity || attr.can_get_affinity )
|
||||
) {
|
||||
if ( sc == RTEMS_SUCCESSFUL && HasRequiredAttributes( required, &attr ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -69,7 +89,9 @@ rtems_vector_number GetValidInterruptVectorNumber(
|
||||
return vector;
|
||||
}
|
||||
|
||||
rtems_vector_number GetTestableInterruptVector( void )
|
||||
rtems_vector_number GetTestableInterruptVector(
|
||||
const rtems_interrupt_attributes *required
|
||||
)
|
||||
{
|
||||
rtems_vector_number vector;
|
||||
|
||||
@@ -87,6 +109,10 @@ rtems_vector_number GetTestableInterruptVector( void )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !HasRequiredAttributes( required, &attr ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( HasInterruptVectorEntriesInstalled( vector ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This source file contains the implementation of SetIORelaxHandler().
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
void __real__IO_Relax( void );
|
||||
|
||||
void __wrap__IO_Relax( void );
|
||||
|
||||
static void ( *io_relax_handler )( void * );
|
||||
|
||||
static void *io_relax_arg;
|
||||
|
||||
void __wrap__IO_Relax( void )
|
||||
{
|
||||
void ( *handler )( void * );
|
||||
|
||||
handler = io_relax_handler;
|
||||
|
||||
if ( handler != NULL ) {
|
||||
( *handler )( io_relax_arg );
|
||||
}
|
||||
|
||||
__real__IO_Relax();
|
||||
}
|
||||
|
||||
void SetIORelaxHandler( void ( *handler )( void * ), void *arg )
|
||||
{
|
||||
io_relax_handler = handler;
|
||||
io_relax_arg = arg;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This source file contains the implementation of
|
||||
* MemoryAllocationFailWhen() and __wrap_rtems_malloc().
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
void *__real_rtems_malloc( size_t );
|
||||
|
||||
void *__wrap_rtems_malloc( size_t );
|
||||
|
||||
static uint32_t fail_when_counter;
|
||||
|
||||
void MemoryAllocationFailWhen( uint32_t counter )
|
||||
{
|
||||
fail_when_counter = counter;
|
||||
}
|
||||
|
||||
static bool IsFail( void )
|
||||
{
|
||||
uint32_t counter;
|
||||
|
||||
counter = fail_when_counter;
|
||||
|
||||
if ( counter == 1 ) {
|
||||
fail_when_counter = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( counter > 1 ) {
|
||||
fail_when_counter = counter - 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void *__wrap_rtems_malloc( size_t size )
|
||||
{
|
||||
if ( IsFail() ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return __real_rtems_malloc( size );
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This source file contains the implementation of
|
||||
* SetPreemptionIntervention().
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/score/chainimpl.h>
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
|
||||
#include <rtems/test.h>
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
typedef struct {
|
||||
void ( *handler )( void * );
|
||||
void *arg;
|
||||
Scheduler_Context scheduler_context;
|
||||
Scheduler_Node scheduler_node;
|
||||
Thread_Control thread;
|
||||
} PreemptionInterventionContext;
|
||||
|
||||
static PreemptionInterventionContext preemption_intervention_instance;
|
||||
|
||||
static bool PreemptionInterventionAskForHelp(
|
||||
const Scheduler_Control *scheduler,
|
||||
Thread_Control *thread,
|
||||
Scheduler_Node *node
|
||||
)
|
||||
{
|
||||
PreemptionInterventionContext *ctx;
|
||||
void ( *handler )( void * );
|
||||
void *arg;
|
||||
|
||||
(void) scheduler;
|
||||
(void) thread;
|
||||
(void) node;
|
||||
|
||||
ctx = &preemption_intervention_instance;
|
||||
handler = ctx->handler;
|
||||
arg = ctx->arg;
|
||||
ctx->handler = NULL;
|
||||
ctx->arg = NULL;
|
||||
( *handler )( arg );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const Scheduler_Control preemption_intervention_scheduler = {
|
||||
.context = &preemption_intervention_instance.scheduler_context,
|
||||
.Operations = {
|
||||
.ask_for_help = PreemptionInterventionAskForHelp
|
||||
}
|
||||
};
|
||||
|
||||
static void PreemptionInterventionInitialize( void )
|
||||
{
|
||||
PreemptionInterventionContext *ctx;
|
||||
|
||||
ctx = &preemption_intervention_instance;
|
||||
|
||||
_Chain_Initialize_node( &ctx->thread.Scheduler.Help_node );
|
||||
_Thread_queue_Initialize(
|
||||
&ctx->thread.Join_queue,
|
||||
"Preemption Intervention"
|
||||
);
|
||||
_ISR_lock_Initialize(
|
||||
&ctx->scheduler_context.Lock,
|
||||
"Preemption Intervention"
|
||||
);
|
||||
_Scheduler_Node_do_initialize(
|
||||
&preemption_intervention_scheduler,
|
||||
&ctx->scheduler_node,
|
||||
&ctx->thread,
|
||||
0
|
||||
);
|
||||
_Chain_Initialize_one(
|
||||
&ctx->thread.Scheduler.Scheduler_nodes,
|
||||
&ctx->scheduler_node.Thread.Scheduler_node.Chain
|
||||
);
|
||||
}
|
||||
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
PreemptionInterventionInitialize,
|
||||
RTEMS_SYSINIT_DEVICE_DRIVERS,
|
||||
RTEMS_SYSINIT_ORDER_MIDDLE
|
||||
);
|
||||
#endif
|
||||
|
||||
void SetPreemptionIntervention(
|
||||
struct Per_CPU_Control *cpu,
|
||||
void ( *handler )( void * ),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
#if defined(RTEMS_SMP)
|
||||
PreemptionInterventionContext *ctx;
|
||||
rtems_interrupt_level level;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
ctx = &preemption_intervention_instance;
|
||||
T_quiet_assert_null( ctx->handler );
|
||||
ctx->handler = handler;
|
||||
ctx->arg = arg;
|
||||
|
||||
rtems_interrupt_local_disable( level );
|
||||
_Per_CPU_Acquire( cpu, &lock_context );
|
||||
_Chain_Append_unprotected(
|
||||
&cpu->Threads_in_need_for_help,
|
||||
&ctx->thread.Scheduler.Help_node
|
||||
);
|
||||
_Per_CPU_Release( cpu, &lock_context );
|
||||
rtems_interrupt_local_enable( level );
|
||||
#else
|
||||
(void) cpu;
|
||||
(void) handler;
|
||||
(void) arg;
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,160 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This source file contains the definition of SetGetTimecountHandler(),
|
||||
* GetTimecountCounter(), and SetTimecountCounter().
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/timecounter.h>
|
||||
#include <rtems/score/atomic.h>
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/smpimpl.h>
|
||||
#include <rtems/score/threaddispatch.h>
|
||||
|
||||
typedef struct {
|
||||
struct timecounter base;
|
||||
GetTimecountHandler handler;
|
||||
Atomic_Ulong counter;
|
||||
} TimecounterControl;
|
||||
|
||||
static TimecounterControl TimecounterInstance;
|
||||
|
||||
GetTimecountHandler SetGetTimecountHandler( GetTimecountHandler handler )
|
||||
{
|
||||
GetTimecountHandler previous;
|
||||
|
||||
previous = TimecounterInstance.handler;
|
||||
TimecounterInstance.handler = handler;
|
||||
return previous;
|
||||
}
|
||||
|
||||
uint32_t GetTimecountCounter( void )
|
||||
{
|
||||
return (uint32_t) _Atomic_Load_ulong(
|
||||
&TimecounterInstance.counter,
|
||||
ATOMIC_ORDER_RELAXED
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t SetTimecountCounter( uint32_t counter )
|
||||
{
|
||||
return (uint32_t) _Atomic_Exchange_ulong(
|
||||
&TimecounterInstance.counter,
|
||||
counter,
|
||||
ATOMIC_ORDER_RELAXED
|
||||
);
|
||||
}
|
||||
|
||||
static uint32_t GetTimecountSoftware( void )
|
||||
{
|
||||
return (uint32_t) _Atomic_Fetch_add_ulong(
|
||||
&TimecounterInstance.counter,
|
||||
1,
|
||||
ATOMIC_ORDER_RELAXED
|
||||
);
|
||||
}
|
||||
|
||||
static uint32_t GetTimecountWrapper( struct timecounter *tc )
|
||||
{
|
||||
TimecounterControl *self;
|
||||
|
||||
self = (TimecounterControl *) tc;
|
||||
return ( *self->handler )();
|
||||
}
|
||||
|
||||
static void InstallTimecounter( void )
|
||||
{
|
||||
TimecounterControl *self;
|
||||
|
||||
self = &TimecounterInstance;
|
||||
self->handler = GetTimecountSoftware;
|
||||
self->base.tc_get_timecount = GetTimecountWrapper;
|
||||
self->base.tc_counter_mask = 0xffffffff;
|
||||
self->base.tc_frequency = SOFTWARE_TIMECOUNTER_FREQUENCY;
|
||||
self->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
|
||||
rtems_timecounter_install( &self->base );
|
||||
}
|
||||
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
InstallTimecounter,
|
||||
RTEMS_SYSINIT_DEVICE_DRIVERS,
|
||||
RTEMS_SYSINIT_ORDER_LAST
|
||||
);
|
||||
|
||||
static void DoTimecounterTick( void *arg )
|
||||
{
|
||||
(void) arg;
|
||||
_Timecounter_Tick();
|
||||
}
|
||||
|
||||
void TimecounterTick( void )
|
||||
{
|
||||
unsigned long counter_ticks_per_clock_tick;
|
||||
Per_CPU_Control *cpu_self;
|
||||
bool success;
|
||||
|
||||
counter_ticks_per_clock_tick =
|
||||
SOFTWARE_TIMECOUNTER_FREQUENCY / rtems_clock_get_ticks_per_second();
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
|
||||
do {
|
||||
unsigned long old_counter;
|
||||
unsigned long new_counter;
|
||||
|
||||
old_counter = _Atomic_Load_ulong(
|
||||
&TimecounterInstance.counter,
|
||||
ATOMIC_ORDER_RELAXED
|
||||
);
|
||||
new_counter = old_counter + counter_ticks_per_clock_tick -
|
||||
( old_counter % counter_ticks_per_clock_tick );
|
||||
success = _Atomic_Compare_exchange_ulong(
|
||||
&TimecounterInstance.counter,
|
||||
&old_counter,
|
||||
new_counter,
|
||||
ATOMIC_ORDER_RELAXED,
|
||||
ATOMIC_ORDER_RELAXED
|
||||
);
|
||||
} while ( !success );
|
||||
|
||||
DoTimecounterTick( NULL );
|
||||
#if defined( RTEMS_SMP )
|
||||
_SMP_Othercast_action( DoTimecounterTick, NULL );
|
||||
#endif
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This source file contains the definition of DeleteTimerServer().
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/test.h>
|
||||
#include <rtems/rtems/timerimpl.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
|
||||
rtems_id GetTimerServerTaskId( void )
|
||||
{
|
||||
if ( _Timer_server == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
return _Timer_server->server_id;
|
||||
}
|
||||
|
||||
bool DeleteTimerServer( void )
|
||||
{
|
||||
Timer_server_Control *server;
|
||||
|
||||
server = _Timer_server;
|
||||
|
||||
if ( server == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DeleteTask( server->server_id );
|
||||
_ISR_lock_Destroy( &server->Lock );
|
||||
T_true( _Chain_Is_empty( &server->Pending ) );
|
||||
_Timer_server = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Timer_Classes GetTimerClass( rtems_id id )
|
||||
{
|
||||
/* This code is derived from rtems_timer_get_information() */
|
||||
Timer_Classes result = TIMER_DORMANT;
|
||||
Timer_Control *the_timer;
|
||||
ISR_lock_Context lock_context;
|
||||
Per_CPU_Control *cpu;
|
||||
|
||||
the_timer = _Timer_Get( id, &lock_context );
|
||||
if ( the_timer != NULL ) {
|
||||
cpu = _Timer_Acquire_critical( the_timer, &lock_context );
|
||||
result = the_timer->the_class;
|
||||
_Timer_Release( cpu, &lock_context );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void GetTimerSchedulingData(
|
||||
rtems_id id,
|
||||
Timer_Scheduling_Data *data
|
||||
)
|
||||
{
|
||||
/* This code is derived from rtems_timer_get_information() */
|
||||
Timer_Control *the_timer;
|
||||
ISR_lock_Context lock_context;
|
||||
Per_CPU_Control *cpu;
|
||||
|
||||
if ( data == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
the_timer = _Timer_Get( id, &lock_context );
|
||||
if ( the_timer != NULL ) {
|
||||
cpu = _Timer_Acquire_critical( the_timer, &lock_context );
|
||||
data->routine = the_timer->routine;
|
||||
data->user_data = the_timer->user_data;
|
||||
data->interval = the_timer->initial;
|
||||
_Timer_Release( cpu, &lock_context );
|
||||
}
|
||||
}
|
||||
|
||||
Timer_States GetTimerState( rtems_id id )
|
||||
{
|
||||
/* This code is derived from rtems_timer_cancel() and _timer_cancel() */
|
||||
Timer_States result = TIMER_INVALID;
|
||||
Timer_Control *the_timer;
|
||||
ISR_lock_Context lock_context;
|
||||
Per_CPU_Control *cpu;
|
||||
Timer_Classes the_class;
|
||||
Timer_server_Control *timer_server = _Timer_server;
|
||||
ISR_lock_Context lock_context_server;
|
||||
|
||||
the_timer = _Timer_Get( id, &lock_context );
|
||||
if ( the_timer != NULL ) {
|
||||
result = TIMER_INACTIVE;
|
||||
cpu = _Timer_Acquire_critical( the_timer, &lock_context );
|
||||
the_class = the_timer->the_class;
|
||||
|
||||
if ( _Watchdog_Is_scheduled( &the_timer->Ticker ) ) {
|
||||
result = TIMER_SCHEDULED;
|
||||
} else if ( _Timer_Is_on_task_class( the_class ) ) {
|
||||
_Assert( timer_server != NULL );
|
||||
_Timer_server_Acquire_critical( timer_server, &lock_context_server );
|
||||
if ( _Watchdog_Get_state( &the_timer->Ticker ) == WATCHDOG_PENDING ) {
|
||||
result = TIMER_PENDING;
|
||||
}
|
||||
_Timer_server_Release_critical( timer_server, &lock_context_server );
|
||||
}
|
||||
_Timer_Release( cpu, &lock_context );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void UnsetClock( void )
|
||||
{
|
||||
_TOD.is_set = false;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSTestSuites
|
||||
*
|
||||
* @brief This source file contains the implementation of the thread queue
|
||||
* wrapper.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "tx-support.h"
|
||||
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void WrapThreadQueueInitialize(
|
||||
WrapThreadQueueContext *ctx,
|
||||
void ( *handler )( void * ),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
memset( ctx, 0, sizeof( *ctx ) );
|
||||
ctx->isr_request.handler = handler;
|
||||
ctx->isr_request.arg = arg;
|
||||
_Thread_queue_Initialize( &ctx->thread_queue, "Wrap" );
|
||||
}
|
||||
|
||||
static void Prepare(
|
||||
WrapThreadQueueContext *ctx,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
if ( thread->Wait.queue != NULL ) {
|
||||
ctx->wrapped_ops = thread->Wait.operations;
|
||||
thread->Wait.operations = &ctx->tq_ops;
|
||||
} else {
|
||||
Thread_queue_Context queue_context;
|
||||
|
||||
ctx->wrapped_ops = NULL;
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Acquire( &ctx->thread_queue, &queue_context );
|
||||
_Thread_Wait_flags_set(
|
||||
thread,
|
||||
THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK
|
||||
);
|
||||
_Thread_Wait_claim( thread, &ctx->thread_queue.Queue );
|
||||
_Thread_Wait_claim_finalize( thread, &ctx->tq_ops );
|
||||
_Thread_queue_Release( &ctx->thread_queue, &queue_context );
|
||||
}
|
||||
}
|
||||
|
||||
static void WrappedExtract(
|
||||
WrapThreadQueueContext *ctx,
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *thread,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
if ( ctx->wrapped_ops ) {
|
||||
thread->Wait.operations = ctx->wrapped_ops;
|
||||
( *thread->Wait.operations->extract )( queue, thread, queue_context );
|
||||
}
|
||||
}
|
||||
|
||||
static void Extract(
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *thread,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
WrapThreadQueueContext *ctx;
|
||||
|
||||
ctx = (WrapThreadQueueContext *) thread->Wait.operations;
|
||||
CallWithinISRSubmit( &ctx->isr_request );
|
||||
WrappedExtract( ctx, queue, thread, queue_context );
|
||||
}
|
||||
|
||||
void WrapThreadQueueExtract(
|
||||
WrapThreadQueueContext *ctx,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
ctx->tq_ops.extract = Extract;
|
||||
Prepare( ctx, thread );
|
||||
}
|
||||
|
||||
static void ExtractDirect(
|
||||
Thread_queue_Queue *queue,
|
||||
Thread_Control *thread,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
WrapThreadQueueContext *ctx;
|
||||
|
||||
ctx = (WrapThreadQueueContext *) thread->Wait.operations;
|
||||
( *ctx->isr_request.handler )( ctx->isr_request.arg );
|
||||
WrappedExtract( ctx, queue, thread, queue_context );
|
||||
}
|
||||
|
||||
void WrapThreadQueueExtractDirect(
|
||||
WrapThreadQueueContext *ctx,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
ctx->tq_ops.extract = ExtractDirect;
|
||||
Prepare( ctx, thread );
|
||||
}
|
||||
|
||||
void WrapThreadQueueDestroy( WrapThreadQueueContext *ctx )
|
||||
{
|
||||
_Thread_queue_Destroy( &ctx->thread_queue );
|
||||
}
|
||||
Reference in New Issue
Block a user