[rtems commit] score: Simplify thread control initialization

Sebastian Huber sebh at rtems.org
Tue Apr 15 09:08:29 UTC 2014


Module:    rtems
Branch:    master
Commit:    69aa33490b1cd357519ab70b15ad150e11bb752e
Changeset: http://git.rtems.org/rtems/commit/?id=69aa33490b1cd357519ab70b15ad150e11bb752e

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Apr  8 09:42:29 2014 +0200

score: Simplify thread control initialization

The thread control block contains fields that point to application
configuration dependent memory areas, like the scheduler information,
the API control blocks, the user extension context table, the RTEMS
notepads and the Newlib re-entrancy support.  Account for these areas in
the configuration and avoid extra workspace allocations for these areas.

This helps also to avoid heap fragementation and reduces the per thread
memory due to a reduced heap allocation overhead.

---

 cpukit/libcsupport/include/rtems/libcsupport.h     |    7 +-
 cpukit/libcsupport/src/newlibc_reent.c             |   26 +---
 cpukit/posix/src/pthread.c                         |   25 +---
 cpukit/rtems/include/rtems/rtems/tasks.h           |    2 +-
 cpukit/rtems/src/tasks.c                           |   40 +-----
 cpukit/sapi/include/confdefs.h                     |  160 +++++++++-----------
 cpukit/score/Makefile.am                           |    3 -
 cpukit/score/include/rtems/score/scheduler.h       |    6 +-
 cpukit/score/include/rtems/score/schedulercbs.h    |    4 +-
 cpukit/score/include/rtems/score/scheduleredf.h    |   17 +--
 cpukit/score/include/rtems/score/schedulerimpl.h   |    2 +-
 .../score/include/rtems/score/schedulerpriority.h  |   30 +----
 .../rtems/score/schedulerpriorityaffinitysmp.h     |    4 +-
 .../include/rtems/score/schedulerprioritysmp.h     |    4 +-
 cpukit/score/include/rtems/score/thread.h          |   60 +++++++-
 cpukit/score/src/schedulercbsallocate.c            |   20 +--
 cpukit/score/src/schedulerdefaultallocatefree.c    |    4 +-
 cpukit/score/src/scheduleredfallocate.c            |   18 +--
 cpukit/score/src/scheduleredffree.c                |   36 -----
 cpukit/score/src/schedulerpriorityaffinitysmp.c    |    8 +-
 cpukit/score/src/schedulerpriorityallocate.c       |   38 -----
 cpukit/score/src/schedulerpriorityfree.c           |   35 -----
 cpukit/score/src/thread.c                          |    3 +-
 cpukit/score/src/threadinitialize.c                |   65 +++-----
 cpukit/score/src/threadrestart.c                   |    2 -
 25 files changed, 200 insertions(+), 419 deletions(-)

diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h
index 7d40084..c1bb9a1 100644
--- a/cpukit/libcsupport/include/rtems/libcsupport.h
+++ b/cpukit/libcsupport/include/rtems/libcsupport.h
@@ -85,11 +85,6 @@ bool newlib_create_hook(
 
 #define __RTEMS_NEWLIB_BEGIN 0
 
-void newlib_delete_hook(
-  rtems_tcb *current_task,
-  rtems_tcb *deleted_task
-);
-
 void newlib_terminate_hook(
   rtems_tcb *current_task
 );
@@ -99,7 +94,7 @@ void newlib_terminate_hook(
   newlib_create_hook,     /* rtems_task_create  */ \
   0,                      /* rtems_task_start   */ \
   0,                      /* rtems_task_restart */ \
-  newlib_delete_hook,     /* rtems_task_delete  */ \
+  0,                      /* rtems_task_delete  */ \
   0,                      /* task_switch  */ \
   __RTEMS_NEWLIB_BEGIN,   /* task_begin   */ \
   0,                      /* task_exitted */ \
diff --git a/cpukit/libcsupport/src/newlibc_reent.c b/cpukit/libcsupport/src/newlibc_reent.c
index cd3ac2a..430157c 100644
--- a/cpukit/libcsupport/src/newlibc_reent.c
+++ b/cpukit/libcsupport/src/newlibc_reent.c
@@ -35,9 +35,6 @@ bool newlib_create_hook(
   rtems_tcb *creating_task
 )
 {
-  struct _reent *ptr;
-  bool ok;
-
 #if !defined(__DYNAMIC_REENT__)
   if (_Thread_libc_reent == 0)
   {
@@ -47,28 +44,9 @@ bool newlib_create_hook(
   }
 #endif
 
-  /* It is OK to allocate from the workspace because these
-   * hooks run with thread dispatching disabled.
-   */
-  ptr = (struct _reent *) _Workspace_Allocate(sizeof(*ptr));
-  creating_task->libc_reent = ptr;
-  ok = ptr != NULL;
-
-  if (ok) {
-    _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */
-  }
-
-  return ok;
-}
-
-void newlib_delete_hook(
-  rtems_tcb *current_task,
-  rtems_tcb *deleted_task
-)
-{
-  (void) current_task;
+  _REENT_INIT_PTR((creating_task->libc_reent)); /* GCC extension: structure constants */
 
-  _Workspace_Free(deleted_task->libc_reent);
+  return true;
 }
 
 void newlib_terminate_hook(
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 6f79658..ab197f3 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -190,12 +190,7 @@ static bool _POSIX_Threads_Create_extension(
   POSIX_API_Control *api;
   POSIX_API_Control *executing_api;
 
-  api = _Workspace_Allocate( sizeof( POSIX_API_Control ) );
-
-  if ( !api )
-    return false;
-
-  created->API_Extensions[ THREAD_API_POSIX ] = api;
+  api = created->API_Extensions[ THREAD_API_POSIX ];
 
   /* XXX check all fields are touched */
   _POSIX_Threads_Initialize_attributes( &api->Attributes );
@@ -266,19 +261,6 @@ static void _POSIX_Threads_Restart_extension(
   _POSIX_Threads_cancel_run( restarted );
 }
 
-/*
- *  _POSIX_Threads_Delete_extension
- *
- *  This method is invoked for each thread deleted.
- */
-static void _POSIX_Threads_Delete_extension(
-  Thread_Control *executing __attribute__((unused)),
-  Thread_Control *deleted
-)
-{
-  _Workspace_Free( deleted->API_Extensions[ THREAD_API_POSIX ] );
-}
-
 static void _POSIX_Threads_Terminate_extension(
   Thread_Control *executing
 )
@@ -355,7 +337,7 @@ User_extensions_Control _POSIX_Threads_User_extensions = {
   { _POSIX_Threads_Create_extension,          /* create */
     NULL,                                     /* start */
     _POSIX_Threads_Restart_extension,         /* restart */
-    _POSIX_Threads_Delete_extension,          /* delete */
+    NULL,                                     /* delete */
     NULL,                                     /* switch */
     NULL,                                     /* begin */
     _POSIX_Threads_Exitted_extension,         /* exitted */
@@ -392,8 +374,7 @@ void _POSIX_Threads_Manager_initialization(void)
     OBJECTS_POSIX_THREADS,       /* object class */
     Configuration_POSIX_API.maximum_threads,
                                  /* maximum objects of this class */
-    sizeof( Thread_Control ),
-                                 /* size of this object's control block */
+    _Thread_Control_size,        /* size of this object's control block */
     true,                        /* true if names for this object are strings */
     _POSIX_PATH_MAX              /* maximum length of each object's name */
 #if defined(RTEMS_MULTIPROCESSING)
diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
index 263cc53..56dd12d 100644
--- a/cpukit/rtems/include/rtems/rtems/tasks.h
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -574,7 +574,7 @@ typedef struct {
    *
    *  @note MUST BE LAST ENTRY.
    */
-  uint32_t                 Notepads[ RTEMS_NUMBER_NOTEPADS ];
+  uint32_t                 Notepads[ RTEMS_ZERO_LENGTH_ARRAY ];
 }  RTEMS_API_Control;
 
 /**
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
index 209a43c..f989fff 100644
--- a/cpukit/rtems/src/tasks.c
+++ b/cpukit/rtems/src/tasks.c
@@ -50,23 +50,9 @@ static bool _RTEMS_tasks_Create_extension(
 )
 {
   RTEMS_API_Control *api;
-  int                i;
-  size_t             to_allocate;
+  size_t             i;
 
-  /*
-   *  Notepads must be the last entry in the structure and they
-   *  can be left off if disabled in the configuration.
-   */
-  to_allocate = sizeof( RTEMS_API_Control );
-  if ( !rtems_configuration_get_notepads_enabled() )
-    to_allocate -= (RTEMS_NUMBER_NOTEPADS * sizeof(uint32_t));
-
-  api = _Workspace_Allocate( to_allocate );
-
-  if ( !api )
-    return false;
-
-  created->API_Extensions[ THREAD_API_RTEMS ] = api;
+  api = created->API_Extensions[ THREAD_API_RTEMS ];
 
   _Event_Initialize( &api->Event );
   _Event_Initialize( &api->System_event );
@@ -104,24 +90,6 @@ static void _RTEMS_tasks_Start_extension(
   _Event_Initialize( &api->System_event );
 }
 
-/*
- *  _RTEMS_tasks_Delete_extension
- *
- *  This extension routine is invoked when a task is deleted.
- */
-
-static void _RTEMS_tasks_Delete_extension(
-  Thread_Control *executing,
-  Thread_Control *deleted
-)
-{
-  /*
-   *  Free API specific memory
-   */
-
-  (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_RTEMS ] );
-}
-
 static void _RTEMS_tasks_Terminate_extension(
   Thread_Control *executing
 )
@@ -204,7 +172,7 @@ User_extensions_Control _RTEMS_tasks_User_extensions = {
   { _RTEMS_tasks_Create_extension,            /* create */
     _RTEMS_tasks_Start_extension,             /* start */
     _RTEMS_tasks_Start_extension,             /* restart */
-    _RTEMS_tasks_Delete_extension,            /* delete */
+    NULL,                                     /* delete */
     RTEMS_TASKS_SWITCH_EXTENSION,             /* switch */
     NULL,                                     /* begin */
     NULL,                                     /* exitted */
@@ -221,7 +189,7 @@ void _RTEMS_tasks_Manager_initialization(void)
     OBJECTS_RTEMS_TASKS,       /* object class */
     Configuration_RTEMS_API.maximum_tasks,
                                /* maximum objects of this class */
-    sizeof( Thread_Control ),  /* size of this object's control block */
+    _Thread_Control_size,      /* size of this object's control block */
     false,                     /* true if the name is a string */
     RTEMS_MAXIMUM_NAME_LENGTH  /* maximum length of an object name */
 #if defined(RTEMS_MULTIPROCESSING)
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index 959514f..e62e917 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -641,7 +641,7 @@ const rtems_libio_helper rtems_fs_init_helper =
  * CONFIGURE_SCHEDULER_USER and the following:
  *    - CONFIGURE_SCHEDULER_CONTEXT
  *    - CONFIGURE_SCHEDULER_CONTROLS
- *    - CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER - per task memory
+ *    - CONFIGURE_SCHEDULER_USER_PER_THREAD
  */
 
 /* If no scheduler is specified, the priority scheduler is default. */
@@ -676,12 +676,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     #define CONFIGURE_SCHEDULER_CONTROLS \
       RTEMS_SCHEDULER_CONTROL_PRIORITY(dflt)
   #endif
-
-  /**
-   * This defines the memory used by the priority scheduler.
-   */
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
-    _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
 #endif
 
 /*
@@ -699,12 +693,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     #define CONFIGURE_SCHEDULER_CONTROLS \
       RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(dflt)
   #endif
-
-  /**
-   * This defines the memory used by the priority scheduler.
-   */
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
-    _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
 #endif
 
 /*
@@ -722,12 +710,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     #define CONFIGURE_SCHEDULER_CONTROLS \
       RTEMS_SCHEDULER_CONTROL_PRIORITY_AFFINITY_SMP(dflt)
   #endif
-
-  /**
-   * This defines the memory used by the priority scheduler.
-   */
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
-    _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
 #endif
 
 /*
@@ -739,11 +721,6 @@ const rtems_libio_helper rtems_fs_init_helper =
 
     #define CONFIGURE_SCHEDULER_CONTROLS RTEMS_SCHEDULER_CONTROL_SIMPLE(dflt)
   #endif
-
-  /**
-   * define the memory used by the simple scheduler
-   */
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
 #endif
 
 /*
@@ -757,13 +734,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     #define CONFIGURE_SCHEDULER_CONTROLS \
       RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(dflt)
   #endif
-
-  /**
-   * Define the memory used by the Simple SMP Scheduler
-   *
-   * NOTE: This is the same as the Simple Scheduler
-   */
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
 #endif
 
 /*
@@ -775,12 +745,6 @@ const rtems_libio_helper rtems_fs_init_helper =
 
     #define CONFIGURE_SCHEDULER_CONTROLS RTEMS_SCHEDULER_CONTROL_EDF(dflt)
   #endif
-
-  /**
-   * define the memory used by the EDF scheduler
-   */
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
-    _Configure_From_workspace(sizeof(Scheduler_EDF_Per_thread)))
 #endif
 
 /*
@@ -804,12 +768,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     Scheduler_CBS_Server
       _Scheduler_CBS_Server_list[ CONFIGURE_CBS_MAXIMUM_SERVERS ];
   #endif
-
-  /**
-   * define the memory used by the CBS scheduler
-   */
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
-    _Configure_From_workspace(sizeof(Scheduler_CBS_Per_thread)))
 #endif
 
 /*
@@ -1596,15 +1554,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     #define CONFIGURE_NOTEPADS_ENABLED           FALSE
   #endif
 
-  #ifndef CONFIGURE_DISABLE_CLASSIC_API_NOTEPADS
-    #define CONFIGURE_MEMORY_PER_TASK_FOR_CLASSIC_API \
-      _Configure_From_workspace( sizeof(RTEMS_API_Control) )
-  #else
-    #define CONFIGURE_MEMORY_PER_TASK_FOR_CLASSIC_API \
-      _Configure_From_workspace( sizeof(RTEMS_API_Control) - \
-        (RTEMS_NUMBER_NOTEPADS * sizeof(uint32_t)))
-  #endif
-
 /**
  * This macro calculates the memory required for task variables.
  *
@@ -1840,9 +1789,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     #define CONFIGURE_MAXIMUM_POSIX_THREADS 0
   #endif
 
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API \
-    _Configure_From_workspace(sizeof(POSIX_API_Control))
-
   #ifndef CONFIGURE_MAXIMUM_POSIX_MUTEXES
     #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 0
   #endif
@@ -1979,7 +1925,6 @@ const rtems_libio_helper rtems_fs_init_helper =
 #else
 
   #define CONFIGURE_MAXIMUM_POSIX_THREADS         0
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API 0
   #define CONFIGURE_MEMORY_FOR_POSIX              0
 
 #endif    /* RTEMS_POSIX_API */
@@ -2056,23 +2001,6 @@ const rtems_libio_helper rtems_fs_init_helper =
   #define CONFIGURE_MAXIMUM_GO_CHANNELS         0
 #endif
 
-#ifndef RTEMS_SCHEDSIM
-/**
- * This macro specifies the amount of memory to be reserved for the
- * Newlib C Library reentrancy structure -- if we are using newlib.
- */
-
-#if (defined(RTEMS_NEWLIB) && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY))
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB \
-    _Configure_From_workspace(sizeof(struct _reent))
-#else
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB 0
-#endif
-
-#else
-  #define CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB 0
-#endif
-
 /**
  * This is so we can account for tasks with stacks greater than minimum
  * size.  This is in bytes.
@@ -2104,17 +2032,7 @@ const rtems_libio_helper rtems_fs_init_helper =
 
 #define CONFIGURE_MEMORY_FOR_TASKS(_tasks, _number_FP_tasks) \
   ( \
-    _Configure_Object_RAM(_tasks, sizeof(Thread_Control)) \
-      + _Configure_Max_Objects(_tasks) \
-        * ( \
-            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_SCHEDULER \
-              + _Configure_From_workspace( \
-                (CONFIGURE_MAXIMUM_USER_EXTENSIONS + 1) * sizeof(void *) \
-              ) \
-          ) \
+    _Configure_Object_RAM(_tasks, sizeof(Configuration_Thread_control)) \
       + _Configure_Max_Objects(_number_FP_tasks) \
         * _Configure_From_workspace(CONTEXT_FP_SIZE) \
         * (CONTEXT_FP_SIZE != 0) \
@@ -2380,6 +2298,78 @@ const rtems_libio_helper rtems_fs_init_helper =
   )
 
 #ifdef CONFIGURE_INIT
+  typedef struct {
+    Thread_Control Control;
+    #if CONFIGURE_MAXIMUM_USER_EXTENSIONS > 0
+      void *extensions[ CONFIGURE_MAXIMUM_USER_EXTENSIONS + 1 ];
+    #endif
+    union {
+      #ifdef CONFIGURE_SCHEDULER_CBS
+        Scheduler_CBS_Per_thread CBS;
+      #endif
+      #ifdef CONFIGURE_SCHEDULER_EDF
+        Scheduler_EDF_Per_thread EDF;
+      #endif
+      #if defined(CONFIGURE_SCHEDULER_PRIORITY) \
+        || defined(CONFIGURE_SCHEDULER_PRIORITY_SMP)
+        Scheduler_priority_Per_thread Priority;
+      #endif
+      #ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
+        Scheduler_priority_affinity_SMP_Per_thread Priority_affinity;
+      #endif
+      #ifdef CONFIGURE_SCHEDULER_USER_PER_THREAD
+        CONFIGURE_SCHEDULER_USER_PER_THREAD User;
+      #endif
+    } Scheduler;
+    RTEMS_API_Control API_RTEMS;
+    #ifndef CONFIGURE_DISABLE_CLASSIC_API_NOTEPADS
+      uint32_t Notepads[ RTEMS_NUMBER_NOTEPADS ];
+    #endif
+    #ifdef RTEMS_POSIX_API
+      POSIX_API_Control API_POSIX;
+    #endif
+    #if !defined(RTEMS_SCHEDSIM) \
+      && defined(RTEMS_NEWLIB) \
+      && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY)
+      struct _reent Newlib;
+    #else
+      struct { /* Empty */ } Newlib;
+    #endif
+  } Configuration_Thread_control;
+
+  const size_t _Thread_Control_size = sizeof( Configuration_Thread_control );
+
+  const Thread_Control_add_on _Thread_Control_add_ons[] = {
+    {
+      offsetof( Configuration_Thread_control, Control.scheduler_info ),
+      offsetof( Configuration_Thread_control, Scheduler )
+    }, {
+      offsetof(
+        Configuration_Thread_control,
+        Control.API_Extensions[ THREAD_API_RTEMS ]
+      ),
+      offsetof( Configuration_Thread_control, API_RTEMS )
+    }, {
+      offsetof(
+        Configuration_Thread_control,
+        Control.libc_reent
+      ),
+      offsetof( Configuration_Thread_control, Newlib )
+    }
+    #ifdef RTEMS_POSIX_API
+      , {
+        offsetof(
+          Configuration_Thread_control,
+          Control.API_Extensions[ THREAD_API_POSIX ]
+        ),
+        offsetof( Configuration_Thread_control, API_POSIX )
+      }
+    #endif
+  };
+
+  const size_t _Thread_Control_add_on_count =
+    RTEMS_ARRAY_SIZE( _Thread_Control_add_ons );
+
   /**
    * This is the Classic API Configuration Table.
    */
@@ -2572,7 +2562,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_PER_TASK_FOR_SCHEDULER;
 
     /* Classic API Pieces */
     uint32_t CLASSIC_TASKS;
@@ -2628,7 +2617,6 @@ const rtems_libio_helper rtems_fs_init_helper =
     CONFIGURE_INTERRUPT_VECTOR_TABLE,
     CONFIGURE_INTERRUPT_STACK_MEMORY,
     CONFIGURE_MEMORY_FOR_IDLE_TASK,
-    CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER,
 
     /* Classic API Pieces */
     CONFIGURE_MEMORY_FOR_TASKS(CONFIGURE_MAXIMUM_TASKS, 0),
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 07cb520..4cd89d7 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -203,12 +203,10 @@ libscore_a_SOURCES += src/schedulerdefaultupdate.c
 
 ## SCHEDULERPRIORITY_C_FILES
 libscore_a_SOURCES += src/schedulerpriority.c \
-    src/schedulerpriorityallocate.c \
     src/schedulerpriorityblock.c \
     src/schedulerpriorityenqueue.c \
     src/schedulerpriorityenqueuefirst.c \
     src/schedulerpriorityextract.c \
-    src/schedulerpriorityfree.c \
     src/schedulerpriorityprioritycompare.c \
     src/schedulerpriorityschedule.c \
     src/schedulerpriorityunblock.c \
@@ -234,7 +232,6 @@ libscore_a_SOURCES += src/scheduleredf.c \
     src/scheduleredfenqueue.c \
     src/scheduleredfenqueuefirst.c \
     src/scheduleredfextract.c \
-    src/scheduleredffree.c \
     src/scheduleredfprioritycompare.c \
     src/scheduleredfreleasejob.c \
     src/scheduleredfschedule.c \
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index 931f008..d4e1339 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -67,7 +67,7 @@ typedef struct {
   void ( *unblock )( const Scheduler_Control *, Thread_Control * );
 
   /** allocates the scheduler field of the given thread */
-  void * ( *allocate )( const Scheduler_Control *, Thread_Control * );
+  bool ( *allocate )( const Scheduler_Control *, Thread_Control * );
 
   /** frees the scheduler field of the given thread */
   void ( *free )( const Scheduler_Control *, Thread_Control * );
@@ -199,9 +199,9 @@ extern const Scheduler_Control _Scheduler_Table[];
  * @param[in] scheduler Unused.
  * @param[in] the_thread Unused.
  *
- * @return An arbitrary non-NULL value.
+ * @retval true Always.
  */
-void *_Scheduler_default_Allocate(
+bool _Scheduler_default_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 );
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index 3abfdc5..e546c8d 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -53,7 +53,7 @@ extern "C" {
     _Scheduler_EDF_Block,            /* block entry point */ \
     _Scheduler_CBS_Unblock,          /* unblock entry point */ \
     _Scheduler_CBS_Allocate,         /* allocate entry point */ \
-    _Scheduler_EDF_Free,             /* free entry point */ \
+    _Scheduler_default_Free,         /* free entry point */ \
     _Scheduler_EDF_Update,           /* update entry point */ \
     _Scheduler_EDF_Enqueue,          /* enqueue entry point */ \
     _Scheduler_EDF_Enqueue_first,    /* enqueue_first entry point */ \
@@ -344,7 +344,7 @@ void _Scheduler_CBS_Budget_callout(
  *  @param[in] the_thread is the thread the scheduler is allocating
  *             management memory for.
  */
-void *_Scheduler_CBS_Allocate(
+bool _Scheduler_CBS_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 );
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index c6aba2d..fabce7e 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -46,7 +46,7 @@ extern "C" {
     _Scheduler_EDF_Block,            /* block entry point */ \
     _Scheduler_EDF_Unblock,          /* unblock entry point */ \
     _Scheduler_EDF_Allocate,         /* allocate entry point */ \
-    _Scheduler_EDF_Free,             /* free entry point */ \
+    _Scheduler_default_Free,         /* free entry point */ \
     _Scheduler_EDF_Update,           /* update entry point */ \
     _Scheduler_EDF_Enqueue,          /* enqueue entry point */ \
     _Scheduler_EDF_Enqueue_first,    /* enqueue_first entry point */ \
@@ -150,20 +150,7 @@ void _Scheduler_EDF_Schedule(
  *  @param[in] the_thread is the thread the scheduler is allocating
  *             management memory for.
  */
-void *_Scheduler_EDF_Allocate(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-);
-
-/**
- *  @brief Frees EDF information of a thread.
- *
- *  This routine frees the EDF specific information of @a the_thread.
- *
- *  @param[in] the_thread is the thread whose scheduler specific information
- *             will be deallocated.
- */
-void _Scheduler_EDF_Free(
+bool _Scheduler_EDF_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 );
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 25866e5..5c78723 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -124,7 +124,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock(
  *
  * This routine allocates @a the_thread->scheduler
  */
-RTEMS_INLINE_ROUTINE void* _Scheduler_Allocate(
+RTEMS_INLINE_ROUTINE bool _Scheduler_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 )
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 7706bf3..b46c0fa 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -52,8 +52,8 @@ extern "C" {
     _Scheduler_priority_Yield,            /* yield entry point */ \
     _Scheduler_priority_Block,            /* block entry point */ \
     _Scheduler_priority_Unblock,          /* unblock entry point */ \
-    _Scheduler_priority_Allocate,         /* allocate entry point */ \
-    _Scheduler_priority_Free,             /* free entry point */ \
+    _Scheduler_default_Allocate,         /* allocate entry point */ \
+    _Scheduler_default_Free,             /* free entry point */ \
     _Scheduler_priority_Update,           /* update entry point */ \
     _Scheduler_priority_Enqueue,          /* enqueue entry point */ \
     _Scheduler_priority_Enqueue_first,    /* enqueue_first entry point */ \
@@ -126,32 +126,6 @@ void _Scheduler_priority_Schedule(
 );
 
 /**
- *  @brief Allocates @a the_thread->scheduler.
- *
- *  This routine allocates @a the_thread->scheduler.
- *
- *  @param[in] the_thread is the thread the scheduler is allocating
- *             management memory for
- */
-void * _Scheduler_priority_Allocate(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-);
-
-/**
- *  @brief Frees @a the_thread->scheduler.
- *
- *  This routine frees @a the_thread->scheduler.
- *
- *  @param[in] the_thread is the thread whose scheduler specific information
- *             will be deallocated.
- */
-void _Scheduler_priority_Free(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-);
-
-/**
  *  @brief Update the scheduler priority.
  *  This routine updates @a the_thread->scheduler based on @a the_scheduler
  *  structures and thread state.
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index 54fca12..4f31722 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -55,7 +55,7 @@ extern "C" {
     _Scheduler_priority_SMP_Block, \
     _Scheduler_priority_SMP_Enqueue_fifo, \
     _Scheduler_priority_affinity_SMP_Allocate, \
-    _Scheduler_priority_Free, \
+    _Scheduler_default_Free, \
     _Scheduler_priority_SMP_Update, \
     _Scheduler_priority_SMP_Enqueue_fifo, \
     _Scheduler_priority_SMP_Enqueue_lifo, \
@@ -77,7 +77,7 @@ extern "C" {
  *  @param[in] the_thread is the thread the scheduler is allocating
  *             management memory for.
  */
-void * _Scheduler_priority_affinity_SMP_Allocate(
+bool _Scheduler_priority_affinity_SMP_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 );
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index df8af18..8506623 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -63,8 +63,8 @@ typedef struct {
     _Scheduler_priority_SMP_Yield, \
     _Scheduler_priority_SMP_Block, \
     _Scheduler_priority_SMP_Enqueue_fifo, \
-    _Scheduler_priority_Allocate, \
-    _Scheduler_priority_Free, \
+    _Scheduler_default_Allocate, \
+    _Scheduler_default_Free, \
     _Scheduler_priority_SMP_Update, \
     _Scheduler_priority_SMP_Enqueue_fifo, \
     _Scheduler_priority_SMP_Enqueue_lifo, \
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 2765f56..77e105b 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -566,8 +566,6 @@ struct Thread_Control_struct {
   struct _reent                        *libc_reent;
   /** This array contains the API extension area pointers. */
   void                                 *API_Extensions[ THREAD_API_LAST + 1 ];
-  /** This field points to the user extension pointers. */
-  void                                **extensions;
 
 #if !defined(RTEMS_SMP)
   /** This field points to the set of per task variables. */
@@ -584,6 +582,13 @@ struct Thread_Control_struct {
   Chain_Control           Key_Chain;
 
   Thread_Life_control                   Life;
+
+  /**
+   * @brief Variable length array of user extension pointers.
+   *
+   * The length is defined by the application via <rtems/confdefs.h>.
+   */
+  void                                 *extensions[ RTEMS_ZERO_LENGTH_ARRAY ];
 };
 
 #if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
@@ -638,6 +643,57 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get_executing( void )
   return executing;
 }
 
+/**
+ * @brief Thread control add-on.
+ */
+typedef struct {
+  /**
+   * @brief Offset of the pointer field in Thread_Control referencing an
+   * application configuration dependent memory area in the thread control
+   * block.
+   */
+  size_t destination_offset;
+
+  /**
+   * @brief Offset relative to the thread control block begin to an application
+   * configuration dependent memory area.
+   */
+  size_t source_offset;
+} Thread_Control_add_on;
+
+/**
+ * @brief Thread control add-ons.
+ *
+ * The thread control block contains fields that point to application
+ * configuration dependent memory areas, like the scheduler information, the
+ * API control blocks, the user extension context table, the RTEMS notepads and
+ * the Newlib re-entrancy support.  Account for these areas in the
+ * configuration and avoid extra workspace allocations for these areas.
+ *
+ * This array is provided via <rtems/confdefs.h>.
+ *
+ * @see _Thread_Control_add_on_count and _Thread_Control_size.
+ */
+extern const Thread_Control_add_on _Thread_Control_add_ons[];
+
+/**
+ * @brief Thread control add-on count.
+ *
+ * Count of entries in _Thread_Control_add_ons.
+ *
+ * This value is provided via <rtems/confdefs.h>.
+ */
+extern const size_t _Thread_Control_add_on_count;
+
+/**
+ * @brief Size of the thread control block of a particular application.
+ *
+ * This value is provided via <rtems/confdefs.h>.
+ *
+ * @see _Thread_Control_add_ons.
+ */
+extern const size_t _Thread_Control_size;
+
 /**@}*/
 
 #ifdef __cplusplus
diff --git a/cpukit/score/src/schedulercbsallocate.c b/cpukit/score/src/schedulercbsallocate.c
index 1190b84..a6f89c3 100644
--- a/cpukit/score/src/schedulercbsallocate.c
+++ b/cpukit/score/src/schedulercbsallocate.c
@@ -25,24 +25,18 @@
 #include <rtems/score/schedulercbs.h>
 #include <rtems/score/wkspace.h>
 
-void *_Scheduler_CBS_Allocate(
+bool _Scheduler_CBS_Allocate(
   const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
+  Thread_Control    *the_thread
 )
 {
-  void *sched;
-  Scheduler_CBS_Per_thread *schinfo;
+  Scheduler_CBS_Per_thread *schinfo = the_thread->scheduler_info;
 
   (void) scheduler;
 
-  sched = _Workspace_Allocate(sizeof(Scheduler_CBS_Per_thread));
-  if ( sched ) {
-    the_thread->scheduler_info = sched;
-    schinfo = (Scheduler_CBS_Per_thread *)(the_thread->scheduler_info);
-    schinfo->edf_per_thread.thread = the_thread;
-    schinfo->edf_per_thread.queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
-    schinfo->cbs_server = NULL;
-  }
+  schinfo->edf_per_thread.thread = the_thread;
+  schinfo->edf_per_thread.queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
+  schinfo->cbs_server = NULL;
 
-  return sched;
+  return true;
 }
diff --git a/cpukit/score/src/schedulerdefaultallocatefree.c b/cpukit/score/src/schedulerdefaultallocatefree.c
index 4efed5b..c865385 100644
--- a/cpukit/score/src/schedulerdefaultallocatefree.c
+++ b/cpukit/score/src/schedulerdefaultallocatefree.c
@@ -21,7 +21,7 @@
 
 #include <rtems/score/scheduler.h>
 
-void *_Scheduler_default_Allocate(
+bool _Scheduler_default_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 )
@@ -29,7 +29,7 @@ void *_Scheduler_default_Allocate(
   ( void ) scheduler;
   ( void ) the_thread;
 
-  return ( void * )-1; /* maybe pick an appropriate poison value */
+  return true;
 }
 
 void _Scheduler_default_Free(
diff --git a/cpukit/score/src/scheduleredfallocate.c b/cpukit/score/src/scheduleredfallocate.c
index 68ae124..3dc9dd5 100644
--- a/cpukit/score/src/scheduleredfallocate.c
+++ b/cpukit/score/src/scheduleredfallocate.c
@@ -24,24 +24,18 @@
 #include <rtems/score/scheduleredf.h>
 #include <rtems/score/wkspace.h>
 
-void *_Scheduler_EDF_Allocate(
+bool _Scheduler_EDF_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 )
 {
-  void *sched;
-  Scheduler_EDF_Per_thread *schinfo;
+  Scheduler_EDF_Per_thread *schinfo = the_thread->scheduler_info;
 
   (void) scheduler;
 
-  sched = _Workspace_Allocate( sizeof(Scheduler_EDF_Per_thread) );
+  schinfo = (Scheduler_EDF_Per_thread *)(the_thread->scheduler_info);
+  schinfo->thread = the_thread;
+  schinfo->queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
 
-  if ( sched ) {
-    the_thread->scheduler_info = sched;
-    schinfo = (Scheduler_EDF_Per_thread *)(the_thread->scheduler_info);
-    schinfo->thread = the_thread;
-    schinfo->queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
-  }
-
-  return sched;
+  return true;
 }
diff --git a/cpukit/score/src/scheduleredffree.c b/cpukit/score/src/scheduleredffree.c
deleted file mode 100644
index 3529ac9..0000000
--- a/cpukit/score/src/scheduleredffree.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @file
- *
- * @brief Frees EDF Thread Information
- *
- * @ingroup ScoreScheduler
- */
-
-/*
- *  Copyright (C) 2011 Petr Benes.
- *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/config.h>
-#include <rtems/score/scheduler.h>
-#include <rtems/score/scheduleredf.h>
-#include <rtems/score/wkspace.h>
-
-void _Scheduler_EDF_Free(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-)
-{
-  (void) scheduler;
-
-  _Workspace_Free( the_thread->scheduler_info );
-}
diff --git a/cpukit/score/src/schedulerpriorityaffinitysmp.c b/cpukit/score/src/schedulerpriorityaffinitysmp.c
index 2ab12b4..0ea4336 100644
--- a/cpukit/score/src/schedulerpriorityaffinitysmp.c
+++ b/cpukit/score/src/schedulerpriorityaffinitysmp.c
@@ -31,20 +31,18 @@ _Scheduler_priority_affinity_Get_scheduler_info( Thread_Control *thread )
   return ( Scheduler_priority_affinity_SMP_Per_thread * ) thread->scheduler_info;
 }
 
-void * _Scheduler_priority_affinity_SMP_Allocate(
+bool _Scheduler_priority_affinity_SMP_Allocate(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
 )
 {
   Scheduler_priority_affinity_SMP_Per_thread *info =
-    _Workspace_Allocate( sizeof( *info ) );
+    the_thread->scheduler_info;
 
   info->Affinity = *_CPU_set_Default();
   info->Affinity.set = &info->Affinity.preallocated;
- 
-  the_thread->scheduler_info = info;
 
-  return info;
+  return true;
 }
 
 bool _Scheduler_priority_affinity_SMP_Get_affinity(
diff --git a/cpukit/score/src/schedulerpriorityallocate.c b/cpukit/score/src/schedulerpriorityallocate.c
deleted file mode 100644
index 32feabb..0000000
--- a/cpukit/score/src/schedulerpriorityallocate.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *  @file
- *
- *  @brief Allocate Scheduler Priority
- *  @ingroup ScoreScheduler
- */
-
-/*
- *  Copyright (C) 2010 Gedare Bloom.
- *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/score/schedulerpriority.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/wkspace.h>
-
-void *_Scheduler_priority_Allocate (
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-)
-{
-  Scheduler_priority_Per_thread *sched_info_of_thread =
-    _Workspace_Allocate( sizeof( *sched_info_of_thread ) );
-
-  (void) scheduler;
-
-  the_thread->scheduler_info = sched_info_of_thread;
-
-  return sched_info_of_thread;
-}
diff --git a/cpukit/score/src/schedulerpriorityfree.c b/cpukit/score/src/schedulerpriorityfree.c
deleted file mode 100644
index b2daa26..0000000
--- a/cpukit/score/src/schedulerpriorityfree.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- *  @file
- *
- *  @brief Free Scheduler Priority
- *  @ingroup ScoreScheduler
- */
-
-/*
- *  Copyright (C) 2010 Gedare Bloom.
- *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/config.h>
-#include <rtems/score/scheduler.h>
-#include <rtems/score/schedulerpriority.h>
-#include <rtems/score/wkspace.h>
-
-void _Scheduler_priority_Free (
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-)
-{
-  (void) scheduler;
-
-  _Workspace_Free( the_thread->scheduler_info );
-}
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index a77fe5f..226e63a 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -64,8 +64,7 @@ void _Thread_Handler_initialization(void)
     OBJECTS_INTERNAL_API,
     OBJECTS_INTERNAL_THREADS,
     _Thread_Get_maximum_internal_threads(),
-    sizeof( Thread_Control ),
-                                /* size of this object's control block */
+    _Thread_Control_size,       /* size of this object's control block */
     false,                      /* true if names for this object are strings */
     8                           /* maximum length of each object's name */
     #if defined(RTEMS_MULTIPROCESSING)
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 6864df5..153c1d0 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -42,15 +42,15 @@ bool _Thread_Initialize(
   Objects_Name                          name
 )
 {
-  size_t     actual_stack_size = 0;
-  void      *stack = NULL;
+  size_t                   actual_stack_size = 0;
+  void                    *stack = NULL;
   #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-    void    *fp_area;
+    void                  *fp_area = NULL;
   #endif
-  void      *sched = NULL;
-  void      *extensions_area;
-  bool       extension_status;
-  int        i;
+  bool                     extension_status;
+  size_t                   i;
+  bool                     scheduler_allocated = false;
+  const Scheduler_Control *scheduler;
 
   /*
    * Do not use _TLS_Size here since this will lead GCC to assume that this
@@ -64,6 +64,13 @@ bool _Thread_Initialize(
   }
 #endif
 
+  for ( i = 0 ; i < _Thread_Control_add_on_count ; ++i ) {
+    const Thread_Control_add_on *add_on = &_Thread_Control_add_ons[ i ];
+
+    *(void **) ( (char *) the_thread + add_on->destination_offset ) =
+      (char *) the_thread + add_on->source_offset;
+  }
+
   /*
    *  Initialize the Ada self pointer
    */
@@ -71,20 +78,8 @@ bool _Thread_Initialize(
     the_thread->rtems_ada_self = NULL;
   #endif
 
-  /*
-   *  Zero out all the allocated memory fields
-   */
-  for ( i=0 ; i <= THREAD_API_LAST ; i++ )
-    the_thread->API_Extensions[i] = NULL;
-
-  extensions_area = NULL;
-  the_thread->libc_reent = NULL;
   the_thread->Start.tls_area = NULL;
 
-  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-    fp_area = NULL;
-  #endif
-
   /*
    *  Allocate and Initialize the stack for this thread.
    */
@@ -153,18 +148,6 @@ bool _Thread_Initialize(
   #endif
 
   /*
-   *  Allocate the extensions area for this thread
-   */
-  if ( rtems_configuration_get_maximum_extensions() ) {
-    extensions_area = _Workspace_Allocate(
-      (rtems_configuration_get_maximum_extensions() + 1) * sizeof( void * )
-    );
-    if ( !extensions_area )
-      goto failed;
-  }
-  the_thread->extensions = (void **) extensions_area;
-
-  /*
    * Clear the extensions area so extension users can determine
    * if they are linked to the thread. An extension user may
    * create the extension long after tasks have been created
@@ -215,9 +198,13 @@ bool _Thread_Initialize(
   the_thread->resource_count          = 0;
   the_thread->real_priority           = priority;
   the_thread->Start.initial_priority  = priority;
-  sched =_Scheduler_Allocate( _Scheduler_Get( the_thread ), the_thread );
-  if ( !sched )
+
+  scheduler = _Scheduler_Get( _Thread_Get_executing() );
+  scheduler_allocated = _Scheduler_Allocate( scheduler, the_thread );
+  if ( !scheduler_allocated ) {
     goto failed;
+  }
+
   _Thread_Set_priority( the_thread, priority );
 
   /*
@@ -260,21 +247,17 @@ bool _Thread_Initialize(
     return true;
 
 failed:
-  _Workspace_Free( the_thread->Start.tls_area );
-
-  _Workspace_Free( the_thread->libc_reent );
 
-  for ( i=0 ; i <= THREAD_API_LAST ; i++ )
-    _Workspace_Free( the_thread->API_Extensions[i] );
+  if ( scheduler_allocated ) {
+    _Scheduler_Free( scheduler, the_thread );
+  }
 
-  _Workspace_Free( extensions_area );
+  _Workspace_Free( the_thread->Start.tls_area );
 
   #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
     _Workspace_Free( fp_area );
   #endif
 
-   _Workspace_Free( sched );
-
    _Thread_Stack_Free( the_thread );
   return false;
 }
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index 47c2792..422ee33 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -91,8 +91,6 @@ static void _Thread_Free( Thread_Control *the_thread )
    */
   _Thread_Stack_Free( the_thread );
 
-  _Workspace_Free( the_thread->extensions );
-
   _Workspace_Free( the_thread->Start.tls_area );
 
   _Objects_Free(




More information about the vc mailing list