summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/score/Makefile.am1
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h2
-rw-r--r--cpukit/score/include/rtems/score/scheduleredf.h2
-rw-r--r--cpukit/score/include/rtems/score/scheduleredfimpl.h56
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h35
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityimpl.h12
-rw-r--r--cpukit/score/include/rtems/score/schedulersimple.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulersimpleimpl.h16
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h2
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h10
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/scheduleredfblock.c17
-rw-r--r--cpukit/score/src/scheduleredfschedule.c12
-rw-r--r--cpukit/score/src/scheduleredfyield.c9
-rw-r--r--cpukit/score/src/schedulerpriorityblock.c16
-rw-r--r--cpukit/score/src/schedulerpriorityschedule.c4
-rw-r--r--cpukit/score/src/schedulersimpleblock.c15
-rw-r--r--cpukit/score/src/schedulersimpleschedule.c9
-rw-r--r--cpukit/score/src/schedulersimplesmp.c4
-rw-r--r--cpukit/score/src/schedulersimpleyield.c5
-rw-r--r--cpukit/score/src/threadchangepriority.c14
22 files changed, 164 insertions, 85 deletions
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 7cde82cf92..a725ffcba1 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -50,6 +50,7 @@ include_rtems_score_HEADERS += include/rtems/score/scheduler.h
include_rtems_score_HEADERS += include/rtems/score/schedulerimpl.h
include_rtems_score_HEADERS += include/rtems/score/schedulercbs.h
include_rtems_score_HEADERS += include/rtems/score/scheduleredf.h
+include_rtems_score_HEADERS += include/rtems/score/scheduleredfimpl.h
include_rtems_score_HEADERS += include/rtems/score/schedulerpriority.h
include_rtems_score_HEADERS += include/rtems/score/schedulerpriorityimpl.h
include_rtems_score_HEADERS += include/rtems/score/schedulersimple.h
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index a34387d8c7..10a2a974af 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -46,7 +46,7 @@ typedef struct {
void ( *initialize )(void);
/** Implements the scheduling decision logic (policy). */
- void ( *schedule )(void);
+ void ( *schedule )( Thread_Control *thread );
/**
* @brief Voluntarily yields the processor per the scheduling policy.
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index b28bed1363..01f91e6c26 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -129,7 +129,7 @@ void _Scheduler_EDF_Block(
* This kernel routine sets the heir thread to be the next ready thread
* in the rbtree ready queue.
*/
-void _Scheduler_EDF_Schedule( void );
+void _Scheduler_EDF_Schedule( Thread_Control *thread );
/**
* @brief Allocates EDF specific information of @a the_thread.
diff --git a/cpukit/score/include/rtems/score/scheduleredfimpl.h b/cpukit/score/include/rtems/score/scheduleredfimpl.h
new file mode 100644
index 0000000000..04201bcdfc
--- /dev/null
+++ b/cpukit/score/include/rtems/score/scheduleredfimpl.h
@@ -0,0 +1,56 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerEDF
+ *
+ * @brief EDF Scheduler Implementation
+ */
+
+/*
+ * Copryight (c) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULEREDFIMPL_H
+#define _RTEMS_SCORE_SCHEDULEREDFIMPL_H
+
+#include <rtems/score/scheduleredf.h>
+#include <rtems/score/schedulerimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSchedulerEDF EDF
+ *
+ * @{
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
+ Thread_Control *thread,
+ bool force_dispatch
+)
+{
+ RBTree_Node *first = _RBTree_First(&_Scheduler_EDF_Ready_queue, RBT_LEFT);
+ Scheduler_EDF_Per_thread *sched_info =
+ _RBTree_Container_of(first, Scheduler_EDF_Per_thread, Node);
+ Thread_Control *heir = (Thread_Control *) sched_info->thread;
+
+ ( void ) thread;
+
+ _Scheduler_Update_heir( heir, force_dispatch );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 5ea4bb8b74..2d9957a62a 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -20,6 +20,7 @@
#define _RTEMS_SCORE_SCHEDULERIMPL_H
#include <rtems/score/scheduler.h>
+#include <rtems/score/threadimpl.h>
#ifdef __cplusplus
extern "C" {
@@ -59,10 +60,12 @@ void _Scheduler_Handler_initialization( void );
*
* This kernel routine implements the scheduling decision logic for
* the scheduler. It does NOT dispatch.
+ *
+ * @param[in] thread The thread which state changed previously.
*/
-RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( void )
+RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *thread )
{
- _Scheduler.Operations.schedule();
+ _Scheduler.Operations.schedule( thread );
}
/**
@@ -237,6 +240,34 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Start_idle(
( *_Scheduler.Operations.start_idle )( thread, processor );
}
+RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir(
+ Thread_Control *heir,
+ bool force_dispatch
+)
+{
+ Thread_Control *executing = _Thread_Executing;
+
+ _Thread_Heir = heir;
+
+ if ( executing != heir && ( force_dispatch || executing->is_preemptible ) )
+ _Thread_Dispatch_necessary = true;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Generic_block(
+ void ( *extract )( Thread_Control *thread ),
+ void ( *schedule )( Thread_Control *thread, bool force_dispatch ),
+ Thread_Control *thread
+)
+{
+ ( *extract )( thread );
+
+ /* TODO: flash critical section? */
+
+ if ( _Thread_Is_executing( thread ) || _Thread_Is_heir( thread ) ) {
+ ( *schedule )( thread, true );
+ }
+}
+
/**
* Macro testing whether @a p1 has lower priority than @a p2
* in the intuitive sense of priority.
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 69649435bd..cbe0066d8d 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -93,7 +93,7 @@ void _Scheduler_priority_Block(
* This kernel routine sets the heir thread to be the next ready thread
* by invoking the_scheduler->ready_queue->operations->first().
*/
-void _Scheduler_priority_Schedule(void);
+void _Scheduler_priority_Schedule( Thread_Control *thread );
/**
* @brief Allocates @a the_thread->scheduler.
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
index 8a8917ca1b..73c635dced 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
@@ -23,6 +23,7 @@
#include <rtems/score/schedulerpriority.h>
#include <rtems/score/chainimpl.h>
#include <rtems/score/prioritybitmapimpl.h>
+#include <rtems/score/schedulerimpl.h>
#include <rtems/score/thread.h>
#include <rtems/score/wkspace.h>
@@ -182,11 +183,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_requeue(
* This kernel routine implements scheduling decision logic
* for priority-based scheduling.
*/
-RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(void)
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
+ Thread_Control *thread,
+ bool force_dispatch
+)
{
- _Thread_Heir = _Scheduler_priority_Ready_queue_first(
+ Thread_Control *heir = _Scheduler_priority_Ready_queue_first(
(Chain_Control *) _Scheduler.information
);
+
+ ( void ) thread;
+
+ _Scheduler_Update_heir( heir, force_dispatch );
}
/**
diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
index 5180d36087..477ea2c026 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -66,7 +66,7 @@ void _Scheduler_simple_Initialize( void );
* on the ready queue by getting the first node in the scheduler
* information.
*/
-void _Scheduler_simple_Schedule( void );
+void _Scheduler_simple_Schedule( Thread_Control *thread );
/**
* @brief Invoked when a thread wishes to voluntarily
diff --git a/cpukit/score/include/rtems/score/schedulersimpleimpl.h b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
index 076d1a9258..51d37741b1 100644
--- a/cpukit/score/include/rtems/score/schedulersimpleimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
@@ -21,7 +21,7 @@
#include <rtems/score/schedulersimple.h>
#include <rtems/score/chainimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/schedulerimpl.h>
#ifdef __cplusplus
extern "C" {
@@ -96,6 +96,20 @@ RTEMS_INLINE_ROUTINE void _Scheduler_simple_Insert_priority_fifo(
);
}
+RTEMS_INLINE_ROUTINE void _Scheduler_simple_Schedule_body(
+ Thread_Control *thread,
+ bool force_dispatch
+)
+{
+ Thread_Control *heir = (Thread_Control *) _Chain_First(
+ (Chain_Control *) _Scheduler.information
+ );
+
+ ( void ) thread;
+
+ _Scheduler_Update_heir( heir, force_dispatch );
+}
+
/** @} */
#ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index 1b827cbabe..6cc87f3dec 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -85,7 +85,7 @@ void _Scheduler_simple_smp_Extract( Thread_Control *thread );
void _Scheduler_simple_smp_Yield( Thread_Control *thread );
-void _Scheduler_simple_smp_Schedule( void );
+void _Scheduler_simple_smp_Schedule( Thread_Control *thread );
void _Scheduler_simple_smp_Start_idle(
Thread_Control *thread,
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 717f00b4e8..e07b39266d 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -498,16 +498,6 @@ RTEMS_INLINE_ROUTINE bool _Thread_Is_heir (
}
/**
- * This function returns true if the currently executing thread
- * is also the heir thread, and false otherwise.
- */
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_also_the_heir( void )
-{
- return ( _Thread_Executing == _Thread_Heir );
-}
-
-/**
* This routine clears any blocking state for the_thread. It performs
* any necessary scheduling operations including the selection of
* a new heir thread.
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 80fad5b97e..14d873ce4c 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -183,6 +183,10 @@ $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h: include/rtems/score/scheduleredf.
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h
+$(PROJECT_INCLUDE)/rtems/score/scheduleredfimpl.h: include/rtems/score/scheduleredfimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduleredfimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduleredfimpl.h
+
$(PROJECT_INCLUDE)/rtems/score/schedulerpriority.h: include/rtems/score/schedulerpriority.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.h
diff --git a/cpukit/score/src/scheduleredfblock.c b/cpukit/score/src/scheduleredfblock.c
index 4ad767d7bf..80bb1d5549 100644
--- a/cpukit/score/src/scheduleredfblock.c
+++ b/cpukit/score/src/scheduleredfblock.c
@@ -19,20 +19,15 @@
#include "config.h"
#endif
-#include <rtems/score/scheduleredf.h>
-#include <rtems/score/threadimpl.h>
+#include <rtems/score/scheduleredfimpl.h>
void _Scheduler_EDF_Block(
Thread_Control *the_thread
)
{
- _Scheduler_EDF_Extract( the_thread );
-
- /* TODO: flash critical section? */
-
- if ( _Thread_Is_heir( the_thread ) )
- _Scheduler_EDF_Schedule();
-
- if ( _Thread_Is_executing( the_thread ) )
- _Thread_Dispatch_necessary = true;
+ _Scheduler_Generic_block(
+ _Scheduler_EDF_Extract,
+ _Scheduler_EDF_Schedule_body,
+ the_thread
+ );
}
diff --git a/cpukit/score/src/scheduleredfschedule.c b/cpukit/score/src/scheduleredfschedule.c
index dbe21dc491..a71a5b52ba 100644
--- a/cpukit/score/src/scheduleredfschedule.c
+++ b/cpukit/score/src/scheduleredfschedule.c
@@ -18,15 +18,9 @@
#include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/score/scheduler.h>
-#include <rtems/score/scheduleredf.h>
+#include <rtems/score/scheduleredfimpl.h>
-void _Scheduler_EDF_Schedule(void)
+void _Scheduler_EDF_Schedule( Thread_Control *thread )
{
- RBTree_Node *first = _RBTree_First(&_Scheduler_EDF_Ready_queue, RBT_LEFT);
- Scheduler_EDF_Per_thread *sched_info =
- _RBTree_Container_of(first, Scheduler_EDF_Per_thread, Node);
-
- _Thread_Heir = (Thread_Control *) sched_info->thread;
+ _Scheduler_EDF_Schedule_body( thread, false );
}
diff --git a/cpukit/score/src/scheduleredfyield.c b/cpukit/score/src/scheduleredfyield.c
index 4ba9f79b77..fc5b13a7a0 100644
--- a/cpukit/score/src/scheduleredfyield.c
+++ b/cpukit/score/src/scheduleredfyield.c
@@ -19,11 +19,7 @@
#include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/score/isr.h>
-#include <rtems/score/scheduler.h>
-#include <rtems/score/scheduleredf.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/scheduleredfimpl.h>
void _Scheduler_EDF_Yield( Thread_Control *thread )
{
@@ -44,8 +40,7 @@ void _Scheduler_EDF_Yield( Thread_Control *thread )
_ISR_Flash( level );
- _Scheduler_EDF_Schedule();
- _Thread_Dispatch_necessary = true;
+ _Scheduler_EDF_Schedule_body( thread, false );
_ISR_Enable( level );
}
diff --git a/cpukit/score/src/schedulerpriorityblock.c b/cpukit/score/src/schedulerpriorityblock.c
index 9e48101f9e..329ddd7bda 100644
--- a/cpukit/score/src/schedulerpriorityblock.c
+++ b/cpukit/score/src/schedulerpriorityblock.c
@@ -21,20 +21,14 @@
#endif
#include <rtems/score/schedulerpriorityimpl.h>
-#include <rtems/score/threadimpl.h>
void _Scheduler_priority_Block(
Thread_Control *the_thread
)
{
- _Scheduler_priority_Ready_queue_extract( the_thread );
-
- /* TODO: flash critical section? */
-
- if ( _Thread_Is_heir( the_thread ) )
- _Scheduler_priority_Schedule_body();
-
- if ( _Thread_Is_executing( the_thread ) )
- _Thread_Dispatch_necessary = true;
-
+ _Scheduler_Generic_block(
+ _Scheduler_priority_Ready_queue_extract,
+ _Scheduler_priority_Schedule_body,
+ the_thread
+ );
}
diff --git a/cpukit/score/src/schedulerpriorityschedule.c b/cpukit/score/src/schedulerpriorityschedule.c
index 22ed5f403c..42647e617b 100644
--- a/cpukit/score/src/schedulerpriorityschedule.c
+++ b/cpukit/score/src/schedulerpriorityschedule.c
@@ -20,7 +20,7 @@
#include <rtems/score/schedulerpriorityimpl.h>
-void _Scheduler_priority_Schedule(void)
+void _Scheduler_priority_Schedule( Thread_Control *thread )
{
- _Scheduler_priority_Schedule_body();
+ _Scheduler_priority_Schedule_body( thread, false );
}
diff --git a/cpukit/score/src/schedulersimpleblock.c b/cpukit/score/src/schedulersimpleblock.c
index b9753b5954..1e6e8a0b47 100644
--- a/cpukit/score/src/schedulersimpleblock.c
+++ b/cpukit/score/src/schedulersimpleblock.c
@@ -19,18 +19,15 @@
#include "config.h"
#endif
-#include <rtems/score/schedulersimple.h>
-#include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulersimpleimpl.h>
void _Scheduler_simple_Block(
Thread_Control *the_thread
)
{
- _Scheduler_simple_Extract(the_thread);
-
- if ( _Thread_Is_heir( the_thread ) )
- _Scheduler_simple_Schedule();
-
- if ( _Thread_Is_executing( the_thread ) )
- _Thread_Dispatch_necessary = true;
+ _Scheduler_Generic_block(
+ _Scheduler_simple_Extract,
+ _Scheduler_simple_Schedule_body,
+ the_thread
+ );
}
diff --git a/cpukit/score/src/schedulersimpleschedule.c b/cpukit/score/src/schedulersimpleschedule.c
index b60f096b09..5018e0b638 100644
--- a/cpukit/score/src/schedulersimpleschedule.c
+++ b/cpukit/score/src/schedulersimpleschedule.c
@@ -18,12 +18,9 @@
#include "config.h"
#endif
-#include <rtems/score/schedulersimple.h>
-#include <rtems/score/chainimpl.h>
+#include <rtems/score/schedulersimpleimpl.h>
-void _Scheduler_simple_Schedule(void)
+void _Scheduler_simple_Schedule( Thread_Control *thread )
{
- _Thread_Heir = (Thread_Control *) _Chain_First(
- (Chain_Control *) _Scheduler.information
- );
+ _Scheduler_simple_Schedule_body( thread, false );
}
diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
index db08b96ab3..e26151025c 100644
--- a/cpukit/score/src/schedulersimplesmp.c
+++ b/cpukit/score/src/schedulersimplesmp.c
@@ -182,9 +182,9 @@ void _Scheduler_simple_smp_Yield( Thread_Control *thread )
_ISR_Enable( level );
}
-void _Scheduler_simple_smp_Schedule( void )
+void _Scheduler_simple_smp_Schedule( Thread_Control *thread )
{
- /* Nothing to do */
+ ( void ) thread;
}
void _Scheduler_simple_smp_Start_idle(
diff --git a/cpukit/score/src/schedulersimpleyield.c b/cpukit/score/src/schedulersimpleyield.c
index cb8dc6fc92..43784d65f9 100644
--- a/cpukit/score/src/schedulersimpleyield.c
+++ b/cpukit/score/src/schedulersimpleyield.c
@@ -32,10 +32,7 @@ void _Scheduler_simple_Yield( Thread_Control *thread )
_ISR_Flash( level );
- _Scheduler_simple_Schedule();
-
- if ( !_Thread_Is_heir( thread ) )
- _Thread_Dispatch_necessary = true;
+ _Scheduler_simple_Schedule_body( thread, false );
_ISR_Enable( level );
}
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index b4437313a7..b3d79844c2 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -62,6 +62,15 @@ void _Thread_Change_priority(
/* Only clear the transient state if it wasn't set already */
if ( ! _States_Is_transient( original_state ) )
the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
+
+ /*
+ * The thread may have new blocking states added by interrupt service
+ * routines after the change into the transient state. This will not
+ * result in a _Scheduler_Block() operation. Make sure we select an heir
+ * now.
+ */
+ _Scheduler_Schedule( the_thread );
+
_ISR_Enable( level );
if ( _States_Is_waiting_on_thread_queue( state ) ) {
_Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
@@ -91,10 +100,7 @@ void _Thread_Change_priority(
* We altered the set of thread priorities. So let's figure out
* who is the heir and if we need to switch to them.
*/
- _Scheduler_Schedule();
+ _Scheduler_Schedule( the_thread );
- if ( !_Thread_Is_executing_also_the_heir() &&
- _Thread_Executing->is_preemptible )
- _Thread_Dispatch_necessary = true;
_ISR_Enable( level );
}