summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2010-11-24 15:51:28 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2010-11-24 15:51:28 +0000
commit0faa9dad0768f0291cb44d8d0dcb74fd3f362cc2 (patch)
tree5fdf3fb63a7b901897891cf25b3958c9a750ed69 /cpukit
parentRemove duplicate entry. (diff)
downloadrtems-0faa9dad0768f0291cb44d8d0dcb74fd3f362cc2.tar.bz2
2010-11-24 Gedare Bloom <giddyup44@yahoo.com>
PR 1647/cpukit * posix/src/nanosleep.c, posix/src/sched_yield.c, rtems/src/taskwakeafter.c, sapi/include/confdefs.h, sapi/include/rtems/config.h, sapi/src/exinit.c, score/Makefile.am, score/preinstall.am, score/include/rtems/score/prioritybitmap.h, score/include/rtems/score/thread.h, score/inline/rtems/score/thread.inl, score/src/thread.c, score/src/threadchangepriority.c, score/src/threadclearstate.c, score/src/threadclose.c, score/src/threadinitialize.c, score/src/threadready.c, score/src/threadresume.c, score/src/threadsetpriority.c, score/src/threadsetstate.c, score/src/threadsettransient.c, score/src/threadsuspend.c, score/src/threadtickletimeslice.c: Refactor scheduler out of thread handler to facilitate alternate scheduler implementations. * score/src/threadyieldprocessor.c: Removed. * score/src/schedulerprioritythreadschedulerupdate.c, score/src/schedulerprioritythreadschedulerfree.c, score/src/schedulerpriorityblock.c, score/src/scheduler.c, score/src/schedulerprioritythreadschedulerallocate.c, score/src/schedulerpriorityunblock.c, score/src/schedulerpriority.c, score/src/schedulerpriorityyield.c, score/include/rtems/score/schedulerpriority.h, score/include/rtems/score/scheduler.h, score/inline/rtems/score/scheduler.inl, score/inline/rtems/score/schedulerpriority.inl: New files.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/ChangeLog28
-rw-r--r--cpukit/posix/src/nanosleep.c3
-rw-r--r--cpukit/posix/src/sched_yield.c3
-rw-r--r--cpukit/rtems/src/taskwakeafter.c3
-rw-r--r--cpukit/sapi/include/confdefs.h123
-rw-r--r--cpukit/sapi/include/rtems/config.h4
-rw-r--r--cpukit/sapi/src/exinit.c4
-rw-r--r--cpukit/score/Makefile.am17
-rw-r--r--cpukit/score/include/rtems/score/prioritybitmap.h11
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h156
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h117
-rw-r--r--cpukit/score/include/rtems/score/thread.h23
-rw-r--r--cpukit/score/inline/rtems/score/scheduler.inl139
-rw-r--r--cpukit/score/inline/rtems/score/schedulerpriority.inl286
-rw-r--r--cpukit/score/inline/rtems/score/thread.inl11
-rw-r--r--cpukit/score/preinstall.am16
-rw-r--r--cpukit/score/src/scheduler.c45
-rw-r--r--cpukit/score/src/schedulerpriority.c66
-rw-r--r--cpukit/score/src/schedulerpriorityblock.c48
-rw-r--r--cpukit/score/src/schedulerpriorityschedule.c48
-rw-r--r--cpukit/score/src/schedulerprioritythreadschedulerallocate.c53
-rw-r--r--cpukit/score/src/schedulerprioritythreadschedulerfree.c46
-rw-r--r--cpukit/score/src/schedulerprioritythreadschedulerupdate.c55
-rw-r--r--cpukit/score/src/schedulerpriorityunblock.c57
-rw-r--r--cpukit/score/src/schedulerpriorityyield.c77
-rw-r--r--cpukit/score/src/thread.c9
-rw-r--r--cpukit/score/src/threadchangepriority.c12
-rw-r--r--cpukit/score/src/threadclearstate.c27
-rw-r--r--cpukit/score/src/threadclose.c6
-rw-r--r--cpukit/score/src/threadinitialize.c8
-rw-r--r--cpukit/score/src/threadready.c15
-rw-r--r--cpukit/score/src/threadresume.c15
-rw-r--r--cpukit/score/src/threadsetpriority.c7
-rw-r--r--cpukit/score/src/threadsetstate.c21
-rw-r--r--cpukit/score/src/threadsettransient.c15
-rw-r--r--cpukit/score/src/threadsuspend.c21
-rw-r--r--cpukit/score/src/threadtickletimeslice.c3
37 files changed, 1434 insertions, 164 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
index 3ee1ccc9aa..9a1cfcb872 100644
--- a/cpukit/ChangeLog
+++ b/cpukit/ChangeLog
@@ -1,3 +1,31 @@
+2010-11-24 Gedare Bloom <giddyup44@yahoo.com>
+
+ PR 1647/cpukit
+ * posix/src/nanosleep.c, posix/src/sched_yield.c,
+ rtems/src/taskwakeafter.c, sapi/include/confdefs.h,
+ sapi/include/rtems/config.h, sapi/src/exinit.c, score/Makefile.am,
+ score/preinstall.am, score/include/rtems/score/prioritybitmap.h,
+ score/include/rtems/score/thread.h,
+ score/inline/rtems/score/thread.inl, score/src/thread.c,
+ score/src/threadchangepriority.c, score/src/threadclearstate.c,
+ score/src/threadclose.c, score/src/threadinitialize.c,
+ score/src/threadready.c, score/src/threadresume.c,
+ score/src/threadsetpriority.c, score/src/threadsetstate.c,
+ score/src/threadsettransient.c, score/src/threadsuspend.c,
+ score/src/threadtickletimeslice.c: Refactor scheduler out of thread
+ handler to facilitate alternate scheduler implementations.
+ * score/src/threadyieldprocessor.c: Removed.
+ * score/src/schedulerprioritythreadschedulerupdate.c,
+ score/src/schedulerprioritythreadschedulerfree.c,
+ score/src/schedulerpriorityblock.c, score/src/scheduler.c,
+ score/src/schedulerprioritythreadschedulerallocate.c,
+ score/src/schedulerpriorityunblock.c,
+ score/src/schedulerpriority.c, score/src/schedulerpriorityyield.c,
+ score/include/rtems/score/schedulerpriority.h,
+ score/include/rtems/score/scheduler.h,
+ score/inline/rtems/score/scheduler.inl,
+ score/inline/rtems/score/schedulerpriority.inl: New files.
+
2010-11-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
* score/src/iterateoverthreads.c, libmisc/cpuuse/cpuusagereport.c:
diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c
index 5031039c24..dc81a378d5 100644
--- a/cpukit/posix/src/nanosleep.c
+++ b/cpukit/posix/src/nanosleep.c
@@ -18,6 +18,7 @@
#include <rtems/system.h>
#include <rtems/score/isr.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
@@ -56,7 +57,7 @@ int nanosleep(
if ( !ticks ) {
_Thread_Disable_dispatch();
- _Thread_Yield_processor();
+ _Scheduler_Yield();
_Thread_Enable_dispatch();
if ( rmtp ) {
rmtp->tv_sec = 0;
diff --git a/cpukit/posix/src/sched_yield.c b/cpukit/posix/src/sched_yield.c
index 0925e3cbd0..b6c5c4fce4 100644
--- a/cpukit/posix/src/sched_yield.c
+++ b/cpukit/posix/src/sched_yield.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <rtems/system.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/tod.h>
#include <rtems/score/thread.h>
#include <rtems/seterr.h>
@@ -28,7 +29,7 @@
int sched_yield( void )
{
_Thread_Disable_dispatch();
- _Thread_Yield_processor();
+ _Scheduler_Yield();
_Thread_Enable_dispatch();
return 0;
}
diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c
index 85f2e6307d..2f6fecfe5d 100644
--- a/cpukit/rtems/src/taskwakeafter.c
+++ b/cpukit/rtems/src/taskwakeafter.c
@@ -21,6 +21,7 @@
#include <rtems/rtems/support.h>
#include <rtems/rtems/modes.h>
#include <rtems/score/object.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/stack.h>
#include <rtems/score/states.h>
#include <rtems/rtems/tasks.h>
@@ -52,7 +53,7 @@ rtems_status_code rtems_task_wake_after(
{
_Thread_Disable_dispatch();
if ( ticks == 0 ) {
- _Thread_Yield_processor();
+ _Scheduler_Yield();
} else {
_Thread_Set_state( _Thread_Executing, STATES_DELAYING );
_Watchdog_Initialize(
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index e6f8edaed2..0a1b49d173 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -535,6 +535,116 @@ rtems_fs_init_functions_t rtems_fs_init_helper =
#endif
/*
+ * Scheduler configuration.
+ *
+ * The scheduler configuration allows an application to select the
+ * scheduling policy to use. The supported configurations are:
+ * CONFIGURE_SCHEDULER_USER
+ * CONFIGURE_SCHEDULER_PRIORITY
+ *
+ * If no configuration is specified by the application, then
+ * CONFIGURE_SCHEDULER_PRIORITY is assumed to be the default.
+ *
+ * An application can define its own scheduling policy by defining
+ * CONFIGURE_SCHEDULER_USER and CONFIGURE_SCHEDULER_ENTRY_USER to point
+ * to an initialization routine. Note: CONFIGURE_SCHEDULER_USER is not
+ * fully supported, since it has no per-thread field.
+ *
+ * To add a new scheduler:
+ */
+#include <rtems/score/scheduler.h>
+
+#if defined(CONFIGURE_SCHEDULER_USER) && \
+ !defined(CONFIGURE_SCHEDULER_ENTRY_USER)
+ #error "CONFIGURE_ERROR: CONFIGURE_SCHEDULER_USER without CONFIGURE_SCHEDULER_ENTRY_USER"
+#endif
+
+/* enable all RTEMS-provided schedulers */
+#if defined(CONFIGURE_SCHEDULER_ALL)
+ #define CONFIGURE_SCHEDULER_PRIORITY
+#endif
+
+/* If no scheduler is specified, the priority scheduler is default. */
+#if !defined(CONFIGURE_SCHEDULER_USER) && \
+ !defined(CONFIGURE_SCHEDULER_PRIORITY)
+ #define CONFIGURE_SCHEDULER_PRIORITY
+ #define CONFIGURE_SCHEDULER_POLICY _Scheduler_PRIORITY
+#endif
+
+/*
+ * If a user scheduler is specified and no policy is set,
+ * the user scheduler is the default policy.
+ */
+#if defined(CONFIGURE_SCHEDULER_USER) && \
+ !defined(CONFIGURE_SCHEDULER_POLICY)
+ #define CONFIGURE_SCHEDULER_POLICY _Scheduler_USER
+#endif
+
+/*
+ * Check for priority scheduler next, as it is the default policy if there
+ * is no CONFIGURE_SCHEDULER_POLICY set and no USER scheduler provided.
+ */
+#if defined(CONFIGURE_SCHEDULER_PRIORITY)
+ #include <rtems/score/schedulerpriority.h>
+ #define CONFIGURE_SCHEDULER_ENTRY_PRIORITY { _Scheduler_priority_Initialize }
+ #if !defined(CONFIGURE_SCHEDULER_POLICY)
+ #define CONFIGURE_SCHEDULER_POLICY _Scheduler_PRIORITY
+ #endif
+
+ /**
+ * define the memory used by the priority scheduler
+ */
+ #define CONFIGURE_MEMORY_SCHEDULER_PRIORITY ( \
+ _Configure_From_workspace( \
+ ((CONFIGURE_MAXIMUM_PRIORITY+1) * sizeof(Chain_Control)) ) \
+ )
+ #define CONFIGURE_MEMORY_PER_TASK_SCHEDULER_PRIORITY ( \
+ _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
+#endif
+
+/*
+ * Set up the scheduler table. The scheduling code indexes this table to
+ * invoke the correct scheduling implementation. The scheduler to use is
+ * determined by the Configuration.scheduler_policy field, which is set
+ * by CONFIGURE_SCHEDULER_POLICY. If a particular scheduler is not enabled,
+ * an empty entry is included in its entry in the scheduler table.
+ */
+
+ /**
+ * An empty scheduler entry
+ */
+ #define CONFIGURE_SCHEDULER_NULL { NULL }
+
+#ifdef CONFIGURE_INIT
+ /* the table of available schedulers. */
+ const Scheduler_Table_t _Scheduler_Table[] = {
+ #if defined(CONFIGURE_SCHEDULER_USER) && \
+ defined(CONFIGURE_SCHEDULER_ENTRY_USER)
+ CONFIGURE_SCHEDULER_ENTRY_USER,
+ #else
+ CONFIGURE_SCHEDULER_NULL,
+ #endif
+ #if defined(CONFIGURE_SCHEDULER_PRIORITY) && \
+ defined(CONFIGURE_SCHEDULER_ENTRY_PRIORITY)
+ CONFIGURE_SCHEDULER_ENTRY_PRIORITY,
+ #else
+ CONFIGURE_SCHEDULER_NULL,
+ #endif
+ };
+#endif
+
+/**
+ * Define the memory overhead for the scheduler
+ */
+#define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
+ CONFIGURE_MEMORY_SCHEDULER_PRIORITY \
+ )
+
+#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
+ CONFIGURE_MEMORY_PER_TASK_SCHEDULER_PRIORITY \
+ )
+
+/*
* If you said the IDLE task was going to do application initialization
* and didn't override the IDLE body, then something is amiss.
*/
@@ -1607,7 +1717,8 @@ rtems_fs_init_functions_t rtems_fs_init_helper =
(_Configure_From_workspace(CONFIGURE_MINIMUM_TASK_STACK_SIZE) + \
CONFIGURE_MEMORY_PER_TASK_FOR_CLASSIC_API + \
CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB + \
- CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API)) + \
+ CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API + \
+ CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER)) + \
_Configure_From_workspace( \
_Configure_Max_Objects(_number_FP_tasks) * CONTEXT_FP_SIZE) + \
_Configure_From_workspace( \
@@ -1705,13 +1816,6 @@ rtems_fs_init_functions_t rtems_fs_init_helper =
_Configure_Object_RAM(1, sizeof(API_Mutex_Control))
/**
- * This defines the memory used by the thread ready chains. There is
- * one chain per priority.
- */
-#define CONFIGURE_MEMORY_FOR_THREAD_READY_CHAINS \
- _Configure_From_workspace( \
- ((CONFIGURE_MAXIMUM_PRIORITY+1) * sizeof(Chain_Control)) )
-/**
* This defines the amount of memory reserved for the IDLE task
* control structures and stack.
*/
@@ -1724,7 +1828,7 @@ rtems_fs_init_functions_t rtems_fs_init_helper =
*/
#define CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
( CONFIGURE_MEMORY_FOR_IDLE_TASK + /* IDLE and stack */ \
- CONFIGURE_MEMORY_FOR_THREAD_READY_CHAINS + /* Ready chains */ \
+ CONFIGURE_MEMORY_FOR_SCHEDULER + /* Scheduler */ \
CONFIGURE_INTERRUPT_VECTOR_TABLE + /* interrupt vectors */ \
CONFIGURE_INTERRUPT_STACK_MEMORY + /* interrupt stack */ \
CONFIGURE_API_MUTEX_MEMORY /* allocation mutex */ \
@@ -2005,6 +2109,7 @@ rtems_fs_init_functions_t rtems_fs_init_helper =
CONFIGURE_MAXIMUM_USER_EXTENSIONS, /* maximum dynamic extensions */
CONFIGURE_MICROSECONDS_PER_TICK, /* microseconds per clock tick */
CONFIGURE_TICKS_PER_TIMESLICE, /* ticks per timeslice quantum */
+ CONFIGURE_SCHEDULER_POLICY, /* scheduling policy */
CONFIGURE_IDLE_TASK_BODY, /* user's IDLE task */
CONFIGURE_IDLE_TASK_STACK_SIZE, /* IDLE task stack size */
CONFIGURE_INTERRUPT_STACK_SIZE, /* interrupt stack size */
diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h
index 1f9b56c3e8..541bc9ddff 100644
--- a/cpukit/sapi/include/rtems/config.h
+++ b/cpukit/sapi/include/rtems/config.h
@@ -118,6 +118,10 @@ typedef struct {
*/
uint32_t ticks_per_timeslice;
+ /** This field specifies the scheduling policy to use.
+ */
+ uint32_t scheduler_policy;
+
/** This element points to the BSP's optional idle task which may override
* the default one provided with RTEMS.
*/
diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
index 1185b74e4a..2cbddfa1da 100644
--- a/cpukit/sapi/src/exinit.c
+++ b/cpukit/sapi/src/exinit.c
@@ -42,7 +42,7 @@
#include <rtems/score/mpci.h>
#endif
#include <rtems/score/priority.h>
-#include <rtems/score/prioritybitmap.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
#include <rtems/score/userext.h>
@@ -131,6 +131,8 @@ void rtems_initialize_data_structures(void)
_Thread_Handler_initialization();
+ _Scheduler_Handler_initialization();
+
#if defined(RTEMS_MULTIPROCESSING)
_Objects_MP_Handler_initialization();
_MPCI_Handler_initialization( RTEMS_TIMEOUT );
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index fd1f2a90e2..6ad13b51e8 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -26,6 +26,7 @@ include_rtems_score_HEADERS = include/rtems/score/address.h \
include/rtems/score/interr.h include/rtems/score/isr.h \
include/rtems/score/object.h include/rtems/score/percpu.h \
include/rtems/score/priority.h include/rtems/score/prioritybitmap.h \
+ include/rtems/score/scheduler.h include/rtems/score/schedulerpriority.h \
include/rtems/score/stack.h include/rtems/score/states.h \
include/rtems/score/sysstate.h include/rtems/score/thread.h \
include/rtems/score/threadq.h include/rtems/score/threadsync.h \
@@ -54,6 +55,7 @@ include_rtems_score_HEADERS += inline/rtems/score/address.inl \
inline/rtems/score/coresem.inl inline/rtems/score/heap.inl \
inline/rtems/score/isr.inl inline/rtems/score/object.inl \
inline/rtems/score/priority.inl inline/rtems/score/prioritybitmap.inl \
+ inline/rtems/score/scheduler.inl inline/rtems/score/schedulerpriority.inl \
inline/rtems/score/stack.inl inline/rtems/score/states.inl \
inline/rtems/score/sysstate.inl inline/rtems/score/thread.inl \
inline/rtems/score/threadq.inl inline/rtems/score/tod.inl \
@@ -137,6 +139,19 @@ libscore_a_SOURCES += src/objectallocate.c src/objectclose.c \
src/objectgetinfo.c src/objectgetinfoid.c src/objectapimaximumclass.c \
src/objectnamespaceremove.c
+## SCHEDULER_C_FILES
+libscore_a_SOURCES += src/scheduler.c
+
+## SCHEDULERPRIORITY_C_FILES
+libscore_a_SOURCES += src/schedulerpriority.c \
+ src/schedulerpriorityblock.c \
+ src/schedulerprioritythreadschedulerallocate.c \
+ src/schedulerprioritythreadschedulerfree.c \
+ src/schedulerprioritythreadschedulerupdate.c \
+ src/schedulerpriorityschedule.c \
+ src/schedulerpriorityunblock.c \
+ src/schedulerpriorityyield.c
+
## PROTECTED_HEAP_C_FILES
libscore_a_SOURCES += src/pheapallocate.c \
src/pheapextend.c src/pheapfree.c src/pheapgetsize.c \
@@ -153,7 +168,7 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
src/threadsetstate.c src/threadsettransient.c \
src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \
src/threadstartmultitasking.c src/threadsuspend.c \
- src/threadtickletimeslice.c src/threadyieldprocessor.c \
+ src/threadtickletimeslice.c \
src/iterateoverthreads.c src/threadblockingoperationcancel.c
## THREADQ_C_FILES
diff --git a/cpukit/score/include/rtems/score/prioritybitmap.h b/cpukit/score/include/rtems/score/prioritybitmap.h
index cd712952b2..bba5b428b6 100644
--- a/cpukit/score/include/rtems/score/prioritybitmap.h
+++ b/cpukit/score/include/rtems/score/prioritybitmap.h
@@ -37,18 +37,17 @@ extern "C" {
#include <rtems/score/priority.h>
+
/*
- * TODO:
- * These should only be instantiated if using the bit map handler. The
- * logical place for this is in confdefs.h when a scheduler that uses the
- * bit map handler is configured.
+ * The Priority_bit_map_Control variables are instantiated only
+ * if using the bit map handler.
*/
/**
* Each sixteen bit entry in this array is associated with one of
* the sixteen entries in the Priority Bit map.
*/
-SCORE_EXTERN volatile Priority_bit_map_Control _Priority_Major_bit_map;
+extern volatile Priority_bit_map_Control _Priority_Major_bit_map;
/** Each bit in the Priority Bitmap indicates whether or not there are
* threads ready at a particular priority. The mapping of
@@ -56,7 +55,7 @@ SCORE_EXTERN volatile Priority_bit_map_Control _Priority_Major_bit_map;
* dependent as is the value of each bit used to indicate that
* threads are ready at that priority.
*/
-SCORE_EXTERN Priority_bit_map_Control
+extern Priority_bit_map_Control
_Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
/*
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
new file mode 100644
index 0000000000..b0ac20917c
--- /dev/null
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -0,0 +1,156 @@
+/**
+ * @file rtems/score/scheduler.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the scheduler.
+ */
+
+/*
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULER_H
+#define _RTEMS_SCORE_SCHEDULER_H
+
+/**
+ * @defgroup ScoreScheduler Scheduler Handler
+ *
+ * This handler encapsulates functionality related to managing sets of threads
+ * that are ready for execution.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/prioritybitmap.h>
+
+/*
+ * These defines are used to set the scheduler_policy value. The values
+ * must correspond directly with the order of the fields in the scheduler
+ * table (Scheduler_Table_t), because the Configuration.scheduler_policy
+ * field is used to index the scheduler table.
+ */
+#define _Scheduler_USER (0)
+#define _Scheduler_PRIORITY (1)
+
+typedef struct Scheduler_Control_struct Scheduler_Control;
+
+/*
+ * The Scheduler_Table_t type defines the scheduler initialization table,
+ * which is set up by confdefs.h based on the user's choice of scheduler
+ * policy.
+ */
+typedef struct {
+ void ( *scheduler_init )( Scheduler_Control * );
+} Scheduler_Table_t;
+
+/* instantiated and initialized in confdefs.h */
+extern const Scheduler_Table_t _Scheduler_Table[];
+
+/**
+ * The following Scheduler_Per_thread_xxx structures are used to
+ * hold per-thread data used by the scheduler. Thread_Control->scheduler is a
+ * union of pointers, one for each of the following structures. The
+ * scheduler->xxx field points to an instantion of one of these structures,
+ * which is allocated from the workspace during _Thread_Start.
+ */
+
+/**
+ * Per-thread data related to the _Scheduler_PRIORITY scheduling policy.
+ */
+typedef struct {
+ /** This field points to the Ready FIFO for this thread's priority. */
+ Chain_Control *ready_chain;
+
+ /** This field contains precalculated priority map indices. */
+ Priority_bit_map_Information Priority_map;
+} Scheduler_priority_Per_thread;
+
+/**
+ * function jump table that holds pointers to the functions that
+ * implement specific schedulers.
+ */
+typedef struct {
+ /** Implements the scheduling decision logic (policy). */
+ void ( *schedule ) ( Scheduler_Control * );
+
+ /** Voluntarily yields the processor per the scheduling policy. */
+ void ( *yield ) ( Scheduler_Control * );
+
+ /** Removes the given thread from scheduling decisions. */
+ void ( *block ) ( Scheduler_Control *, Thread_Control * );
+
+ /** Adds the given thread to scheduling decisions. */
+ void ( *unblock ) ( Scheduler_Control *, Thread_Control * );
+
+ /** allocates the scheduler field of the given thread */
+ void * ( *scheduler_allocate ) ( Scheduler_Control *, Thread_Control * );
+
+ /** frees the scheduler field of the given thread */
+ void ( *scheduler_free ) ( Scheduler_Control *, Thread_Control * );
+
+ /** updates the scheduler field of the given thread -- primarily used
+ * when changing the thread's priority. */
+ void ( *scheduler_update ) ( Scheduler_Control *, Thread_Control * );
+} Scheduler_Operations;
+
+/**
+ * This is the structure used to manage the scheduler.
+ */
+struct Scheduler_Control_struct {
+ /**
+ * This union contains the pointer to the data structure used to manage
+ * the ready set of tasks. The pointer varies based upon the type of
+ * ready queue required by the scheduler.
+ */
+ union {
+ /**
+ * This is the set of lists (an array of Chain_Control) for
+ * priority scheduling.
+ */
+ Chain_Control *Priority;
+
+ } ready_queues;
+
+ /** The jump table for scheduler-specific functions */
+ Scheduler_Operations operations;
+};
+
+/**
+ * The _Scheduler holds the structures used to manage the
+ * scheduler.
+ *
+ * @note Can we make this per-cpu? then _Scheduler will be a macro.
+ */
+SCORE_EXTERN Scheduler_Control _Scheduler;
+
+/**
+ * This routine initializes the scheduler to the policy chosen by the user
+ * through confdefs, or to the priority scheduler with ready chains by
+ * default.
+ */
+void _Scheduler_Handler_initialization( void );
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/scheduler.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
new file mode 100644
index 0000000000..54c999f058
--- /dev/null
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -0,0 +1,117 @@
+/**
+ * @file rtems/score/schedulerpriority.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of threads for the priority-based scheduler.
+ */
+
+/*
+ * Copryight (c) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_H
+#define _RTEMS_SCORE_SCHEDULERPRIORITY_H
+
+/**
+ * @addtogroup ScoreScheduler
+ *
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/chain.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/wkspace.h>
+
+/**
+ * This routine initializes the priority scheduler.
+ */
+void _Scheduler_priority_Initialize(
+ Scheduler_Control *the_scheduler
+);
+
+/**
+ * This routine removes @a the_thread from the scheduling decision,
+ * that is, removes it from the ready queue. It performs
+ * any necessary scheduling operations including the selection of
+ * a new heir thread.
+ */
+void _Scheduler_priority_Block(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+);
+
+/**
+ * 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(
+ Scheduler_Control *the_scheduler
+);
+
+/**
+ * This routine allocates @a the_thread->scheduler.
+ */
+void * _Scheduler_priority_Thread_scheduler_allocate(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine frees @a the_thread->scheduler.
+ */
+void _Scheduler_priority_Thread_scheduler_free(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine updates @a the_thread->scheduler based on @a the_scheduler
+ * structures and thread state
+ */
+void _Scheduler_priority_Thread_scheduler_update(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine adds @a the_thread to the scheduling decision,
+ * that is, adds it to the ready queue and
+ * updates any appropriate scheduling variables, for example the heir thread.
+ */
+void _Scheduler_priority_Unblock(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+);
+
+/**
+ * This routine is invoked when a thread wishes to voluntarily
+ * transfer control of the processor to another thread in the queue.
+ */
+void _Scheduler_priority_Yield(
+ Scheduler_Control *the_scheduler
+);
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/schedulerpriority.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 9565458bb8..370d5491a3 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -70,7 +70,7 @@ extern "C" {
#endif
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
-#include <rtems/score/prioritybitmap.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/stack.h>
#include <rtems/score/states.h>
#include <rtems/score/tod.h>
@@ -390,10 +390,10 @@ struct Thread_Control_struct {
* since it was created.
*/
Thread_CPU_usage_t cpu_time_used;
- /** This field points to the Ready FIFO for this priority. */
- Chain_Control *ready;
- /** This field contains precalculated priority map indices. */
- Priority_bit_map_Information Priority_map;
+ /** This union holds per-thread data for the scheduler and ready queue. */
+ union {
+ Scheduler_priority_Per_thread *priority;
+ } scheduler;
/** This field contains information about the starting state of
* this thread.
*/
@@ -456,12 +456,6 @@ SCORE_EXTERN uint32_t _Thread_Maximum_extensions;
SCORE_EXTERN uint32_t _Thread_Ticks_per_timeslice;
/**
- * The following points to the array of FIFOs used to manage the
- * set of ready threads.
- */
-SCORE_EXTERN Chain_Control *_Thread_Ready_chain;
-
-/**
* The following points to the thread whose floating point
* context is currently loaded.
*/
@@ -654,13 +648,6 @@ void _Thread_Set_transient(
void _Thread_Tickle_timeslice( void );
/**
- * This routine is invoked when a thread wishes to voluntarily
- * transfer control of the processor to another thread of equal
- * or greater priority.
- */
-void _Thread_Yield_processor( void );
-
-/**
* This routine initializes the context of the_thread to its
* appropriate starting state.
*/
diff --git a/cpukit/score/inline/rtems/score/scheduler.inl b/cpukit/score/inline/rtems/score/scheduler.inl
new file mode 100644
index 0000000000..4a0f10a3f3
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/scheduler.inl
@@ -0,0 +1,139 @@
+/**
+ * @file rtems/score/scheduler.inl
+ *
+ * This inline file contains all of the inlined routines associated with
+ * the manipulation of the scheduler.
+ */
+
+/*
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULER_H
+# error "Never use <rtems/score/scheduler.inl> directly; include <rtems/score/scheduler.h> instead."
+#endif
+
+#ifndef _RTEMS_SCORE_SCHEDULER_INL
+#define _RTEMS_SCORE_SCHEDULER_INL
+
+/**
+ * @addtogroup ScoreScheduler
+ * @{
+ */
+
+/**
+ * The preferred method to add a new scheduler is to define the jump table
+ * entries and add a case to the _Scheduler_Initialize routine.
+ *
+ * Generic scheduling implementations that rely on the ready queue only can
+ * be found in the _Scheduler_queue_XXX functions.
+ *
+ */
+
+/* Passing the Scheduler_Control* to these functions allows for multiple
+ * scheduler's to exist simultaneously, which could be useful on an SMP
+ * system. Then remote Schedulers may be accessible. How to protect such
+ * accesses remains an open problem.
+ */
+
+/** @brief _Scheduler_Schedule
+ *
+ * This kernel routine implements the scheduling decision logic for
+ * @a the_scheduler. It does NOT dispatch.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Schedule(
+ Scheduler_Control *the_scheduler
+)
+{
+ the_scheduler->operations.schedule( the_scheduler );
+}
+
+/** @brief _Scheduler_Yield
+ *
+ * This routine is invoked when a thread wishes to voluntarily
+ * transfer control of the processor to another thread. This routine
+ * always operates on the scheduler that 'owns' the currently executing
+ * thread.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Yield( void )
+{
+ _Scheduler.operations.yield( &_Scheduler );
+}
+
+/** @brief _Scheduler_Block
+ *
+ * This routine removes @a the_thread from the scheduling decision for
+ * @a the_scheduler. The primary task is to remove the thread from the
+ * ready queue. It performs any necessary schedulering operations
+ * including the selection of a new heir thread.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Block(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ the_scheduler->operations.block( the_scheduler, the_thread );
+}
+
+/** @brief _Scheduler_Unblock
+ *
+ * This routine adds @a the_thread to the scheduling decision for
+ * @a the_scheduler. The primary task is to add the thread to the
+ * ready queue per the schedulering policy and update any appropriate
+ * scheduling variables, for example the heir thread.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Unblock(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ the_scheduler->operations.unblock( the_scheduler, the_thread );
+}
+
+/** @brief _Scheduler_Thread_scheduler_allocate
+ *
+ * This routine allocates @a the_thread->scheduler
+ */
+RTEMS_INLINE_ROUTINE void* _Scheduler_Thread_scheduler_allocate(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ return
+ the_scheduler->operations.scheduler_allocate( the_scheduler, the_thread );
+}
+
+/** @brief _Scheduler_Thread_scheduler_free
+ *
+ * This routine frees @a the_thread->scheduler
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Thread_scheduler_free(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ return the_scheduler->operations.scheduler_free( the_scheduler, the_thread );
+}
+
+/** @brief _Scheduler_Thread_scheduler_update
+ *
+ * This routine updates @a the_thread->scheduler
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Thread_scheduler_update(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ the_scheduler->operations.scheduler_update( the_scheduler, the_thread );
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/schedulerpriority.inl b/cpukit/score/inline/rtems/score/schedulerpriority.inl
new file mode 100644
index 0000000000..da6de2802d
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/schedulerpriority.inl
@@ -0,0 +1,286 @@
+/**
+ * @file rtems/score/schedulerpriority.inl
+ *
+ * This inline file contains all of the inlined routines associated with
+ * the manipulation of the priority-based scheduling structures.
+ */
+
+/*
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_H
+# error "Never use <rtems/score/schedulerpriority.inl> directly; include <rtems/score/schedulerpriority.h> instead."
+#endif
+
+#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_INL
+#define _RTEMS_SCORE_SCHEDULERPRIORITY_INL
+
+/**
+ * @addtogroup ScoreScheduler
+ * @{
+ */
+
+/** @brief Scheduler priority Ready queue initialize
+ *
+ * This routine initializes @a the_ready_queue for priority-based scheduling.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize(
+ Scheduler_Control *the_scheduler
+) {
+ uint32_t index;
+
+ /* allocate ready queue structures */
+ the_scheduler->ready_queues.Priority = (Chain_Control *)
+ _Workspace_Allocate_or_fatal_error(
+ (PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control)
+ );
+
+ /* initialize ready queue structures */
+ for( index=0; index <= PRIORITY_MAXIMUM; index++)
+ _Chain_Initialize_empty( &the_scheduler->ready_queues.Priority[index] );
+}
+
+/*
+ * _Scheduler_priority_Ready_queue_enqueue
+ *
+ * This routine puts @a the_thread on to the priority-based ready queue.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
+ Thread_Control *the_thread
+)
+{
+ _Priority_bit_map_Add( &the_thread->scheduler.priority->Priority_map );
+
+ _Chain_Append_unprotected( the_thread->scheduler.priority->ready_chain,
+ &the_thread->Object.Node );
+}
+
+/*
+ * _Scheduler_priority_Ready_queue_Enqueue_first
+ *
+ * This routine puts @a the_thread to the head of the ready queue.
+ * For priority-based ready queues, the thread will be the first thread
+ * at its priority level.
+ *
+ * Input parameters:
+ * the_thread - pointer to thread
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
+ Thread_Control *the_thread
+)
+{
+ _Priority_bit_map_Add( &the_thread->scheduler.priority->Priority_map );
+
+ _Chain_Prepend_unprotected( the_thread->scheduler.priority->ready_chain,
+ &the_thread->Object.Node );
+}
+
+/*
+ * _Scheduler_priority_Ready_queue_extract
+ *
+ * This routine removes a specific thread from the specified
+ * priority-based ready queue.
+ *
+ * Input parameters:
+ * the_thread - pointer to a thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract(
+ Thread_Control *the_thread
+)
+{
+ Chain_Control *ready = the_thread->scheduler.priority->ready_chain;
+
+ if ( _Chain_Has_only_one_node( ready ) ) {
+ _Chain_Initialize_empty( ready );
+ _Priority_bit_map_Remove( &the_thread->scheduler.priority->Priority_map );
+ } else
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+}
+
+/*
+ * _Scheduler_priority_Ready_queue_first
+ *
+ * This routines returns a pointer to the first thread on @a the_ready_queue.
+ *
+ * Input parameters:
+ * the_ready_queue - pointer to thread queue
+ *
+ * Output parameters:
+ * returns - first thread or NULL
+ */
+
+RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Ready_queue_first(
+ Chain_Control *the_ready_queue
+)
+{
+ uint32_t index = _Priority_bit_map_Get_highest();
+
+ if ( !_Chain_Is_empty( &the_ready_queue[ index ] ) )
+ return (Thread_Control *) the_ready_queue[ index ].first;
+
+ return NULL;
+}
+
+/*
+ * _Scheduler_priority_Ready_queue_requeue
+ *
+ * This routine is invoked when a thread changes priority and should be
+ * moved to a different position on the ready queue.
+ *
+ * Input parameters:
+ * the_thread - pointer to a thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY: NONE
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_requeue(
+ Thread_Control *the_thread
+)
+{
+ if ( !_Chain_Has_only_one_node(
+ the_thread->scheduler.priority->ready_chain
+ ) ) {
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+
+ _Chain_Append_unprotected( the_thread->scheduler.priority->ready_chain,
+ &the_thread->Object.Node );
+ }
+}
+
+/*
+ * _Scheduler_priority_Schedule_body
+ *
+ * This kernel routine implements scheduling decision logic for priority-based
+ * scheduling.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
+ Scheduler_Control *the_scheduler
+)
+{
+ _Thread_Heir = _Scheduler_priority_Ready_queue_first(
+ the_scheduler->ready_queues.Priority
+ );
+}
+
+/*
+ * _Scheduler_priority_Block_body
+ *
+ * This kernel routine removes the_thread from scheduling decisions based
+ * on simple queue extraction.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Block_body(
+ Scheduler_Control *the_scheduler,
+ 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(the_scheduler);
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _Thread_Dispatch_necessary = true;
+
+ return;
+}
+
+/*
+ * _Scheduler_priority_Unblock_body
+ *
+ * This kernel routine readies the requested thread according to the queuing
+ * discipline. A new heir thread may be selected.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: This routine uses the "blocking" heir selection mechanism.
+ * This ensures the correct heir after a thread restart.
+ *
+ * INTERRUPT LATENCY:
+ */
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Unblock_body (
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Ready_queue_enqueue(
+ the_thread
+ );
+
+ /* 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 ( the_thread->current_priority < _Thread_Heir->current_priority ) {
+ _Thread_Heir = the_thread;
+ if ( _Thread_Executing->is_preemptible ||
+ the_thread->current_priority == 0 )
+ _Thread_Dispatch_necessary = true;
+ }
+}
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl
index d0a9e703f7..e700bdfb53 100644
--- a/cpukit/score/inline/rtems/score/thread.inl
+++ b/cpukit/score/inline/rtems/score/thread.inl
@@ -120,17 +120,6 @@ RTEMS_INLINE_ROUTINE void _Thread_Restart_self( void )
}
/**
- * This function returns a pointer to the highest priority
- * ready thread.
- */
-
-RTEMS_INLINE_ROUTINE void _Thread_Calculate_heir( void )
-{
- _Thread_Heir = (Thread_Control *)
- _Thread_Ready_chain[ _Priority_bit_map_Get_highest() ].first;
-}
-
-/**
* This function returns true if the floating point context of
* the_thread is currently loaded in the floating point unit, and
* false otherwise.
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 9768f8c81d..65f28c4a85 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -111,6 +111,14 @@ $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.h: include/rtems/score/prioritybit
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.h
+$(PROJECT_INCLUDE)/rtems/score/scheduler.h: include/rtems/score/scheduler.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduler.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduler.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
+
$(PROJECT_INCLUDE)/rtems/score/stack.h: include/rtems/score/stack.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.h
@@ -245,6 +253,14 @@ $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.inl: inline/rtems/score/prioritybi
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.inl
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.inl
+$(PROJECT_INCLUDE)/rtems/score/scheduler.inl: inline/rtems/score/scheduler.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduler.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduler.inl
+
+$(PROJECT_INCLUDE)/rtems/score/schedulerpriority.inl: inline/rtems/score/schedulerpriority.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.inl
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.inl
+
$(PROJECT_INCLUDE)/rtems/score/stack.inl: inline/rtems/score/stack.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.inl
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.inl
diff --git a/cpukit/score/src/scheduler.c b/cpukit/score/src/scheduler.c
new file mode 100644
index 0000000000..9d7424eef6
--- /dev/null
+++ b/cpukit/score/src/scheduler.c
@@ -0,0 +1,45 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+
+/*
+ * _Scheduler_Handler_initialization
+ *
+ * This routine initializes the scheduler by calling the scheduler_init
+ * function registered in the Configuration Scheduler Table.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ */
+
+void _Scheduler_Handler_initialization( )
+{
+ Scheduler_Control *the_scheduler = &_Scheduler;
+
+ (*(_Scheduler_Table[Configuration.scheduler_policy].scheduler_init))(
+ the_scheduler
+ );
+}
diff --git a/cpukit/score/src/schedulerpriority.c b/cpukit/score/src/schedulerpriority.c
new file mode 100644
index 0000000000..5e7ad61d9a
--- /dev/null
+++ b/cpukit/score/src/schedulerpriority.c
@@ -0,0 +1,66 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+
+/* Instantiate any global variables needed by the priority scheduler */
+volatile Priority_bit_map_Control _Priority_Major_bit_map;
+
+Priority_bit_map_Control _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
+
+/*
+ * _Scheduler_priority_Initialize
+ *
+ * Initializes the scheduler for priority scheduling.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ *
+ * Output parameters: NONE
+ */
+
+void _Scheduler_priority_Initialize (
+ Scheduler_Control *the_scheduler
+)
+{
+ /* the operations table is a jump table to redirect generic scheduler
+ * function calls to scheduler implementation specific functions. The
+ * main purpose of scheduler initialization is to set up the jump table
+ * for the scheduler. Every scheduler implementation provides its own
+ * scheduler operations table.
+ */
+ the_scheduler->operations.schedule = &_Scheduler_priority_Schedule;
+ the_scheduler->operations.yield = &_Scheduler_priority_Yield;
+ the_scheduler->operations.block = &_Scheduler_priority_Block;
+ the_scheduler->operations.unblock = &_Scheduler_priority_Unblock;
+ the_scheduler->operations.scheduler_allocate =
+ &_Scheduler_priority_Thread_scheduler_allocate;
+ the_scheduler->operations.scheduler_free =
+ &_Scheduler_priority_Thread_scheduler_free;
+ the_scheduler->operations.scheduler_update =
+ &_Scheduler_priority_Thread_scheduler_update;
+
+ _Scheduler_priority_Ready_queue_initialize( the_scheduler );
+ _Priority_bit_map_Handler_initialization( );
+}
diff --git a/cpukit/score/src/schedulerpriorityblock.c b/cpukit/score/src/schedulerpriorityblock.c
new file mode 100644
index 0000000000..cc137e64f5
--- /dev/null
+++ b/cpukit/score/src/schedulerpriorityblock.c
@@ -0,0 +1,48 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/thread.h>
+
+/*
+ * _Scheduler_priority_Block
+ *
+ * This kernel routine removes the_thread from scheduling decisions based
+ * on simple queue extraction.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ */
+
+void _Scheduler_priority_Block(
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Block_body(the_scheduler, the_thread);
+}
diff --git a/cpukit/score/src/schedulerpriorityschedule.c b/cpukit/score/src/schedulerpriorityschedule.c
new file mode 100644
index 0000000000..10c46652ef
--- /dev/null
+++ b/cpukit/score/src/schedulerpriorityschedule.c
@@ -0,0 +1,48 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/thread.h>
+
+/*
+ * _Scheduler_priority_Schedule
+ *
+ * This kernel routine implements scheduling decision logic for priority-based
+ * scheduling.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ */
+
+void _Scheduler_priority_Schedule(
+ Scheduler_Control *the_scheduler
+)
+{
+ _Scheduler_priority_Schedule_body( the_scheduler );
+}
diff --git a/cpukit/score/src/schedulerprioritythreadschedulerallocate.c b/cpukit/score/src/schedulerprioritythreadschedulerallocate.c
new file mode 100644
index 0000000000..21595ff778
--- /dev/null
+++ b/cpukit/score/src/schedulerprioritythreadschedulerallocate.c
@@ -0,0 +1,53 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Scheduler_priority_Thread_scheduler_allocate
+ *
+ * Allocates @a the_thread->scheduler
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters:
+ * Returns pointer to allocated space.
+ */
+
+void* _Scheduler_priority_Thread_scheduler_allocate (
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ void *sched;
+
+ sched = _Workspace_Allocate( sizeof(Scheduler_priority_Per_thread) );
+
+ the_thread->scheduler.priority = (Scheduler_priority_Per_thread*) sched;
+
+ return sched;
+}
diff --git a/cpukit/score/src/schedulerprioritythreadschedulerfree.c b/cpukit/score/src/schedulerprioritythreadschedulerfree.c
new file mode 100644
index 0000000000..78226b5fb3
--- /dev/null
+++ b/cpukit/score/src/schedulerprioritythreadschedulerfree.c
@@ -0,0 +1,46 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Scheduler_priority_Thread_scheduler_free
+ *
+ * Frees @a the_thread->scheduler
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ */
+
+void _Scheduler_priority_Thread_scheduler_free (
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ _Workspace_Free( the_thread->scheduler.priority );
+}
diff --git a/cpukit/score/src/schedulerprioritythreadschedulerupdate.c b/cpukit/score/src/schedulerprioritythreadschedulerupdate.c
new file mode 100644
index 0000000000..c4c7e815ce
--- /dev/null
+++ b/cpukit/score/src/schedulerprioritythreadschedulerupdate.c
@@ -0,0 +1,55 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/prioritybitmap.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/thread.h>
+
+/*
+ * _Scheduler_priority_Thread_scheduler_update
+ *
+ * Updates @a the_thread->scheduler
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ */
+
+void _Scheduler_priority_Thread_scheduler_update (
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ Chain_Control *rq = the_scheduler->ready_queues.Priority;
+ the_thread->scheduler.priority->ready_chain = &rq[
+ the_thread->current_priority
+ ];
+
+ _Priority_bit_map_Initialize_information(
+ &the_thread->scheduler.priority->Priority_map,
+ the_thread->current_priority
+ );
+}
diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c
new file mode 100644
index 0000000000..9030c0a137
--- /dev/null
+++ b/cpukit/score/src/schedulerpriorityunblock.c
@@ -0,0 +1,57 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Scheduler_priority_Unblock
+ *
+ * This kernel routine readies the requested thread according to the queuing
+ * discipline. A new heir thread may be selected.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ * the_thread - pointer to thread control block
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: This routine uses the "blocking" heir selection mechanism.
+ * This ensures the correct heir after a thread restart.
+ *
+ * INTERRUPT LATENCY:
+ */
+
+void _Scheduler_priority_Unblock (
+ Scheduler_Control *the_scheduler,
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Unblock_body(the_scheduler, the_thread);
+}
diff --git a/cpukit/score/src/schedulerpriorityyield.c b/cpukit/score/src/schedulerpriorityyield.c
new file mode 100644
index 0000000000..1a13a4e318
--- /dev/null
+++ b/cpukit/score/src/schedulerpriorityyield.c
@@ -0,0 +1,77 @@
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/apiext.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/states.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/userext.h>
+#include <rtems/score/wkspace.h>
+
+/*
+ * _Scheduler_priority_Yield
+ *
+ * This kernel routine will remove the running THREAD from the ready queue
+ * and place it immediately at the rear of this chain. Reset timeslice
+ * and yield the processor functions both use this routine, therefore if
+ * reset is true and this is the only thread on the queue then the
+ * timeslice counter is reset. The heir THREAD will be updated if the
+ * running is also the currently the heir.
+ *
+ * Input parameters:
+ * the_scheduler - pointer to scheduler control
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Scheduler_priority_Yield(
+ Scheduler_Control *the_scheduler
+)
+{
+ ISR_Level level;
+ Thread_Control *executing;
+ Chain_Control *ready;
+
+ executing = _Thread_Executing;
+ ready = executing->scheduler.priority->ready_chain;
+ _ISR_Disable( level );
+ if ( !_Chain_Has_only_one_node( ready ) ) {
+ _Chain_Extract_unprotected( &executing->Object.Node );
+ _Chain_Append_unprotected( ready, &executing->Object.Node );
+
+ _ISR_Flash( level );
+
+ if ( _Thread_Is_heir( executing ) )
+ _Thread_Heir = (Thread_Control *) ready->first;
+ _Thread_Dispatch_necessary = true;
+ }
+ else if ( !_Thread_Is_heir( executing ) )
+ _Thread_Dispatch_necessary = true;
+
+ _ISR_Enable( level );
+}
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index f0891373f6..bf8e8939e7 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -24,6 +24,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -45,7 +46,6 @@
void _Thread_Handler_initialization(void)
{
- uint32_t index;
uint32_t ticks_per_timeslice;
uint32_t maximum_extensions;
#if defined(RTEMS_MULTIPROCESSING)
@@ -80,13 +80,6 @@ void _Thread_Handler_initialization(void)
_Thread_Ticks_per_timeslice = ticks_per_timeslice;
- _Thread_Ready_chain = (Chain_Control *) _Workspace_Allocate_or_fatal_error(
- (PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control)
- );
-
- for ( index=0; index <= PRIORITY_MAXIMUM ; index++ )
- _Chain_Initialize_empty( &_Thread_Ready_chain[ index ] );
-
#if defined(RTEMS_MULTIPROCESSING)
_Thread_MP_Handler_initialization( maximum_proxies );
#endif
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index 58f5eb5fd3..7b46f799c7 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -23,6 +23,8 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -117,14 +119,16 @@ void _Thread_Change_priority(
* We now know the thread will be in the READY state when we remove
* the TRANSIENT state. So we have to place it on the appropriate
* Ready Queue with interrupts off.
+ *
+ * FIXME: hard-coded for priority scheduling. Might be ok since this
+ * function is specific to priority scheduling?
*/
the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
- _Priority_bit_map_Add( &the_thread->Priority_map );
if ( prepend_it )
- _Chain_Prepend_unprotected( the_thread->ready, &the_thread->Object.Node );
+ _Scheduler_priority_Ready_queue_enqueue_first( the_thread );
else
- _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node );
+ _Scheduler_priority_Ready_queue_enqueue( the_thread );
}
_ISR_Flash( level );
@@ -133,7 +137,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.
*/
- _Thread_Calculate_heir();
+ _Scheduler_Schedule(&_Scheduler);
if ( !_Thread_Is_executing_also_the_heir() &&
_Thread_Executing->is_preemptible )
diff --git a/cpukit/score/src/threadclearstate.c b/cpukit/score/src/threadclearstate.c
index c5ab03497a..c3a9083197 100644
--- a/cpukit/score/src/threadclearstate.c
+++ b/cpukit/score/src/threadclearstate.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -66,31 +67,7 @@ void _Thread_Clear_state(
the_thread->current_state = _States_Clear( state, current_state );
if ( _States_Is_ready( current_state ) ) {
-
- _Priority_bit_map_Add( &the_thread->Priority_map );
-
- _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);
-
- _ISR_Flash( level );
-
- /*
- * 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 ( the_thread->current_priority < _Thread_Heir->current_priority ) {
- _Thread_Heir = the_thread;
- if ( _Thread_Executing->is_preemptible ||
- the_thread->current_priority == 0 )
- _Thread_Dispatch_necessary = true;
- }
+ _Scheduler_Unblock( &_Scheduler, the_thread);
}
}
_ISR_Enable( level );
diff --git a/cpukit/score/src/threadclose.c b/cpukit/score/src/threadclose.c
index 51db06f56c..5098f0fbc4 100644
--- a/cpukit/score/src/threadclose.c
+++ b/cpukit/score/src/threadclose.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -86,6 +87,11 @@ void _Thread_Close(
}
/*
+ * Free the per-thread scheduling information.
+ */
+ _Scheduler_Thread_scheduler_free( &_Scheduler, the_thread );
+
+ /*
* The thread might have been FP. So deal with that.
*/
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 4afdbcb821..eda6f6bb5a 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -60,6 +61,7 @@ bool _Thread_Initialize(
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
void *fp_area;
#endif
+ void *sched = NULL;
void *extensions_area;
bool extension_status;
int i;
@@ -192,6 +194,9 @@ bool _Thread_Initialize(
the_thread->resource_count = 0;
the_thread->real_priority = priority;
the_thread->Start.initial_priority = priority;
+ sched =_Scheduler_Thread_scheduler_allocate( &_Scheduler, the_thread );
+ if ( !sched )
+ goto failed;
_Thread_Set_priority( the_thread, priority );
/*
@@ -235,6 +240,9 @@ failed:
(void) _Workspace_Free( fp_area );
#endif
+ if ( sched )
+ (void) _Workspace_Free( sched );
+
_Thread_Stack_Free( the_thread );
return false;
diff --git a/cpukit/score/src/threadready.c b/cpukit/score/src/threadready.c
index 3daa6506bd..f0e006503c 100644
--- a/cpukit/score/src/threadready.c
+++ b/cpukit/score/src/threadready.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -55,24 +56,12 @@ void _Thread_Ready(
)
{
ISR_Level level;
- Thread_Control *heir;
_ISR_Disable( level );
the_thread->current_state = STATES_READY;
- _Priority_bit_map_Add( &the_thread->Priority_map );
-
- _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node );
-
- _ISR_Flash( level );
-
- _Thread_Calculate_heir();
-
- heir = _Thread_Heir;
-
- if ( !_Thread_Is_executing( heir ) && _Thread_Executing->is_preemptible )
- _Thread_Dispatch_necessary = true;
+ _Scheduler_Unblock( &_Scheduler, the_thread );
_ISR_Enable( level );
}
diff --git a/cpukit/score/src/threadresume.c b/cpukit/score/src/threadresume.c
index c82466d3b3..1997c3c293 100644
--- a/cpukit/score/src/threadresume.c
+++ b/cpukit/score/src/threadresume.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -68,19 +69,7 @@ void _Thread_Resume(
the_thread->current_state = _States_Clear(STATES_SUSPENDED, current_state);
if ( _States_Is_ready( current_state ) ) {
-
- _Priority_bit_map_Add( &the_thread->Priority_map );
-
- _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);
-
- _ISR_Flash( level );
-
- if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
- _Thread_Heir = the_thread;
- if ( _Thread_Executing->is_preemptible ||
- the_thread->current_priority == 0 )
- _Thread_Dispatch_necessary = true;
- }
+ _Scheduler_Unblock( &_Scheduler, the_thread );
}
}
diff --git a/cpukit/score/src/threadsetpriority.c b/cpukit/score/src/threadsetpriority.c
index cfe069d4ae..b55de24b43 100644
--- a/cpukit/score/src/threadsetpriority.c
+++ b/cpukit/score/src/threadsetpriority.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -50,10 +51,6 @@ void _Thread_Set_priority(
)
{
the_thread->current_priority = new_priority;
- the_thread->ready = &_Thread_Ready_chain[ new_priority ];
- _Priority_bit_map_Initialize_information(
- &the_thread->Priority_map,
- new_priority
- );
+ _Scheduler_Thread_scheduler_update(&_Scheduler, the_thread);
}
diff --git a/cpukit/score/src/threadsetstate.c b/cpukit/score/src/threadsetstate.c
index 2edd3bb70d..73a71b70e2 100644
--- a/cpukit/score/src/threadsetstate.c
+++ b/cpukit/score/src/threadsetstate.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -54,9 +55,7 @@ void _Thread_Set_state(
)
{
ISR_Level level;
- Chain_Control *ready;
-
- ready = the_thread->ready;
+
_ISR_Disable( level );
if ( !_States_Is_ready( the_thread->current_state ) ) {
the_thread->current_state =
@@ -67,21 +66,7 @@ void _Thread_Set_state(
the_thread->current_state = state;
- if ( _Chain_Has_only_one_node( ready ) ) {
-
- _Chain_Initialize_empty( ready );
- _Priority_bit_map_Remove( &the_thread->Priority_map );
-
- } else
- _Chain_Extract_unprotected( &the_thread->Object.Node );
-
- _ISR_Flash( level );
-
- if ( _Thread_Is_heir( the_thread ) )
- _Thread_Calculate_heir();
-
- if ( _Thread_Is_executing( the_thread ) )
- _Thread_Dispatch_necessary = true;
+ _Scheduler_Block( &_Scheduler, the_thread);
_ISR_Enable( level );
}
diff --git a/cpukit/score/src/threadsettransient.c b/cpukit/score/src/threadsettransient.c
index 36f60a6077..ce697f2d02 100644
--- a/cpukit/score/src/threadsettransient.c
+++ b/cpukit/score/src/threadsettransient.c
@@ -23,6 +23,8 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -54,22 +56,15 @@ void _Thread_Set_transient(
{
ISR_Level level;
uint32_t old_state;
- Chain_Control *ready;
-
- ready = the_thread->ready;
+
_ISR_Disable( level );
old_state = the_thread->current_state;
the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state );
+ /* FIXME: need to check which scheduler to use? */
if ( _States_Is_ready( old_state ) ) {
- if ( _Chain_Has_only_one_node( ready ) ) {
-
- _Chain_Initialize_empty( ready );
- _Priority_bit_map_Remove( &the_thread->Priority_map );
-
- } else
- _Chain_Extract_unprotected( &the_thread->Object.Node );
+ _Scheduler_priority_Ready_queue_extract( the_thread);
}
_ISR_Enable( level );
diff --git a/cpukit/score/src/threadsuspend.c b/cpukit/score/src/threadsuspend.c
index 8cb2796691..8b4a631e5f 100644
--- a/cpukit/score/src/threadsuspend.c
+++ b/cpukit/score/src/threadsuspend.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -52,9 +53,7 @@ void _Thread_Suspend(
)
{
ISR_Level level;
- Chain_Control *ready;
-
- ready = the_thread->ready;
+
_ISR_Disable( level );
if ( !_States_Is_ready( the_thread->current_state ) ) {
the_thread->current_state =
@@ -65,21 +64,7 @@ void _Thread_Suspend(
the_thread->current_state = STATES_SUSPENDED;
- if ( _Chain_Has_only_one_node( ready ) ) {
-
- _Chain_Initialize_empty( ready );
- _Priority_bit_map_Remove( &the_thread->Priority_map );
-
- } else
- _Chain_Extract_unprotected( &the_thread->Object.Node );
-
- _ISR_Flash( level );
-
- if ( _Thread_Is_heir( the_thread ) )
- _Thread_Calculate_heir();
-
- if ( _Thread_Is_executing( the_thread ) )
- _Thread_Dispatch_necessary = true;
+ _Scheduler_Block(&_Scheduler, the_thread);
_ISR_Enable( level );
}
diff --git a/cpukit/score/src/threadtickletimeslice.c b/cpukit/score/src/threadtickletimeslice.c
index b05305650a..951339cb42 100644
--- a/cpukit/score/src/threadtickletimeslice.c
+++ b/cpukit/score/src/threadtickletimeslice.c
@@ -23,6 +23,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/states.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/thread.h>
@@ -89,7 +90,7 @@ void _Thread_Tickle_timeslice( void )
* currently executing thread is placed at the rear of the
* FIFO for this priority and a new heir is selected.
*/
- _Thread_Yield_processor();
+ _Scheduler_Yield( );
executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
}
break;