score: Remove PRIORITY_PSEUDO_ISR thread priority

The uniprocessor schedulers had some special case logic for the
PRIORITY_PSEUDO_ISR priority.  Tasks with a priority of PRIORITY_PSEUDO_ISR
were allowed to preempt a not preemptible task.  If other higher priority task
are made ready while a PRIORITY_PSEUDO_ISR task preempts a not preemptible
task, then the other tasks run before the not preemptible task.  This made the
RTEMS_NO_PREEMPT mode ineffective.

Remove the PRIORITY_PSEUDO_ISR special case logic.  This simplifies the
uniprocessor schedulers.  Move the uniprocessor-specific scheduler support to
the new header file <rtems/score/scheduleruniimpl.h>.

Close #2365.
This commit is contained in:
Sebastian Huber
2022-07-15 09:16:04 +02:00
parent 0a1d2d7814
commit 7fe6d60bf0
26 changed files with 295 additions and 204 deletions

View File

@@ -84,7 +84,7 @@ RTEMS_INLINE_ROUTINE int _POSIX_Priority_Get_maximum(
* Thus, SuperCore has priorities run in the opposite sense of the POSIX API.
*
* Let N be the maximum priority of this scheduler instance. The SuperCore
* priority zero is system reserved (PRIORITY_PSEUDO_ISR). There are only
* priority zero is system reserved (PRIORITY_MINIMUM). There are only
* N - 1 POSIX API priority levels since a thread at SuperCore priority N would
* never run because of the idle threads. This is necessary because GNAT maps
* the lowest Ada task priority to the lowest thread priority. The lowest

View File

@@ -95,13 +95,6 @@ typedef uint64_t Priority_Control;
*/
#define PRIORITY_MINIMUM 0
/**
* @brief The priority value of pseudo-ISR threads.
*
* Examples are the MPCI and timer server threads.
*/
#define PRIORITY_PSEUDO_ISR PRIORITY_MINIMUM
/**
* @brief The default lowest (least important) thread priority value.
*

View File

@@ -39,7 +39,7 @@
#define _RTEMS_SCORE_SCHEDULEREDFIMPL_H
#include <rtems/score/scheduleredf.h>
#include <rtems/score/schedulerimpl.h>
#include <rtems/score/scheduleruniimpl.h>
#ifdef __cplusplus
extern "C" {
@@ -216,30 +216,23 @@ RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Extract_body(
}
/**
* @brief Schedules the next ready thread as the heir.
* @brief Gets the highest priority ready thread of the scheduler.
*
* @param scheduler The scheduler instance to schedule the minimum of the context of.
* @param the_thread This parameter is not used.
* @param force_dispatch Indicates whether the current heir is blocked even if it is
* not set as preemptible.
* @param scheduler is the scheduler.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
bool force_dispatch
RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_EDF_Get_highest_ready(
const Scheduler_Control *scheduler
)
{
Scheduler_EDF_Context *context;
RBTree_Node *first;
Scheduler_EDF_Node *node;
(void) the_thread;
context = _Scheduler_EDF_Get_context( scheduler );
first = _RBTree_Minimum( &context->Ready );
node = RTEMS_CONTAINER_OF( first, Scheduler_EDF_Node, Node );
_Scheduler_Update_heir( node->Base.owner, force_dispatch );
return node->Base.owner;
}
/** @} */

View File

@@ -668,40 +668,6 @@ Status_Control _Scheduler_Set_affinity(
const cpu_set_t *cpuset
);
/**
* @brief Blocks the thread.
*
* @param scheduler The scheduler instance.
* @param the_thread The thread to block.
* @param node The corresponding scheduler node.
* @param extract Method to extract the thread.
* @param schedule Method for scheduling threads.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Generic_block(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node,
void ( *extract )(
const Scheduler_Control *,
Thread_Control *,
Scheduler_Node *
),
void ( *schedule )(
const Scheduler_Control *,
Thread_Control *,
bool
)
)
{
( *extract )( scheduler, the_thread, node );
/* TODO: flash critical section? */
if ( _Thread_Is_heir( the_thread ) ) {
( *schedule )( scheduler, the_thread, true );
}
}
/**
* @brief Gets the number of processors of the scheduler.
*
@@ -951,37 +917,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Discard_idle_thread(
}
#endif
/**
* @brief Updates the heir.
*
* @param[in, out] new_heir The new heir.
* @param force_dispatch Indicates whether the dispatch happens also if the
* currently running thread is set as not preemptible.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir(
Thread_Control *new_heir,
bool force_dispatch
)
{
Thread_Control *heir = _Thread_Heir;
if ( heir != new_heir && ( heir->is_preemptible || force_dispatch ) ) {
#if defined(RTEMS_SMP)
/*
* We need this state only for _Thread_Get_CPU_time_used_locked(). Cannot
* use _Scheduler_Thread_change_state() since THREAD_SCHEDULER_BLOCKED to
* THREAD_SCHEDULER_BLOCKED state changes are illegal for the real SMP
* schedulers.
*/
heir->Scheduler.state = THREAD_SCHEDULER_BLOCKED;
new_heir->Scheduler.state = THREAD_SCHEDULER_SCHEDULED;
#endif
_Thread_Update_CPU_time_used( heir, _Thread_Get_CPU( heir ) );
_Thread_Heir = new_heir;
_Thread_Dispatch_necessary = true;
}
}
/**
* @brief Sets a new scheduler.
*

View File

@@ -41,7 +41,7 @@
#include <rtems/score/schedulerpriority.h>
#include <rtems/score/chainimpl.h>
#include <rtems/score/prioritybitmapimpl.h>
#include <rtems/score/schedulerimpl.h>
#include <rtems/score/scheduleruniimpl.h>
#include <rtems/score/thread.h>
#ifdef __cplusplus
@@ -231,33 +231,21 @@ RTEMS_INLINE_ROUTINE Chain_Node *_Scheduler_priority_Ready_queue_first(
}
/**
* @brief Scheduling decision logic.
* @brief Gets the highest priority ready thread of the scheduler.
*
* This kernel routine implements scheduling decision logic
* for priority-based scheduling.
*
* @param[in, out] scheduler The scheduler instance.
* @param the_thread This parameter is unused.
* @param force_dispatch Indicates whether the dispatch happens also if
* the currently executing thread is set as not preemptible.
* @param scheduler is the scheduler.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
bool force_dispatch
RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Get_highest_ready(
const Scheduler_Control *scheduler
)
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
Thread_Control *heir = (Thread_Control *)
_Scheduler_priority_Ready_queue_first(
&context->Bit_map,
&context->Ready[ 0 ]
);
( void ) the_thread;
_Scheduler_Update_heir( heir, force_dispatch );
return (Thread_Control *) _Scheduler_priority_Ready_queue_first(
&context->Bit_map,
&context->Ready[ 0 ]
);
}
/**

View File

@@ -39,7 +39,7 @@
#include <rtems/score/schedulersimple.h>
#include <rtems/score/chainimpl.h>
#include <rtems/score/schedulerimpl.h>
#include <rtems/score/scheduleruniimpl.h>
#ifdef __cplusplus
extern "C" {
@@ -133,28 +133,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_simple_Extract(
}
/**
* @brief Scheduling decision logic.
* @brief Gets the highest priority ready thread of the scheduler.
*
* This kernel routine implements scheduling decision logic for the simple scheduler.
*
* @param[in, out] scheduler The scheduler instance.
* @param the_thread This parameter is unused.
* @param force_dispatch Indicates whether the dispatch happens also if
* the currently executing thread is set as not preemptible.
* @param scheduler is the scheduler.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_simple_Schedule_body(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
bool force_dispatch
RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_simple_Get_highest_ready(
const Scheduler_Control *scheduler
)
{
Scheduler_simple_Context *context =
_Scheduler_simple_Get_context( scheduler );
Thread_Control *heir = (Thread_Control *) _Chain_First( &context->Ready );
( void ) the_thread;
_Scheduler_Update_heir( heir, force_dispatch );
return (Thread_Control *) _Chain_First( &context->Ready );
}
/** @} */

