[PATCH 4/5] score: Static scheduler configuration

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Apr 4 15:07:40 UTC 2014


Do not allocate the scheduler control structures from the workspace.
This is a preparation step for configuration of clustered/partitioned
schedulers on SMP.
---
 cpukit/sapi/Makefile.am                            |    1 +
 cpukit/sapi/include/confdefs.h                     |  114 ++++++++--------
 cpukit/sapi/include/rtems/scheduler.h              |  137 ++++++++++++++++++++
 cpukit/sapi/preinstall.am                          |    4 +
 cpukit/score/include/rtems/score/scheduler.h       |   50 ++++++--
 cpukit/score/include/rtems/score/schedulercbs.h    |   15 ++-
 .../score/include/rtems/score/schedulercbsimpl.h   |    6 -
 cpukit/score/include/rtems/score/scheduleredf.h    |    5 +
 .../score/include/rtems/score/scheduleredfimpl.h   |    4 +-
 cpukit/score/include/rtems/score/schedulerimpl.h   |    4 +-
 .../score/include/rtems/score/schedulerpriority.h  |    7 +-
 .../include/rtems/score/schedulerpriorityimpl.h    |    4 +-
 .../include/rtems/score/schedulerprioritysmp.h     |    2 +-
 .../include/rtems/score/schedulerprioritysmpimpl.h |    2 +-
 cpukit/score/include/rtems/score/schedulersimple.h |    5 +
 .../include/rtems/score/schedulersimpleimpl.h      |    4 +-
 cpukit/score/include/rtems/score/schedulersmp.h    |    5 +
 cpukit/score/src/scheduler.c                       |    5 +-
 cpukit/score/src/schedulercbs.c                    |   10 --
 cpukit/score/src/schedulercbsattachthread.c        |    8 +-
 cpukit/score/src/schedulercbscleanup.c             |    3 +-
 cpukit/score/src/schedulercbscreateserver.c        |   11 +-
 cpukit/score/src/schedulercbsdestroyserver.c       |    7 +-
 cpukit/score/src/schedulercbsdetachthread.c        |    6 +-
 cpukit/score/src/schedulercbsgetapprovedbudget.c   |    4 +-
 cpukit/score/src/schedulercbsgetexecutiontime.c    |   10 +-
 cpukit/score/src/schedulercbsgetparameters.c       |    4 +-
 cpukit/score/src/schedulercbsgetremainingbudget.c  |    8 +-
 cpukit/score/src/schedulercbsgetserverid.c         |    4 +-
 cpukit/score/src/schedulercbssetparameters.c       |    4 +-
 cpukit/score/src/scheduleredf.c                    |    7 +-
 cpukit/score/src/schedulerpriority.c               |   13 +-
 cpukit/score/src/schedulerprioritysmp.c            |   11 +-
 cpukit/score/src/schedulersimple.c                 |    7 +-
 cpukit/score/src/schedulersimplesmp.c              |    8 +-
 doc/user/conf.t                                    |   12 +-
 testsuites/rhealstone/rhilatency/ilatency.c        |    6 +-
 testsuites/sptests/spinternalerror01/init.c        |    6 +-
 testsuites/sptests/spsize/size.c                   |    8 +-
 testsuites/tmtests/tm26/task1.c                    |    5 +-
 testsuites/tmtests/tm27/task1.c                    |    6 +-
 41 files changed, 358 insertions(+), 184 deletions(-)
 create mode 100644 cpukit/sapi/include/rtems/scheduler.h

diff --git a/cpukit/sapi/Makefile.am b/cpukit/sapi/Makefile.am
index 37a2fa4..4a2b6ca 100644
--- a/cpukit/sapi/Makefile.am
+++ b/cpukit/sapi/Makefile.am
@@ -17,6 +17,7 @@ include_rtems_HEADERS += include/rtems/cbs.h
 include_rtems_HEADERS += include/rtems/profiling.h
 include_rtems_HEADERS += include/rtems/rbheap.h
 include_rtems_HEADERS += include/rtems/rbtree.h
+include_rtems_HEADERS += include/rtems/scheduler.h
 include_rtems_HEADERS += include/rtems/sptables.h
 include_rtems_HEADERS += include/rtems/test.h
 include_rtems_HEADERS += include/rtems/timespec.h
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index 2a94654..dccf7ce 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -640,15 +640,10 @@ const rtems_libio_helper rtems_fs_init_helper =
  *
  * An application can define its own scheduling policy by defining
  * CONFIGURE_SCHEDULER_USER and the following:
- *    - CONFIGURE_SCHEDULER_OPERATIONS
- *    - CONFIGURE_MEMORY_FOR_SCHEDULER - base memory
+ *    - CONFIGURE_SCHEDULER_INSTANCE
+ *    - CONFIGURE_SCHEDULER_REGISTER
  *    - CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER - per task memory
  */
-#include <rtems/score/scheduler.h>
-
-#if !defined(RTEMS_SMP)
-  #undef CONFIGURE_SCHEDULER_SIMPLE_SMP
-#endif
 
 /* If no scheduler is specified, the priority scheduler is default. */
 #if !defined(CONFIGURE_SCHEDULER_USER) && \
@@ -666,21 +661,24 @@ const rtems_libio_helper rtems_fs_init_helper =
   #endif
 #endif
 
+#include <rtems/scheduler.h>
+
 /*
  * If the Priority Scheduler is selected, then configure for it.
  */
 #if defined(CONFIGURE_SCHEDULER_PRIORITY)
-  #include <rtems/score/schedulerpriority.h>
-  #define CONFIGURE_SCHEDULER_OPERATIONS &_Scheduler_priority_Operations
+  #define CONFIGURE_SCHEDULER_INSTANCE \
+    RTEMS_SCHEDULER_INSTANCE_PRIORITY( \
+      priority, \
+      CONFIGURE_MAXIMUM_PRIORITY + 1 \
+    )
+
+  #define CONFIGURE_SCHEDULER_REGISTER \
+    RTEMS_SCHEDULER_REGISTER_PRIORITY(priority)
 
   /**
    * This defines the memory used by the priority scheduler.
    */
