forked from Imagelibrary/rtems
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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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 ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
221
cpukit/include/rtems/score/scheduleruniimpl.h
Normal file
221
cpukit/include/rtems/score/scheduleruniimpl.h
Normal 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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user