View File

@@ -0,0 +1,221 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSScoreScheduler
*
* @brief This header file provides interfaces of the supporting the
* implementation of uniprocessor schedulers.
*/
/*
* Copyright (C) 2010 Gedare Bloom.
* Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
* Copyright (C) 2014, 2022 embedded brains GmbH
*
* 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 _RTEMS_SCORE_SCHEDULERUNIIMPL_H
#define _RTEMS_SCORE_SCHEDULERUNIIMPL_H
#include <rtems/score/schedulerimpl.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup RTEMSScoreScheduler
*
* @{
*/
/**
* @brief Updates the heir thread of the processor.
*
* @param[in, out] heir is the current heir thread.
* @param[in, out] new_heir is the new heir thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_uniprocessor_Update_heir(
Thread_Control *heir,
Thread_Control *new_heir
)
{
_Assert( heir != new_heir );
#if defined(RTEMS_SMP)
/*
* We need this state only for _Thread_Get_CPU_time_used_locked(). Cannot
* use _Scheduler_Thread_change_state() since THREAD_SCHEDULER_BLOCKED to
* THREAD_SCHEDULER_BLOCKED state changes are illegal for the real SMP
* schedulers.
*/
heir->Scheduler.state = THREAD_SCHEDULER_BLOCKED;
new_heir->Scheduler.state = THREAD_SCHEDULER_SCHEDULED;
#endif
_Thread_Update_CPU_time_used( heir, _Thread_Get_CPU( heir ) );
_Thread_Heir = new_heir;
_Thread_Dispatch_necessary = true;
}
/**
* @brief Updates the heir thread of the processor if the current heir is
* not equal to the new heir thread.
*
* The update takes place even if the current heir thread is not preemptible.
*
* @param[in, out] new_heir is the new heir thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_uniprocessor_Update_heir_if_necessary(
Thread_Control *new_heir
)
{
Thread_Control *heir = _Thread_Heir;
if ( heir != new_heir ) {
_Scheduler_uniprocessor_Update_heir( heir, new_heir );
}
}
/**
* @brief Updates the heir thread of the processor if the current heir thread
* is preemptible.
*
* @param[in, out] heir is the current heir thread.
* @param[in, out] new_heir is the new heir thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_uniprocessor_Update_heir_if_preemptible(
Thread_Control *heir,
Thread_Control *new_heir
)
{
if ( heir != new_heir && heir->is_preemptible ) {
_Scheduler_uniprocessor_Update_heir( heir, new_heir );
}
}
/**
* @brief Blocks the thread.
*
* @param scheduler is the scheduler.
* @param the_thread is the thread to block.
* @param node is the scheduler node of the thread.
* @param extract is the handler to extract the thread.
* @param get_highest_ready is the handler to get the highest ready thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_uniprocessor_Block(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node,
void ( *extract )(
const Scheduler_Control *,
Thread_Control *,
Scheduler_Node *
),
Thread_Control *( *get_highest_ready )( const Scheduler_Control * )
)
{
( *extract )( scheduler, the_thread, node );
/* TODO: flash critical section? */
if ( _Thread_Is_heir( the_thread ) ) {
Thread_Control *highest_ready;
highest_ready = ( *get_highest_ready )( scheduler );
_Scheduler_uniprocessor_Update_heir( _Thread_Heir, highest_ready );
}
}
/**
* @brief Schedule the unblocked thread if it is the highest ready thread.
*
* @param scheduler is the scheduler.
* @param the_thread is the thread.
* @param priority is the priority of the thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_uniprocessor_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control priority
)
{
Thread_Control *heir;
heir = _Thread_Heir;
/*
* If the thread is more important than the heir, then we have a new heir.
* This may or may not result in a context switch. If the current heir
* thread is preemptible, then we need to do a context switch.
*/
if ( priority < _Thread_Get_priority( heir ) ) {
_Scheduler_uniprocessor_Update_heir_if_preemptible( heir, the_thread );
}
}
/**
* @brief Schedules the highest ready thread if the current heir thread of the
* processor is preemptible.
*
* @param scheduler is the scheduler.
* @param get_highest_ready is the handler to get the highest ready thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_uniprocessor_Schedule(
const Scheduler_Control *scheduler,
Thread_Control *( *get_highest_ready )( const Scheduler_Control * )
)
{
Thread_Control *highest_ready;
highest_ready = ( *get_highest_ready )( scheduler );
_Scheduler_uniprocessor_Update_heir_if_preemptible(
_Thread_Heir,
highest_ready
);
}
/**
* @brief Yields to the highest ready thread.
*
* @param scheduler is the scheduler.
* @param get_highest_ready is the handler to get the highest ready thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_uniprocessor_Yield(
const Scheduler_Control *scheduler,
Thread_Control *( *get_highest_ready )( const Scheduler_Control * )
)
{
Thread_Control *highest_ready;
highest_ready = ( *get_highest_ready )( scheduler );
_Scheduler_uniprocessor_Update_heir_if_necessary( highest_ready );
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _RTEMS_SCORE_SCHEDULERUNIIMPL_H */

