summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2022-07-15 09:16:04 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2022-07-26 11:26:22 +0200
commit7fe6d60bf08df975c395515074c85976d9e4e3fb (patch)
treeb61a7a72f1c0d763c9fdfadd8275789b1a7de55b
parentsptests/spstdc17: New test (diff)
downloadrtems-7fe6d60bf08df975c395515074c85976d9e4e3fb.tar.bz2
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.
Diffstat (limited to '')
-rw-r--r--cpukit/include/rtems/posix/priorityimpl.h2
-rw-r--r--cpukit/include/rtems/score/priority.h7
-rw-r--r--cpukit/include/rtems/score/scheduleredfimpl.h19
-rw-r--r--cpukit/include/rtems/score/schedulerimpl.h65
-rw-r--r--cpukit/include/rtems/score/schedulerpriorityimpl.h30
-rw-r--r--cpukit/include/rtems/score/schedulersimpleimpl.h22
-rw-r--r--cpukit/include/rtems/score/scheduleruniimpl.h221
-rw-r--r--cpukit/rtems/src/timerserver.c2
-rw-r--r--cpukit/score/src/mpci.c2
-rw-r--r--cpukit/score/src/scheduleredfblock.c4
-rw-r--r--cpukit/score/src/scheduleredfchangepriority.c5
-rw-r--r--cpukit/score/src/scheduleredfschedule.c5
-rw-r--r--cpukit/score/src/scheduleredfunblock.c20
-rw-r--r--cpukit/score/src/scheduleredfyield.c2
-rw-r--r--cpukit/score/src/schedulerpriorityblock.c4
-rw-r--r--cpukit/score/src/schedulerprioritychangepriority.c5
-rw-r--r--cpukit/score/src/schedulerpriorityschedule.c5
-rw-r--r--cpukit/score/src/schedulerpriorityunblock.c16
-rw-r--r--cpukit/score/src/schedulerpriorityyield.c5
-rw-r--r--cpukit/score/src/schedulersimpleblock.c4
-rw-r--r--cpukit/score/src/schedulersimplechangepriority.c5
-rw-r--r--cpukit/score/src/schedulersimpleschedule.c5
-rw-r--r--cpukit/score/src/schedulersimpleunblock.c20
-rw-r--r--cpukit/score/src/schedulersimpleyield.c5
-rw-r--r--spec/build/cpukit/librtemscpu.yml1
-rw-r--r--testsuites/sptests/sptasknopreempt01/init.c18
26 files changed, 295 insertions, 204 deletions
diff --git a/cpukit/include/rtems/posix/priorityimpl.h b/cpukit/include/rtems/posix/priorityimpl.h
index e391448372..ce26787294 100644
--- a/cpukit/include/rtems/posix/priorityimpl.h
+++ b/cpukit/include/rtems/posix/priorityimpl.h
@@ -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
diff --git a/cpukit/include/rtems/score/priority.h b/cpukit/include/rtems/score/priority.h
index 568e3c4e3e..6f6cc12bac 100644
--- a/cpukit/include/rtems/score/priority.h
+++ b/cpukit/include/rtems/score/priority.h
@@ -96,13 +96,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.
*
* This value is CPU port dependent.
diff --git a/cpukit/include/rtems/score/scheduleredfimpl.h b/cpukit/include/rtems/score/scheduleredfimpl.h
index e0a07a8915..06a35ae95f 100644
--- a/cpukit/include/rtems/score/scheduleredfimpl.h
+++ b/cpukit/include/rtems/score/scheduleredfimpl.h
@@ -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;
}
/** @} */
diff --git a/cpukit/include/rtems/score/schedulerimpl.h b/cpukit/include/rtems/score/schedulerimpl.h
index 806cb4e145..33070651db 100644
--- a/cpukit/include/rtems/score/schedulerimpl.h
+++ b/cpukit/include/rtems/score/schedulerimpl.h
@@ -669,40 +669,6 @@ Status_Control _Scheduler_Set_affinity(
);
/**
- * @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.
*
* @param scheduler The scheduler instance to get the number of processors of.
@@ -952,37 +918,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.
*
* @param new_scheduler The new scheduler to set.
diff --git a/cpukit/include/rtems/score/schedulerpriorityimpl.h b/cpukit/include/rtems/score/schedulerpriorityimpl.h
index d8d226d6f1..06d2027a45 100644
--- a/cpukit/include/rtems/score/schedulerpriorityimpl.h
+++ b/cpukit/include/rtems/score/schedulerpriorityimpl.h
@@ -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 ]
+ );
}
/**
diff --git a/cpukit/include/rtems/score/schedulersimpleimpl.h b/cpukit/include/rtems/score/schedulersimpleimpl.h
index 2aaf0fe17e..2293433870 100644
--- a/cpukit/include/rtems/score/schedulersimpleimpl.h
+++ b/cpukit/include/rtems/score/schedulersimpleimpl.h
@@ -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 );
}
/** @} */
diff --git a/cpukit/include/rtems/score/scheduleruniimpl.h b/cpukit/include/rtems/score/scheduleruniimpl.h
new file mode 100644
index 0000000000..faa719ce45
--- /dev/null
+++ b/cpukit/include/rtems/score/scheduleruniimpl.h
@@ -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 */
diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
index 5d863bd79c..e5242c82a5 100644
--- a/cpukit/rtems/src/timerserver.c
+++ b/cpukit/rtems/src/timerserver.c
@@ -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;
}
/*
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index 3b525a2066..458031c794 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -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
diff --git a/cpukit/score/src/scheduleredfblock.c b/cpukit/score/src/scheduleredfblock.c
index 56f7c9c021..cb7ab91450 100644
--- a/cpukit/score/src/scheduleredfblock.c
+++ b/cpukit/score/src/scheduleredfblock.c
@@ -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
);
}
diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c
index 26ce1c348f..de17ca0fad 100644
--- a/cpukit/score/src/scheduleredfchangepriority.c
+++ b/cpukit/score/src/scheduleredfchangepriority.c
@@ -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
+ );
}
diff --git a/cpukit/score/src/scheduleredfschedule.c b/cpukit/score/src/scheduleredfschedule.c
index d0acea7a30..40c5ab2c06 100644
--- a/cpukit/score/src/scheduleredfschedule.c
+++ b/cpukit/score/src/scheduleredfschedule.c
@@ -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
+ );
}
diff --git a/cpukit/score/src/scheduleredfunblock.c b/cpukit/score/src/scheduleredfunblock.c
index d6604686e3..4638eedf71 100644
--- a/cpukit/score/src/scheduleredfunblock.c
+++ b/cpukit/score/src/scheduleredfunblock.c
@@ -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 );
}
diff --git a/cpukit/score/src/scheduleredfyield.c b/cpukit/score/src/scheduleredfyield.c
index d83e1d9268..d38bea705a 100644
--- a/cpukit/score/src/scheduleredfyield.c
+++ b/cpukit/score/src/scheduleredfyield.c
@@ -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 );
}
diff --git a/cpukit/score/src/schedulerpriorityblock.c b/cpukit/score/src/schedulerpriorityblock.c
index 53636940dc..ffc7a3ad86 100644
--- a/cpukit/score/src/schedulerpriorityblock.c
+++ b/cpukit/score/src/schedulerpriorityblock.c
@@ -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
);
}
diff --git a/cpukit/score/src/schedulerprioritychangepriority.c b/cpukit/score/src/schedulerprioritychangepriority.c
index 8a059763de..3588a2ce42 100644
--- a/cpukit/score/src/schedulerprioritychangepriority.c
+++ b/cpukit/score/src/schedulerprioritychangepriority.c
@@ -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
+ );
}
diff --git a/cpukit/score/src/schedulerpriorityschedule.c b/cpukit/score/src/schedulerpriorityschedule.c
index bde749f9bc..bb7cf87399 100644
--- a/cpukit/score/src/schedulerpriorityschedule.c
+++ b/cpukit/score/src/schedulerpriorityschedule.c
@@ -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
+ );
}
diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c
index 190c126908..f9b6cabff7 100644
--- a/cpukit/score/src/schedulerpriorityunblock.c
+++ b/cpukit/score/src/schedulerpriorityunblock.c
@@ -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 );
}
diff --git a/cpukit/score/src/schedulerpriorityyield.c b/cpukit/score/src/schedulerpriorityyield.c
index 77fcecc418..adb443df94 100644
--- a/cpukit/score/src/schedulerpriorityyield.c
+++ b/cpukit/score/src/schedulerpriorityyield.c
@@ -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
+ );
}
diff --git a/cpukit/score/src/schedulersimpleblock.c b/cpukit/score/src/schedulersimpleblock.c
index a8229d409f..dfd18df3a2 100644
--- a/cpukit/score/src/schedulersimpleblock.c
+++ b/cpukit/score/src/schedulersimpleblock.c
@@ -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
);
}
diff --git a/cpukit/score/src/schedulersimplechangepriority.c b/cpukit/score/src/schedulersimplechangepriority.c
index b4711dfd01..5c53c96fb3 100644
--- a/cpukit/score/src/schedulersimplechangepriority.c
+++ b/cpukit/score/src/schedulersimplechangepriority.c
@@ -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
+ );
}
diff --git a/cpukit/score/src/schedulersimpleschedule.c b/cpukit/score/src/schedulersimpleschedule.c
index 4108fdaee8..83a3fed7fe 100644
--- a/cpukit/score/src/schedulersimpleschedule.c
+++ b/cpukit/score/src/schedulersimpleschedule.c
@@ -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
+ );
}
diff --git a/cpukit/score/src/schedulersimpleunblock.c b/cpukit/score/src/schedulersimpleunblock.c
index 7791503d7a..436f20ac38 100644
--- a/cpukit/score/src/schedulersimpleunblock.c
+++ b/cpukit/score/src/schedulersimpleunblock.c
@@ -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 );
}
diff --git a/cpukit/score/src/schedulersimpleyield.c b/cpukit/score/src/schedulersimpleyield.c
index c25cceb8a7..ed8dd5b4cc 100644
--- a/cpukit/score/src/schedulersimpleyield.c
+++ b/cpukit/score/src/schedulersimpleyield.c
@@ -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
+ );
}
diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml
index 596bf5e4e3..e8a9da3e50 100644
--- a/spec/build/cpukit/librtemscpu.yml
+++ b/spec/build/cpukit/librtemscpu.yml
@@ -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
diff --git a/testsuites/sptests/sptasknopreempt01/init.c b/testsuites/sptests/sptasknopreempt01/init.c
index 617a44ade1..d92bd245e7 100644
--- a/testsuites/sptests/sptasknopreempt01/init.c
+++ b/testsuites/sptests/sptasknopreempt01/init.c
@@ -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