-  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
-    _Configure_From_workspace( \
-      sizeof(Scheduler_priority_Control) +  \
-      ((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \
-  )
   #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
     _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
 #endif
@@ -690,17 +688,18 @@ const rtems_libio_helper rtems_fs_init_helper =
  * it.
  */
 #if defined(CONFIGURE_SCHEDULER_PRIORITY_SMP)
-  #include <rtems/score/schedulerprioritysmp.h>
-  #define CONFIGURE_SCHEDULER_OPERATIONS &_Scheduler_priority_SMP_Operations
+  #define CONFIGURE_SCHEDULER_INSTANCE \
+    RTEMS_SCHEDULER_INSTANCE_PRIORITY_SMP( \
+      priority_SMP, \
+      CONFIGURE_MAXIMUM_PRIORITY + 1 \
+    )
+
+  #define CONFIGURE_SCHEDULER_REGISTER \
+    RTEMS_SCHEDULER_REGISTER_PRIORITY_SMP(priority_SMP)
 
   /**
    * This defines the memory used by the priority scheduler.
    */
-  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
-    _Configure_From_workspace( \
-      sizeof(Scheduler_priority_SMP_Control) +  \
-      ((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \
-  )
   #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
     _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
 #endif
@@ -710,17 +709,18 @@ const rtems_libio_helper rtems_fs_init_helper =
  * it.
  */
 #if defined(CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP)
-  #include <rtems/score/schedulerpriorityaffinitysmp.h>
-  #define CONFIGURE_SCHEDULER_OPERATIONS &_Scheduler_priority_affinity_SMP_Operations
+  #define CONFIGURE_SCHEDULER_INSTANCE \
+    RTEMS_SCHEDULER_INSTANCE_PRIORITY_AFFINITY_SMP( \
+      priority_affinity_SMP, \
+      CONFIGURE_MAXIMUM_PRIORITY + 1 \
+    )
+
+  #define CONFIGURE_SCHEDULER_REGISTER \
+    RTEMS_SCHEDULER_REGISTER_PRIORITY_AFFINITY_SMP(priority_affinity_SMP)
 
   /**
    * This defines the memory used by the priority scheduler.
    */
-  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
-    _Configure_From_workspace( \
-      sizeof(Scheduler_SMP_Control) +  \
-      ((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \
-  )
   #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
     _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
 #endif
@@ -729,15 +729,13 @@ const rtems_libio_helper rtems_fs_init_helper =
  * If the Simple Priority Scheduler is selected, then configure for it.
  */
 #if defined(CONFIGURE_SCHEDULER_SIMPLE)
-  #include <rtems/score/schedulersimple.h>
-  #define CONFIGURE_SCHEDULER_OPERATIONS &_Scheduler_simple_Operations
+  #define CONFIGURE_SCHEDULER_INSTANCE RTEMS_SCHEDULER_INSTANCE_SIMPLE(simple)
+
+  #define CONFIGURE_SCHEDULER_REGISTER RTEMS_SCHEDULER_REGISTER_SIMPLE(simple)
 
   /**
    * define the memory used by the simple scheduler
    */
-  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
-    _Configure_From_workspace( sizeof( Scheduler_simple_Control ) ) \
-  )
   #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
 #endif
 
@@ -745,17 +743,17 @@ const rtems_libio_helper rtems_fs_init_helper =
  * If the Simple SMP Priority Scheduler is selected, then configure for it.
  */
 #if defined(CONFIGURE_SCHEDULER_SIMPLE_SMP)
-  #include <rtems/score/schedulersimplesmp.h>
-  #define CONFIGURE_SCHEDULER_OPERATIONS &_Scheduler_simple_SMP_Operations
+  #define CONFIGURE_SCHEDULER_INSTANCE \
+    RTEMS_SCHEDULER_INSTANCE_SIMPLE_SMP(simple_SMP)
+
+  #define CONFIGURE_SCHEDULER_REGISTER \
+    RTEMS_SCHEDULER_REGISTER_SIMPLE_SMP(simple_SMP)
 
   /**
    * Define the memory used by the Simple SMP Scheduler
    *
    * NOTE: This is the same as the Simple Scheduler
    */
-  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
-    _Configure_From_workspace( sizeof( Scheduler_simple_SMP_Control ) ) \
-  )
   #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
 #endif
 
@@ -763,14 +761,13 @@ const rtems_libio_helper rtems_fs_init_helper =
  * If the EDF Scheduler is selected, then configure for it.
  */
 #if defined(CONFIGURE_SCHEDULER_EDF)
-  #include <rtems/score/scheduleredf.h>
-  #define CONFIGURE_SCHEDULER_OPERATIONS &_Scheduler_EDF_Operations
+  #define CONFIGURE_SCHEDULER_INSTANCE RTEMS_SCHEDULER_INSTANCE_EDF(EDF)
+
+  #define CONFIGURE_SCHEDULER_REGISTER RTEMS_SCHEDULER_REGISTER_EDF(EDF)
 
   /**
    * define the memory used by the EDF scheduler
    */
-  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
-    _Configure_From_workspace(sizeof(Scheduler_EDF_Control)))
   #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
     _Configure_From_workspace(sizeof(Scheduler_EDF_Per_thread)))
 #endif
@@ -780,25 +777,25 @@ const rtems_libio_helper rtems_fs_init_helper =
  */
 #if defined(CONFIGURE_SCHEDULER_CBS)
   #include <rtems/score/schedulercbs.h>
-  #define CONFIGURE_SCHEDULER_OPERATIONS &_Scheduler_CBS_Operations
+  #define CONFIGURE_SCHEDULER_INSTANCE RTEMS_SCHEDULER_INSTANCE_CBS(CBS)
+
+  #define CONFIGURE_SCHEDULER_REGISTER RTEMS_SCHEDULER_REGISTER_CBS(CBS)
 
   #ifndef CONFIGURE_CBS_MAXIMUM_SERVERS
     #define CONFIGURE_CBS_MAXIMUM_SERVERS CONFIGURE_MAXIMUM_TASKS
   #endif
 
   #ifdef CONFIGURE_INIT
-    uint32_t _Scheduler_CBS_Maximum_servers = CONFIGURE_CBS_MAXIMUM_SERVERS;
+    const uint32_t _Scheduler_CBS_Maximum_servers =
+      CONFIGURE_CBS_MAXIMUM_SERVERS;
+
+    Scheduler_CBS_Server
+      _Scheduler_CBS_Server_list[ CONFIGURE_CBS_MAXIMUM_SERVERS ];
   #endif
 
   /**
    * define the memory used by the CBS scheduler
    */
-  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
-    _Configure_From_workspace(sizeof(Scheduler_EDF_Control)) + \
-      _Configure_From_workspace(CONFIGURE_CBS_MAXIMUM_SERVERS * \
-        sizeof(Scheduler_CBS_Server *)) + \
-      CONFIGURE_CBS_MAXIMUM_SERVERS * \
-        _Configure_From_workspace(sizeof(Scheduler_CBS_Server)))
   #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
     _Configure_From_workspace(sizeof(Scheduler_CBS_Per_thread)))
 #endif
@@ -808,11 +805,17 @@ const rtems_libio_helper rtems_fs_init_helper =
  * this code to know which scheduler is configured by the user.
  */
 #ifdef CONFIGURE_INIT