View File

@@ -173,7 +173,7 @@ static rtems_status_code _Timer_server_Initiate(
}
if ( priority == RTEMS_TIMER_SERVER_DEFAULT_PRIORITY ) {
priority = PRIORITY_PSEUDO_ISR;
priority = PRIORITY_MINIMUM;
}
/*

View File

@@ -162,7 +162,7 @@ static void _MPCI_Create_server( void )
memset( &config, 0, sizeof( config ) );
config.scheduler = &_Scheduler_Table[ 0 ];
config.name = _Objects_Build_name( 'M', 'P', 'C', 'I' );
config.priority = PRIORITY_PSEUDO_ISR;
config.priority = PRIORITY_MINIMUM;
config.is_fp = CPU_ALL_TASKS_ARE_FP;
config.stack_size = _Stack_Minimum()
+ _MPCI_Configuration.extra_mpci_receive_server_stack

View File

@@ -47,11 +47,11 @@ void _Scheduler_EDF_Block(
Scheduler_Node *node
)
{
_Scheduler_Generic_block(
_Scheduler_uniprocessor_Block(
scheduler,
the_thread,
node,
_Scheduler_EDF_Extract_body,
_Scheduler_EDF_Schedule_body
_Scheduler_EDF_Get_highest_ready
);
}

View File

@@ -71,5 +71,8 @@ void _Scheduler_EDF_Update_priority(
_Scheduler_EDF_Extract( context, the_node );
_Scheduler_EDF_Enqueue( context, the_node, insert_priority );
_Scheduler_EDF_Schedule_body( scheduler, the_thread, false );
_Scheduler_uniprocessor_Schedule(
scheduler,
_Scheduler_EDF_Get_highest_ready
);
}

View File

@@ -46,5 +46,8 @@ void _Scheduler_EDF_Schedule(
Thread_Control *the_thread
)
{
_Scheduler_EDF_Schedule_body( scheduler, the_thread, false );
_Scheduler_uniprocessor_Schedule(
scheduler,
_Scheduler_EDF_Get_highest_ready
);
}

View File

@@ -62,23 +62,5 @@ void _Scheduler_EDF_Unblock(
the_node->priority = priority;
_Scheduler_EDF_Enqueue( context, the_node, insert_priority );
/*
* If the thread that was unblocked is more important than the heir,
* then we have a new heir. This may or may not result in a
* context switch.
*
* Normal case:
* If the current thread is preemptible, then we need to do
* a context switch.
* Pseudo-ISR case:
* Even if the thread isn't preemptible, if the new heir is
* a pseudo-ISR system task, we need to do a context switch.
*/
if ( priority < _Thread_Get_priority( _Thread_Heir ) ) {
_Scheduler_Update_heir(
the_thread,
priority == ( SCHEDULER_EDF_PRIO_MSB | PRIORITY_PSEUDO_ISR )
);
}
_Scheduler_uniprocessor_Unblock( scheduler, the_thread, priority );
}

