summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/score
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 /cpukit/include/rtems/score
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 'cpukit/include/rtems/score')
-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
6 files changed, 242 insertions, 122 deletions
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 */