-  Scheduler_Control  _Scheduler = {
-    NULL,                             /* Scheduler Specific Data Pointer */
-    CONFIGURE_SCHEDULER_OPERATIONS    /* Scheduler Operations */
+  CONFIGURE_SCHEDULER_INSTANCE;
+
+  const Scheduler_Registration _Scheduler_Registration[] = {
+    CONFIGURE_SCHEDULER_REGISTER
   };
 
+  #if defined(RTEMS_SMP)
+    const size_t _Scheduler_Count =
+      RTEMS_ARRAY_SIZE( _Scheduler_Registration );
+  #endif
+
   #if defined(CONFIGURE_SCHEDULER_EDF)
     const bool _Scheduler_FIXME_thread_priority_queues_are_broken = true;
   #else
@@ -2191,7 +2194,6 @@ const rtems_libio_helper rtems_fs_init_helper =
  */
 #define CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
   ( CONFIGURE_MEMORY_FOR_IDLE_TASK +                /* IDLE and stack */ \
-    CONFIGURE_MEMORY_FOR_SCHEDULER +                /* Scheduler */ \
     CONFIGURE_INTERRUPT_VECTOR_TABLE +             /* interrupt vectors */ \
     CONFIGURE_INTERRUPT_STACK_MEMORY +             /* interrupt stack */ \
     CONFIGURE_API_MUTEX_MEMORY                     /* allocation mutex */ \
@@ -2470,7 +2472,7 @@ const rtems_libio_helper rtems_fs_init_helper =
       CONFIGURE_MULTIPROCESSING_TABLE,        /* pointer to MP config table */
     #endif
     #ifdef RTEMS_SMP
-      CONFIGURE_SMP_MAXIMUM_PROCESSORS
+      CONFIGURE_SMP_MAXIMUM_PROCESSORS,
     #endif
   };
 #endif
@@ -2552,7 +2554,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     uint32_t INTERRUPT_VECTOR_TABLE;
     uint32_t INTERRUPT_STACK_MEMORY;
     uint32_t MEMORY_FOR_IDLE_TASK;
-    uint32_t MEMORY_FOR_SCHEDULER;
     uint32_t MEMORY_PER_TASK_FOR_SCHEDULER;
 
     /* Classic API Pieces */
@@ -2609,7 +2610,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     CONFIGURE_INTERRUPT_VECTOR_TABLE,
     CONFIGURE_INTERRUPT_STACK_MEMORY,
     CONFIGURE_MEMORY_FOR_IDLE_TASK,
-    CONFIGURE_MEMORY_FOR_SCHEDULER,
     CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER,
 
     /* Classic API Pieces */
diff --git a/cpukit/sapi/include/rtems/scheduler.h b/cpukit/sapi/include/rtems/scheduler.h
new file mode 100644
index 0000000..e1a2b3b
--- /dev/null
+++ b/cpukit/sapi/include/rtems/scheduler.h
@@ -0,0 +1,137 @@
+/**
+ * @file
+ *
+ * @brief Scheduler Configuration API
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SAPI_SCHEDULER_H
+#define _RTEMS_SAPI_SCHEDULER_H
+
+#include <rtems/score/scheduler.h>
+
+#define RTEMS_SCHEDULER_INSTANCE_NAME( name ) \
+  _Configuration_Scheduler_ ## name
+
+/*
+ * This file should be only included in the context of <rtems/confdefs.h>.
+ * Define the scheduler configuration macros only in case the corresponding
+ * configure symbol is defined.  This is necessary to prevent invalid workspace
+ * size estimates since we have to account for the per-thread scheduler
+ * information.
+ */
+
+#ifdef CONFIGURE_SCHEDULER_CBS
+  #include <rtems/score/schedulercbs.h>
+
+  #define RTEMS_SCHEDULER_INSTANCE_CBS( name ) \
+    static Scheduler_EDF_Control RTEMS_SCHEDULER_INSTANCE_NAME( name )
+
+  #define RTEMS_SCHEDULER_REGISTER_CBS( name ) \
+    { \
+      &RTEMS_SCHEDULER_INSTANCE_NAME( name ).Base, \
+      &_Scheduler_CBS_Operations \
+    }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_EDF
+  #include <rtems/score/scheduleredf.h>
+
+  #define RTEMS_SCHEDULER_INSTANCE_EDF( name ) \
+    static Scheduler_EDF_Control RTEMS_SCHEDULER_INSTANCE_NAME( name )
+
+  #define RTEMS_SCHEDULER_REGISTER_EDF( name ) \
+    { \
+      &RTEMS_SCHEDULER_INSTANCE_NAME( name ).Base, \
+      &_Scheduler_EDF_Operations \
+    }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_PRIORITY
+  #include <rtems/score/schedulerpriority.h>
+
+  #define RTEMS_SCHEDULER_INSTANCE_PRIORITY( name, prio_count ) \
+    static struct { \
+      Scheduler_priority_Control Scheduler; \
+      Chain_Control              Ready[ ( prio_count ) ]; \
+    } RTEMS_SCHEDULER_INSTANCE_NAME( name );
+
+  #define RTEMS_SCHEDULER_REGISTER_PRIORITY( name ) \
+    { \
+      &RTEMS_SCHEDULER_INSTANCE_NAME( name ).Scheduler.Base, \
+      &_Scheduler_priority_Operations \
+    }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
+  #include <rtems/score/schedulerpriorityaffinitysmp.h>
+
+  #define RTEMS_SCHEDULER_INSTANCE_PRIORITY_AFFINITY_SMP( name, prio_count ) \
+    static struct { \
+      Scheduler_priority_SMP_Control Scheduler; \
+      Chain_Control                  Ready[ ( prio_count ) ]; \
+    } RTEMS_SCHEDULER_INSTANCE_NAME( name );
+
+  #define RTEMS_SCHEDULER_REGISTER_PRIORITY_AFFINITY_SMP( name ) \
+    { \
+      &RTEMS_SCHEDULER_INSTANCE_NAME( name ).Scheduler.Base, \
+      &_Scheduler_priority_affinity_SMP_Operations \
+    }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_PRIORITY_SMP
+  #include <rtems/score/schedulerprioritysmp.h>
+
+  #define RTEMS_SCHEDULER_INSTANCE_PRIORITY_SMP( name, prio_count ) \
+    static struct { \
+      Scheduler_priority_SMP_Control Scheduler; \
+      Chain_Control                  Ready[ ( prio_count ) ]; \
+    } RTEMS_SCHEDULER_INSTANCE_NAME( name );
+
+  #define RTEMS_SCHEDULER_REGISTER_PRIORITY_SMP( name ) \
+    { \
+      &RTEMS_SCHEDULER_INSTANCE_NAME( name ).Scheduler.Base, \
+      &_Scheduler_priority_SMP_Operations \
+    }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_SIMPLE
+  #include <rtems/score/schedulersimple.h>
+
+  #define RTEMS_SCHEDULER_INSTANCE_SIMPLE( name ) \
+    static Scheduler_simple_Control RTEMS_SCHEDULER_INSTANCE_NAME( name )
+
+  #define RTEMS_SCHEDULER_REGISTER_SIMPLE( name ) \
+    { \
+      &RTEMS_SCHEDULER_INSTANCE_NAME( name ).Base, \
+      &_Scheduler_simple_Operations \
+    }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_SIMPLE_SMP
+  #include <rtems/score/schedulersimplesmp.h>
+
+  #define RTEMS_SCHEDULER_INSTANCE_SIMPLE_SMP( name ) \
+    static Scheduler_simple_SMP_Control RTEMS_SCHEDULER_INSTANCE_NAME( name )
+
+  #define RTEMS_SCHEDULER_REGISTER_SIMPLE_SMP( name ) \
+    { \
+      &RTEMS_SCHEDULER_INSTANCE_NAME( name ).Base, \
+      &_Scheduler_simple_SMP_Operations \
+    }
+#endif
+
+#endif /* _RTEMS_SAPI_SCHEDULER_H */
diff --git a/cpukit/sapi/preinstall.am b/cpukit/sapi/preinstall.am
index 7e18d3a..57c5b97 100644
--- a/cpukit/sapi/preinstall.am
+++ b/cpukit/sapi/preinstall.am
@@ -84,6 +84,10 @@ $(PROJECT_INCLUDE)/rtems/rbtree.h: include/rtems/rbtree.h $(PROJECT_INCLUDE)/rte
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rbtree.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rbtree.h
 
+$(PROJECT_INCLUDE)/rtems/scheduler.h: include/rtems/scheduler.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/scheduler.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/scheduler.h
+
 $(PROJECT_INCLUDE)/rtems/sptables.h: include/rtems/sptables.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/sptables.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/sptables.h
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index e16bab6..9ea27b2 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -20,6 +20,7 @@
 #define _RTEMS_SCORE_SCHEDULER_H
 
 #include <stdbool.h>
+#include <stddef.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -42,29 +43,54 @@ typedef struct Scheduler_Control Scheduler_Control;
 typedef struct Scheduler_Operations Scheduler_Operations;
 
 /**
- * This is the structure used to manage the scheduler.
+ * @brief Scheduler control.
+ *
+ * The scheduler control of a particular scheduler implementation must place
+ * this structure at the begin of its control structure.
  */
 struct Scheduler_Control {
   /**
-   *  This points 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.
+   * @brief The scheduler operations.
    */
-  void                   *information;
-
-  /** The jump table for scheduler-specific functions */
   const Scheduler_Operations *operations;
 };
 
 /**
- *  The _Scheduler holds the structures used to manage the
- *  scheduler.
+ * @brief Scheduler registration.
+ */
+typedef struct {
+  /**
+   * @brief Reference to a statically allocated scheduler control.
+   */
+  struct Scheduler_Control *control;
+
+  /**
+   * @brief Reference to the scheduler operations.
+   */
+  const struct Scheduler_Operations *operations;
+} Scheduler_Registration;
+
+/**
+ * @brief Registered schedulers.
+ *
+ * Application provided via <rtems/confdefs.h>.
+ *
+ * @see _Scheduler_Count.
+ */
+extern const Scheduler_Registration _Scheduler_Registration[];
+
+/**
+ * @brief Count of registered schedulers.
  *
- * @note Can we make this per-cpu? then _Scheduler will be a macro.
+ * Application provided via <rtems/confdefs.h> on SMP configurations.
  *
- * @note This is instantiated and initialized in confdefs.h.
+ * @see _Scheduler_Registration.
  */
-extern Scheduler_Control  _Scheduler;
+#if defined(RTEMS_SMP)
+  extern const size_t _Scheduler_Count;
+#else
+  #define _Scheduler_Count ( (size_t) 1 )
+#endif
 
 /*
  * See also PR2174: Memory corruption with EDF scheduler and thread priority
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index 8217d55..f8df792 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -56,7 +56,7 @@ extern "C" {
 #define SCHEDULER_CBS_ERROR_NOSERVER           SCHEDULER_CBS_ERROR_NOT_FOUND
 
 /** Maximum number of simultaneous servers. */
-extern uint32_t _Scheduler_CBS_Maximum_servers;
+extern const uint32_t _Scheduler_CBS_Maximum_servers;
 
 /** Server id. */
 typedef uint32_t Scheduler_CBS_Server_id;
@@ -90,6 +90,13 @@ typedef struct {
   Scheduler_CBS_Parameters parameters;
   /** Callback function invoked when a budget overrun occurs. */
   Scheduler_CBS_Budget_overrun  cbs_budget_overrun;
+
+  /**
+   * @brief Indicates if this CBS server is initialized.
+   *
+   * @see _Scheduler_CBS_Create_server() and _Scheduler_CBS_Destroy_server().
+   */
+  bool initialized;
 } Scheduler_CBS_Server;
 
 /**
@@ -104,6 +111,12 @@ typedef struct {
 
 extern const Scheduler_Operations _Scheduler_CBS_Operations;
 
+/**
+ * List of servers. The @a Scheduler_CBS_Server is the index to the array
+ * of pointers to @a _Scheduler_CBS_Server_list.
+ */
+extern Scheduler_CBS_Server _Scheduler_CBS_Server_list[];
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpukit/score/include/rtems/score/schedulercbsimpl.h b/cpukit/score/include/rtems/score/schedulercbsimpl.h
index c1ed4df..0f59d97 100644
--- a/cpukit/score/include/rtems/score/schedulercbsimpl.h
+++ b/cpukit/score/include/rtems/score/schedulercbsimpl.h
@@ -26,12 +26,6 @@ extern "C" {
 #endif /* __cplusplus */
 
 /**
- * List of servers. The @a Scheduler_CBS_Server is the index to the array
- * of pointers to @a _Scheduler_CBS_Server_list.
- */
-extern Scheduler_CBS_Server **_Scheduler_CBS_Server_list;
-
-/**
  *  @brief Unblocks a thread from the queue.
  *
  *  This routine adds @a the_thread to the scheduling decision, that is,
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index 8ccf60f..cce1659 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -45,6 +45,11 @@ extern "C" {
 
 typedef struct {
   /**
+   * @brief Basic scheduler control.
+   */
+  Scheduler_Control Base;
+
+  /**
    * Top of the ready queue.
    */
   RBTree_Control Ready;
diff --git a/cpukit/score/include/rtems/score/scheduleredfimpl.h b/cpukit/score/include/rtems/score/scheduleredfimpl.h
index d36f322..5aa53b2 100644
--- a/cpukit/score/include/rtems/score/scheduleredfimpl.h
+++ b/cpukit/score/include/rtems/score/scheduleredfimpl.h
@@ -36,7 +36,7 @@ extern "C" {
  *
  * This routine initializes the EDF scheduler.
  */
-void _Scheduler_EDF_Initialize( void );
+void _Scheduler_EDF_Initialize( Scheduler_Control *scheduler_base );
 
 /**
  *  @brief Removes thread from ready queue.
@@ -211,7 +211,7 @@ void _Scheduler_EDF_Release_job (
 RTEMS_INLINE_ROUTINE Scheduler_EDF_Control *
   _Scheduler_EDF_Self_from_base( Scheduler_Control *scheduler_base )
 {
-  return (Scheduler_EDF_Control *) scheduler_base->information;
+  return (Scheduler_EDF_Control *) scheduler_base;
 }
 
 RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 32b4535..b0f5c4b 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -42,7 +42,7 @@ extern "C" {
  */
 struct Scheduler_Operations {
   /** Implements the scheduling decision logic (policy). */
-  void ( *initialize )(void);
+  void ( *initialize )( Scheduler_Control * );
 
   /** Implements the scheduling decision logic (policy). */
   void ( *schedule )( Scheduler_Control *, Thread_Control *);
@@ -509,7 +509,7 @@ RTEMS_INLINE_ROUTINE Scheduler_Control *_Scheduler_Get(
 {
   (void) the_thread;
 
-  return &_Scheduler;
+  return _Scheduler_Registration[ 0 ].control;
 }
 
 /**
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 33a7710..60cfbc5 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -36,6 +36,11 @@ extern "C" {
 
 typedef struct {
   /**
+   * @brief Basic scheduler control.
+   */
+  Scheduler_Control Base;
+
+  /**
    * @brief Bit map to indicate non-empty ready queues.
    */
   Priority_bit_map_Control Bit_map;
@@ -43,7 +48,7 @@ typedef struct {
   /**
    * @brief One ready queue per priority level.
    */
-  Chain_Control Ready[ 1 ];
+  Chain_Control Ready[ 0 ];
 } Scheduler_priority_Control;
 
 /**
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
index ceda148..8a84669 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
@@ -39,7 +39,7 @@ extern "C" {
  * @brief Initializes the priority scheduler.
  * This routine initializes the priority scheduler.
  */
-void _Scheduler_priority_Initialize(void);
+void _Scheduler_priority_Initialize( Scheduler_Control *scheduler_base );
 
 /**
  *  @brief Removes @a the_thread from the scheduling decision.
@@ -196,7 +196,7 @@ int _Scheduler_priority_Priority_compare(
 RTEMS_INLINE_ROUTINE Scheduler_priority_Control *
   _Scheduler_priority_Self_from_base( Scheduler_Control *scheduler_base )
 {
-  return (Scheduler_priority_Control *) scheduler_base->information;
+  return (Scheduler_priority_Control *) scheduler_base;
 }
 
 /**
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index 88c5985..3896753 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -49,7 +49,7 @@ extern "C" {
 typedef struct {
   Scheduler_SMP_Control    Base;
   Priority_bit_map_Control Bit_map;
-  Chain_Control            Ready[ 1 ];
+  Chain_Control            Ready[ 0 ];
 } Scheduler_priority_SMP_Control;
 
 extern const Scheduler_Operations _Scheduler_priority_SMP_Operations;
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmpimpl.h b/cpukit/score/include/rtems/score/schedulerprioritysmpimpl.h
index eb8c569..7aac003 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmpimpl.h
@@ -35,7 +35,7 @@ extern "C" {
  * @{
  */
 
-void _Scheduler_priority_SMP_Initialize( void );
+void _Scheduler_priority_SMP_Initialize( Scheduler_Control *base );
 
 void _Scheduler_priority_SMP_Schedule(
   Scheduler_Control *base,
diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
index e27c41c..66bd29c 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -37,6 +37,11 @@ extern "C" {
  */
 typedef struct {
   /**
+   * @brief Basic scheduler control.
+   */
+  Scheduler_Control Base;
+
+  /**
    * @brief One ready queue for all ready threads.
    */
   Chain_Control Ready;
diff --git a/cpukit/score/include/rtems/score/schedulersimpleimpl.h b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
index 0834e43..a4942e1 100644
--- a/cpukit/score/include/rtems/score/schedulersimpleimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
@@ -37,7 +37,7 @@ extern "C" {
  *
  *  This routine initializes the simple scheduler.
  */
-void _Scheduler_simple_Initialize( void );
+void _Scheduler_simple_Initialize( Scheduler_Control *scheduler_base );
 
 /**
  *  This routine sets the heir thread to be the next ready thread
@@ -168,7 +168,7 @@ void _Scheduler_simple_Ready_queue_enqueue_first(
 RTEMS_INLINE_ROUTINE Scheduler_simple_Control *
   _Scheduler_simple_Self_from_base( Scheduler_Control *scheduler_base )
 {
-  return (Scheduler_simple_Control *) scheduler_base->information;
+  return (Scheduler_simple_Control *) scheduler_base;
 }
 
 /**
diff --git a/cpukit/score/include/rtems/score/schedulersmp.h b/cpukit/score/include/rtems/score/schedulersmp.h
index 214d157..b76ad2d 100644
--- a/cpukit/score/include/rtems/score/schedulersmp.h
+++ b/cpukit/score/include/rtems/score/schedulersmp.h
@@ -39,6 +39,11 @@ extern "C" {
  */
 
 typedef struct {
+  /**
+   * @brief Basic scheduler control.
+   */
+  Scheduler_Control Base;
+
   Chain_Control Scheduled;
 } Scheduler_SMP_Control;
 
diff --git a/cpukit/score/src/scheduler.c b/cpukit/score/src/scheduler.c
index 70e2f42..af0b9b1 100644
--- a/cpukit/score/src/scheduler.c
+++ b/cpukit/score/src/scheduler.c
@@ -22,5 +22,8 @@
 
 void _Scheduler_Handler_initialization(void)
 {
-  ( *_Scheduler.operations->initialize )();
+  Scheduler_Control *scheduler = _Scheduler_Registration[ 0 ].control;
+
+  scheduler->operations = _Scheduler_Registration[ 0 ].operations;
+  ( *scheduler->operations->initialize )( scheduler );
 }
diff --git a/cpukit/score/src/schedulercbs.c b/cpukit/score/src/schedulercbs.c
index 105015c..593b54f 100644
--- a/cpukit/score/src/schedulercbs.c
+++ b/cpukit/score/src/schedulercbs.c
@@ -22,8 +22,6 @@
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/wkspace.h>
 
-Scheduler_CBS_Server **_Scheduler_CBS_Server_list;
-
 void _Scheduler_CBS_Budget_callout(
   Thread_Control *the_thread
 )
@@ -52,13 +50,5 @@ void _Scheduler_CBS_Budget_callout(
 
 int _Scheduler_CBS_Initialize(void)
 {
-  unsigned int i;
-  _Scheduler_CBS_Server_list = (Scheduler_CBS_Server **) _Workspace_Allocate(
-      _Scheduler_CBS_Maximum_servers * sizeof(Scheduler_CBS_Server*) );
-  if ( !_Scheduler_CBS_Server_list )
-    return SCHEDULER_CBS_ERROR_NO_MEMORY;
-  for (i = 0; i<_Scheduler_CBS_Maximum_servers; i++) {
-    _Scheduler_CBS_Server_list[i] = NULL;
-  }
   return SCHEDULER_CBS_OK;
 }
diff --git a/cpukit/score/src/schedulercbsattachthread.c b/cpukit/score/src/schedulercbsattachthread.c
index f0745d5..e5c06f8 100644
--- a/cpukit/score/src/schedulercbsattachthread.c
+++ b/cpukit/score/src/schedulercbsattachthread.c
@@ -33,11 +33,11 @@ int _Scheduler_CBS_Attach_thread (
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
 
   /* Server is not valid. */
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
 
   /* Server is already attached to a thread. */
-  if ( _Scheduler_CBS_Server_list[server_id]->task_id != -1 )
+  if ( _Scheduler_CBS_Server_list[server_id].task_id != -1 )
     return SCHEDULER_CBS_ERROR_FULL;
 
   the_thread = _Thread_Get(task_id, &location);
@@ -53,8 +53,8 @@ int _Scheduler_CBS_Attach_thread (
       return SCHEDULER_CBS_ERROR_FULL;
     }
 
-    _Scheduler_CBS_Server_list[server_id]->task_id = task_id;
-    sched_info->cbs_server = (void *) _Scheduler_CBS_Server_list[server_id];
+    _Scheduler_CBS_Server_list[server_id].task_id = task_id;
+    sched_info->cbs_server = &_Scheduler_CBS_Server_list[server_id];
 
     the_thread->budget_callout   = _Scheduler_CBS_Budget_callout;
     the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
diff --git a/cpukit/score/src/schedulercbscleanup.c b/cpukit/score/src/schedulercbscleanup.c
index f19930d..3765ee5 100644
--- a/cpukit/score/src/schedulercbscleanup.c
+++ b/cpukit/score/src/schedulercbscleanup.c
@@ -26,9 +26,8 @@ int _Scheduler_CBS_Cleanup (void)
   unsigned int i;
 
   for ( i = 0; i<_Scheduler_CBS_Maximum_servers; i++ ) {
-    if ( _Scheduler_CBS_Server_list[ i ] )
+    if ( _Scheduler_CBS_Server_list[ i ].initialized )
       _Scheduler_CBS_Destroy_server( i );
   }
-  _Workspace_Free( _Scheduler_CBS_Server_list );
   return SCHEDULER_CBS_OK;
 }
diff --git a/cpukit/score/src/schedulercbscreateserver.c b/cpukit/score/src/schedulercbscreateserver.c
index c9aff91..f7af3bb 100644
--- a/cpukit/score/src/schedulercbscreateserver.c
+++ b/cpukit/score/src/schedulercbscreateserver.c
@@ -19,7 +19,6 @@
 #endif
 
 #include <rtems/score/schedulercbsimpl.h>
-#include <rtems/score/wkspace.h>
 
 int _Scheduler_CBS_Create_server (
   Scheduler_CBS_Parameters     *params,
@@ -37,7 +36,7 @@ int _Scheduler_CBS_Create_server (
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
 
   for ( i = 0; i<_Scheduler_CBS_Maximum_servers; i++ ) {
-    if ( !_Scheduler_CBS_Server_list[i] )
+    if ( !_Scheduler_CBS_Server_list[i].initialized )
       break;
   }
 
@@ -45,14 +44,10 @@ int _Scheduler_CBS_Create_server (
     return SCHEDULER_CBS_ERROR_FULL;
 
   *server_id = i;
-  _Scheduler_CBS_Server_list[*server_id] = (Scheduler_CBS_Server *)
-    _Workspace_Allocate( sizeof(Scheduler_CBS_Server) );
-  the_server = _Scheduler_CBS_Server_list[*server_id];
-  if ( !the_server )
-    return SCHEDULER_CBS_ERROR_NO_MEMORY;
-
+  the_server = &_Scheduler_CBS_Server_list[*server_id];
   the_server->parameters = *params;
   the_server->task_id = -1;
   the_server->cbs_budget_overrun = budget_overrun_callback;
+  the_server->initialized = true;
   return SCHEDULER_CBS_OK;
 }
diff --git a/cpukit/score/src/schedulercbsdestroyserver.c b/cpukit/score/src/schedulercbsdestroyserver.c
index f221ef7..6c84e4a 100644
--- a/cpukit/score/src/schedulercbsdestroyserver.c
+++ b/cpukit/score/src/schedulercbsdestroyserver.c
@@ -32,13 +32,12 @@ int _Scheduler_CBS_Destroy_server (
   if ( server_id >= _Scheduler_CBS_Maximum_servers )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
 
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
 
-  if ( (tid = _Scheduler_CBS_Server_list[server_id]->task_id) != -1 )
+  if ( (tid = _Scheduler_CBS_Server_list[server_id].task_id) != -1 )
     ret = _Scheduler_CBS_Detach_thread ( server_id, tid );
 
-  _Workspace_Free( _Scheduler_CBS_Server_list[server_id] );
-  _Scheduler_CBS_Server_list[server_id] = NULL;
+  _Scheduler_CBS_Server_list[server_id].initialized = false;
   return ret;
 }
diff --git a/cpukit/score/src/schedulercbsdetachthread.c b/cpukit/score/src/schedulercbsdetachthread.c
index f9c3847..ad80999 100644
--- a/cpukit/score/src/schedulercbsdetachthread.c
+++ b/cpukit/score/src/schedulercbsdetachthread.c
@@ -34,16 +34,16 @@ int _Scheduler_CBS_Detach_thread (
   if ( server_id >= _Scheduler_CBS_Maximum_servers )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
   /* Server is not valid. */
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
   /* Thread and server are not attached. */
-  if ( _Scheduler_CBS_Server_list[server_id]->task_id != task_id )
+  if ( _Scheduler_CBS_Server_list[server_id].task_id != task_id )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
 
   the_thread = _Thread_Get(task_id, &location);
   /* The routine _Thread_Get may disable dispatch and not enable again. */
   if ( the_thread ) {
-    _Scheduler_CBS_Server_list[server_id]->task_id = -1;
+    _Scheduler_CBS_Server_list[server_id].task_id = -1;
     sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
     sched_info->cbs_server = NULL;
 
diff --git a/cpukit/score/src/schedulercbsgetapprovedbudget.c b/cpukit/score/src/schedulercbsgetapprovedbudget.c
index c73ec44..fa08cb3 100644
--- a/cpukit/score/src/schedulercbsgetapprovedbudget.c
+++ b/cpukit/score/src/schedulercbsgetapprovedbudget.c
@@ -27,9 +27,9 @@ int _Scheduler_CBS_Get_approved_budget (
 {
   if ( server_id >= _Scheduler_CBS_Maximum_servers )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
 
-  *approved_budget = _Scheduler_CBS_Server_list[server_id]->parameters.budget;
+  *approved_budget = _Scheduler_CBS_Server_list[server_id].parameters.budget;
   return SCHEDULER_CBS_OK;
 }
diff --git a/cpukit/score/src/schedulercbsgetexecutiontime.c b/cpukit/score/src/schedulercbsgetexecutiontime.c
index 49083d5..7a70f99 100644
--- a/cpukit/score/src/schedulercbsgetexecutiontime.c
+++ b/cpukit/score/src/schedulercbsgetexecutiontime.c
@@ -33,25 +33,25 @@ int _Scheduler_CBS_Get_execution_time (
 
   if ( server_id >= _Scheduler_CBS_Maximum_servers )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
-  if ( _Scheduler_CBS_Server_list[server_id]->task_id == -1 ) {
+  if ( _Scheduler_CBS_Server_list[server_id].task_id == -1 ) {
     *exec_time = 0;
     return SCHEDULER_CBS_OK;
   }
 
   the_thread = _Thread_Get(
-                 _Scheduler_CBS_Server_list[server_id]->task_id,
+                 _Scheduler_CBS_Server_list[server_id].task_id,
                  &location
                );
   /* The routine _Thread_Get may disable dispatch and not enable again. */
   if ( the_thread ) {
-    *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget -
+    *exec_time = _Scheduler_CBS_Server_list[server_id].parameters.budget -
       the_thread->cpu_time_budget;
     _Objects_Put( &the_thread->Object );
   }
   else {
-    *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget;
+    *exec_time = _Scheduler_CBS_Server_list[server_id].parameters.budget;
   }
   return SCHEDULER_CBS_OK;
 }
diff --git a/cpukit/score/src/schedulercbsgetparameters.c b/cpukit/score/src/schedulercbsgetparameters.c
index 74241ef..01b909f 100644
--- a/cpukit/score/src/schedulercbsgetparameters.c
+++ b/cpukit/score/src/schedulercbsgetparameters.c
@@ -27,9 +27,9 @@ int _Scheduler_CBS_Get_parameters (
 {
   if ( server_id >= _Scheduler_CBS_Maximum_servers )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
 
-  *params = _Scheduler_CBS_Server_list[server_id]->parameters;
+  *params = _Scheduler_CBS_Server_list[server_id].parameters;
   return SCHEDULER_CBS_OK;
 }
diff --git a/cpukit/score/src/schedulercbsgetremainingbudget.c b/cpukit/score/src/schedulercbsgetremainingbudget.c
index 624fc38..dd67d12 100644
--- a/cpukit/score/src/schedulercbsgetremainingbudget.c
+++ b/cpukit/score/src/schedulercbsgetremainingbudget.c
@@ -31,15 +31,15 @@ int _Scheduler_CBS_Get_remaining_budget (
 
   if ( server_id >= _Scheduler_CBS_Maximum_servers )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
-  if ( _Scheduler_CBS_Server_list[server_id]->task_id == -1 ) {
-    *remaining_budget = _Scheduler_CBS_Server_list[server_id]->parameters.budget;
+  if ( _Scheduler_CBS_Server_list[server_id].task_id == -1 ) {
+    *remaining_budget = _Scheduler_CBS_Server_list[server_id].parameters.budget;
     return SCHEDULER_CBS_OK;
   }
 
   the_thread = _Thread_Get(
-                 _Scheduler_CBS_Server_list[server_id]->task_id,
+                 _Scheduler_CBS_Server_list[server_id].task_id,
                  &location
                );
   /* The routine _Thread_Get may disable dispatch and not enable again. */
diff --git a/cpukit/score/src/schedulercbsgetserverid.c b/cpukit/score/src/schedulercbsgetserverid.c
index 7665ebb..fbeea3e 100644
--- a/cpukit/score/src/schedulercbsgetserverid.c
+++ b/cpukit/score/src/schedulercbsgetserverid.c
@@ -27,8 +27,8 @@ int _Scheduler_CBS_Get_server_id (
 {
   unsigned int i;
   for ( i = 0; i<_Scheduler_CBS_Maximum_servers; i++ ) {
-    if ( _Scheduler_CBS_Server_list[i] &&
-         _Scheduler_CBS_Server_list[i]->task_id == task_id ) {
+    if ( _Scheduler_CBS_Server_list[i].initialized &&
+         _Scheduler_CBS_Server_list[i].task_id == task_id ) {
       *server_id = i;
       return SCHEDULER_CBS_OK;
     }
diff --git a/cpukit/score/src/schedulercbssetparameters.c b/cpukit/score/src/schedulercbssetparameters.c
index 4c5fa25..fe5092a 100644
--- a/cpukit/score/src/schedulercbssetparameters.c
+++ b/cpukit/score/src/schedulercbssetparameters.c
@@ -35,9 +35,9 @@ int _Scheduler_CBS_Set_parameters (
        params->deadline >= SCHEDULER_EDF_PRIO_MSB )
     return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
 
-  if ( !_Scheduler_CBS_Server_list[server_id] )
+  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
     return SCHEDULER_CBS_ERROR_NOSERVER;
 
-  _Scheduler_CBS_Server_list[server_id]->parameters = *params;
+  _Scheduler_CBS_Server_list[server_id].parameters = *params;
   return SCHEDULER_CBS_OK;
 }
diff --git a/cpukit/score/src/scheduleredf.c b/cpukit/score/src/scheduleredf.c
index fb317cb..0e7a599 100644
--- a/cpukit/score/src/scheduleredf.c
+++ b/cpukit/score/src/scheduleredf.c
@@ -19,7 +19,6 @@
 #endif
 
 #include <rtems/score/scheduleredfimpl.h>
-#include <rtems/score/wkspace.h>
 
 static int _Scheduler_EDF_RBTree_compare_function
 (
@@ -39,16 +38,14 @@ static int _Scheduler_EDF_RBTree_compare_function
   return (-1)*_Scheduler_EDF_Priority_compare(value1, value2);
 }
 
-void _Scheduler_EDF_Initialize(void)
+void _Scheduler_EDF_Initialize( Scheduler_Control *scheduler_base )
 {
   Scheduler_EDF_Control *scheduler =
-    _Workspace_Allocate_or_fatal_error( sizeof( *scheduler ) );
+    _Scheduler_EDF_Self_from_base( scheduler_base );
 
   _RBTree_Initialize_empty(
     &scheduler->Ready,
     _Scheduler_EDF_RBTree_compare_function,
     0
   );
-
-  _Scheduler.information = scheduler;
 }
diff --git a/cpukit/score/src/schedulerpriority.c b/cpukit/score/src/schedulerpriority.c
index 9d1755d..d42a820 100644
--- a/cpukit/score/src/schedulerpriority.c
+++ b/cpukit/score/src/schedulerpriority.c
@@ -21,14 +21,11 @@
 #include <rtems/score/schedulerpriorityimpl.h>
 #include <rtems/score/wkspace.h>
 
-void _Scheduler_priority_Initialize(void)
+void _Scheduler_priority_Initialize( Scheduler_Control *scheduler_base )
 {
-  Scheduler_priority_Control *self = _Workspace_Allocate_or_fatal_error(
-    sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control )
-  );
+  Scheduler_priority_Control *scheduler =
+    _Scheduler_priority_Self_from_base( scheduler_base );
 
-  _Priority_bit_map_Initialize( &self->Bit_map );
-  _Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] );
-
-  _Scheduler.information = self;
+  _Priority_bit_map_Initialize( &scheduler->Bit_map );
+  _Scheduler_priority_Ready_queue_initialize( &scheduler->Ready[ 0 ] );
 }
diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c
index d19a570..f63cf71 100644
--- a/cpukit/score/src/schedulerprioritysmp.c
+++ b/cpukit/score/src/schedulerprioritysmp.c
@@ -33,7 +33,7 @@
 static Scheduler_priority_SMP_Control *
 _Scheduler_priority_SMP_Self_from_base( Scheduler_Control *base )
 {
-  return (Scheduler_priority_SMP_Control *) base->information;
+  return (Scheduler_priority_SMP_Control *) base;
 }
 
 static Scheduler_priority_SMP_Control *
@@ -44,17 +44,14 @@ _Scheduler_priority_SMP_Self_from_SMP_base( Scheduler_SMP_Control *smp_base )
       - offsetof( Scheduler_priority_SMP_Control, Base ) );
 }
 
-void _Scheduler_priority_SMP_Initialize( void )
+void _Scheduler_priority_SMP_Initialize( Scheduler_Control *base )
 {
-  Scheduler_priority_SMP_Control *self = _Workspace_Allocate_or_fatal_error(
-    sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control )
-  );
+  Scheduler_priority_SMP_Control *self =
+    _Scheduler_priority_SMP_Self_from_base( base );
 
   _Scheduler_SMP_Initialize( &self->Base );
   _Priority_bit_map_Initialize( &self->Bit_map );
   _Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] );
-
-  _Scheduler.information = self;
 }
 
 void _Scheduler_priority_SMP_Update(
diff --git a/cpukit/score/src/schedulersimple.c b/cpukit/score/src/schedulersimple.c
index b425e55..45377f4 100644
--- a/cpukit/score/src/schedulersimple.c
+++ b/cpukit/score/src/schedulersimple.c
@@ -21,14 +21,11 @@
 
 #include <rtems/score/schedulersimpleimpl.h>
 #include <rtems/score/chainimpl.h>
-#include <rtems/score/wkspace.h>
 
-void _Scheduler_simple_Initialize ( void )
+void _Scheduler_simple_Initialize( Scheduler_Control *scheduler_base )
 {
   Scheduler_simple_Control *scheduler =
-    _Workspace_Allocate_or_fatal_error( sizeof( *scheduler ) );
+    _Scheduler_simple_Self_from_base( scheduler_base );
 
   _Chain_Initialize_empty( &scheduler->Ready );
-
-  _Scheduler.information = scheduler;
 }
diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
index 7ea5f6f..002b5d1 100644
--- a/cpukit/score/src/schedulersimplesmp.c
+++ b/cpukit/score/src/schedulersimplesmp.c
@@ -26,7 +26,7 @@
 static Scheduler_simple_SMP_Control *
 _Scheduler_simple_SMP_Self_from_base( Scheduler_Control *base )
 {
-  return (Scheduler_simple_SMP_Control *) base->information;
+  return (Scheduler_simple_SMP_Control *) base;
 }
 
 static Scheduler_simple_SMP_Control *
@@ -36,15 +36,13 @@ _Scheduler_simple_SMP_Self_from_SMP_base( Scheduler_SMP_Control *smp_base )
     ( (char *) smp_base - offsetof( Scheduler_simple_SMP_Control, Base ) );
 }
 
-static void _Scheduler_simple_SMP_Initialize( void )
+static void _Scheduler_simple_SMP_Initialize( Scheduler_Control *base )
 {
   Scheduler_simple_SMP_Control *self =
-    _Workspace_Allocate_or_fatal_error( sizeof( *self ) );
+    _Scheduler_simple_SMP_Self_from_base( base );
 
   _Scheduler_SMP_Initialize( &self->Base );
   _Chain_Initialize_empty( &self->Ready );
-
-  _Scheduler.information = self;
 }
 
 static Thread_Control *_Scheduler_simple_SMP_Get_highest_ready(
diff --git a/doc/user/conf.t b/doc/user/conf.t
index a3f9824..ad3f269 100644
--- a/doc/user/conf.t
+++ b/doc/user/conf.t
@@ -3701,12 +3701,14 @@ own scheduling algorithm. If @code{CONFIGURE_SCHEDULER_USER} is defined
 then the following additional macros must be defined:
 
 @itemize @bullet
- at item @code{CONFIGURE_MEMORY_FOR_SCHEDULER} must be defined with the
-amount of memory required as a base amount for the scheduler.
+ at item @code{CONFIGURE_SCHEDULER_REGISTER} must be defined to a scheduler
+registration initializer for the user scheduler.
 
- at item @code{CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER(_tasks)} must be
-defined as a formula which computes the amount of memory required based
-upon the number of tasks configured.
+ at item @code{CONFIGURE_SCHEDULER_INSTANCE} must be defined to the scheduler
+control structure of the user scheduler.
+
+ at item @code{CONFIGURE_SCHEDULER_USER_PER_THREAD} must be defined to the type of
+the per-thread information of the user scheduler.
 
 @end itemize
 
diff --git a/testsuites/rhealstone/rhilatency/ilatency.c b/testsuites/rhealstone/rhilatency/ilatency.c
index b028ada..94ac796 100644
--- a/testsuites/rhealstone/rhilatency/ilatency.c
+++ b/testsuites/rhealstone/rhilatency/ilatency.c
@@ -16,6 +16,7 @@
 #define CONFIGURE_INIT
 #include <timesys.h>
 #include <rtems/timerdrv.h>
+#include <rtems/score/schedulerpriorityimpl.h>
 #include <coverhd.h>
 
 /* configuration information */
@@ -58,7 +59,10 @@ rtems_task Init(
 
   puts( "*** START OF RHILATENCY ***" );
 
-  if (_Scheduler.operations != &_Scheduler_priority_Operations) {
+  if (
+    _Scheduler_Get( _Thread_Get_executing() )->operations
+      != &_Scheduler_priority_Operations
+  ) {
     puts( "  Error ==> " );
     puts( "Test only supported for deterministic priority scheduler\n" );
     rtems_test_exit( 0 );
diff --git a/testsuites/sptests/spinternalerror01/init.c b/testsuites/sptests/spinternalerror01/init.c
index 71f9f68..30d99b2 100644
--- a/testsuites/sptests/spinternalerror01/init.c
+++ b/testsuites/sptests/spinternalerror01/init.c
@@ -70,11 +70,11 @@ static void *idle_body(uintptr_t ignored)
 
 #define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
 
-#define CONFIGURE_SCHEDULER_OPERATIONS NULL
-
 #define CONFIGURE_SCHEDULER_USER
 
-#define CONFIGURE_MEMORY_FOR_SCHEDULER 0
+#define CONFIGURE_SCHEDULER_INSTANCE
+
+#define CONFIGURE_SCHEDULER_REGISTER { NULL, NULL }
 
 #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER 0
 
diff --git a/testsuites/sptests/spsize/size.c b/testsuites/sptests/spsize/size.c
index 6acdaa6..647fd62 100644
--- a/testsuites/sptests/spsize/size.c
+++ b/testsuites/sptests/spsize/size.c
@@ -84,9 +84,6 @@ void print_formula(void);
 #include <rtems/score/prioritybitmapimpl.h>
 #include <rtems/score/schedulerpriority.h>
 
-/* Priority scheduling uninitialized (globals) consumption */
-#define SCHEDULER_OVHD      (sizeof _Scheduler)
-
 /* Priority scheduling per-thread consumption. Gets 
  * included in the PER_TASK consumption.
  */
@@ -94,8 +91,7 @@ void print_formula(void);
 
 /* Priority scheduling workspace consumption 
  *
- * Include allocation of ready queue.  Pointers are already counted by 
- * including _Scheduler in SCHEDULER_OVHD.
+ * Include allocation of ready queue.
  */
 #define SCHEDULER_WKSP_SIZE  \
     (sizeof(Scheduler_priority_Control) + \
@@ -355,8 +351,6 @@ uninitialized =
 
 /*rtems.h*/     /* Not applicable */
 
-/*scheduler.h*/ SCHEDULER_OVHD                            + 
-
 /*semimpl.h*/   (sizeof _Semaphore_Information)           +
 
 #if defined(RTEMS_MULTIPROCESSING)
diff --git a/testsuites/tmtests/tm26/task1.c b/testsuites/tmtests/tm26/task1.c
index 41c62a2..24078d2 100644
--- a/testsuites/tmtests/tm26/task1.c
+++ b/testsuites/tmtests/tm26/task1.c
@@ -223,7 +223,10 @@ rtems_task Init(
 
   TEST_BEGIN();
 
-  if (_Scheduler.operations != &_Scheduler_priority_Operations) {
+  if (
+    _Scheduler_Get( _Thread_Get_executing() )->operations
+      != &_Scheduler_priority_Operations
+  ) {
     puts("  Error ==> " );
     puts("Test only supported for deterministic priority scheduler\n" );
     TEST_END();
diff --git a/testsuites/tmtests/tm27/task1.c b/testsuites/tmtests/tm27/task1.c
index 13b878f..1773452 100644
--- a/testsuites/tmtests/tm27/task1.c
+++ b/testsuites/tmtests/tm27/task1.c
@@ -55,7 +55,11 @@ rtems_task Init(
   Print_Warning();
 
   TEST_BEGIN();
-  if (_Scheduler.operations != &_Scheduler_priority_Operations) {
+
+  if (
+    _Scheduler_Get( _Thread_Get_executing() )->operations
+      != &_Scheduler_priority_Operations
+  ) {
     puts("  Error ==> " );
     puts("Test only supported for deterministic priority scheduler\n" );
     TEST_END();
-- 
1.7.7




More information about the devel mailing list