View File

@@ -55,5 +55,5 @@ void _Scheduler_EDF_Yield(
_Scheduler_EDF_Extract( context, the_node );
_Scheduler_EDF_Enqueue( context, the_node, the_node->priority );
_Scheduler_EDF_Schedule_body( scheduler, the_thread, true );
_Scheduler_uniprocessor_Yield( scheduler, _Scheduler_EDF_Get_highest_ready );
}

View File

@@ -49,11 +49,11 @@ void _Scheduler_priority_Block(
Scheduler_Node *node
)
{
_Scheduler_Generic_block(
_Scheduler_uniprocessor_Block(
scheduler,
the_thread,
node,
_Scheduler_priority_Extract_body,
_Scheduler_priority_Schedule_body
_Scheduler_priority_Get_highest_ready
);
}

View File

@@ -96,5 +96,8 @@ void _Scheduler_priority_Update_priority(
);
}
_Scheduler_priority_Schedule_body( scheduler, the_thread, false );
_Scheduler_uniprocessor_Schedule(
scheduler,
_Scheduler_priority_Get_highest_ready
);
}

View File

@@ -46,5 +46,8 @@ void _Scheduler_priority_Schedule(
Thread_Control *the_thread
)
{
_Scheduler_priority_Schedule_body( scheduler, the_thread, false );
_Scheduler_uniprocessor_Schedule(
scheduler,
_Scheduler_priority_Get_highest_ready
);
}

View File

@@ -76,19 +76,5 @@ void _Scheduler_priority_Unblock (
/* TODO: flash critical section? */
/*
* If the thread that was unblocked is more important than the heir,
* then we have a new heir. This may or may not result in a
* context switch.
*
* Normal case:
* If the current thread is preemptible, then we need to do
* a context switch.
* Pseudo-ISR case:
* Even if the thread isn't preemptible, if the new heir is
* a pseudo-ISR system task, we need to do a context switch.
*/
if ( priority < _Thread_Get_priority( _Thread_Heir ) ) {
_Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
}
_Scheduler_uniprocessor_Unblock( scheduler, the_thread, priority );
}

View File

@@ -59,5 +59,8 @@ void _Scheduler_priority_Yield(
_Chain_Append_unprotected( ready_chain, &the_thread->Object.Node );
}
_Scheduler_priority_Schedule_body( scheduler, the_thread, true );
_Scheduler_uniprocessor_Yield(
scheduler,
_Scheduler_priority_Get_highest_ready
);
}

View File

@@ -47,11 +47,11 @@ void _Scheduler_simple_Block(
Scheduler_Node *node
)
{
_Scheduler_Generic_block(
_Scheduler_uniprocessor_Block(
scheduler,
the_thread,
node,
_Scheduler_simple_Extract,
_Scheduler_simple_Schedule_body
_Scheduler_simple_Get_highest_ready
);
}

View File

@@ -60,5 +60,8 @@ void _Scheduler_simple_Update_priority(
_Scheduler_simple_Extract( scheduler, the_thread, node );
_Scheduler_simple_Insert( &context->Ready, the_thread, new_priority );
_Scheduler_simple_Schedule_body( scheduler, the_thread, false );
_Scheduler_uniprocessor_Schedule(
scheduler,
_Scheduler_simple_Get_highest_ready
);
}

View File

@@ -46,5 +46,8 @@ void _Scheduler_simple_Schedule(
Thread_Control *the_thread
)
{
_Scheduler_simple_Schedule_body( scheduler, the_thread, false );
_Scheduler_uniprocessor_Schedule(
scheduler,
_Scheduler_simple_Get_highest_ready
);
}

View File

@@ -58,23 +58,5 @@ void _Scheduler_simple_Unblock(
priority = _Thread_Get_priority( the_thread );
insert_priority = SCHEDULER_PRIORITY_APPEND( priority );
_Scheduler_simple_Insert( &context->Ready, the_thread, insert_priority );
/*
* If the thread that was unblocked is more important than the heir,
* then we have a new heir. This may or may not result in a
* context switch.
*
* Normal case:
* If the current thread is preemptible, then we need to do
* a context switch.
* Pseudo-ISR case:
* Even if the thread isn't preemptible, if the new heir is
* a pseudo-ISR system task, we need to do a context switch.
*/
if ( priority < _Thread_Get_priority( _Thread_Heir ) ) {
_Scheduler_Update_heir(
the_thread,
priority == PRIORITY_PSEUDO_ISR
);
}
_Scheduler_uniprocessor_Unblock( scheduler, the_thread, priority );
}

View File

@@ -58,5 +58,8 @@ void _Scheduler_simple_Yield(
insert_priority = (unsigned int) _Thread_Get_priority( the_thread );
insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
_Scheduler_simple_Insert( &context->Ready, the_thread, insert_priority );
_Scheduler_simple_Schedule_body( scheduler, the_thread, false );
_Scheduler_uniprocessor_Yield(
scheduler,
_Scheduler_simple_Get_highest_ready
);
}

View File

@@ -396,6 +396,7 @@ install:
- cpukit/include/rtems/score/schedulersmp.h
- cpukit/include/rtems/score/schedulersmpimpl.h
- cpukit/include/rtems/score/schedulerstrongapa.h
- cpukit/include/rtems/score/scheduleruniimpl.h
- cpukit/include/rtems/score/semaphoreimpl.h
- cpukit/include/rtems/score/smp.h
- cpukit/include/rtems/score/smpbarrier.h

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
* Copyright (C) 2015, 2022 embedded brains GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,12 +37,7 @@ static bool did_run;
static void do_not_run(rtems_task_argument arg)
{
#if 0
rtems_test_assert(0);
#else
did_run = true;
rtems_task_suspend(RTEMS_SELF);
#endif
}
static void test(void)
@@ -64,9 +59,9 @@ static void test(void)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
/*
* This will start a pseudo interrupt task pre-empting the non-preemtive
* executing task. Later the high priority do_not_run() task is scheduled.
* See also https://devel.rtems.org/ticket/2365.
* This will start a task with a priority of PRIORITY_MINIMUM. Check that
* this task and the test task did not preempt the current task. See also
* https://devel.rtems.org/ticket/2365.
*/
sc = rtems_timer_initiate_server(
RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
@@ -75,8 +70,7 @@ static void test(void)
);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
/* This is probably a bug and not a feature */
rtems_test_assert(did_run);
rtems_test_assert(!did_run);
sc = rtems_task_delete(task);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
@@ -99,6 +93,8 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_INIT_TASK_PRIORITY 2
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_NO_PREEMPT
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE