diff options
25 files changed, 200 insertions, 419 deletions
diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h index 7d40084ece..c1bb9a191c 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 cd3ac2a0ec..430157cf0f 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 6f79658677..ab197f3a51 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 263cc531d9..56dd12d7f0 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 209a43cb07..f989fff580 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 959514f850..e62e9175cd 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 07cb52022b..4cd89d792a 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 931f008c06..d4e1339afb 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 3abfdc5d99..e546c8d1e3 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 c6aba2dee2..fabce7e288 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 25866e5ba7..5c787239d0 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 7706bf32ce..b46c0fa29a 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 54fca12bf0..4f31722eb1 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 df8af184e3..8506623c8f 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 2765f56286..77e105bf28 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 1190b84254..a6f89c35a9 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 4efed5bad8..c865385dfb 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 68ae12450c..3dc9dd5070 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 3529ac9c41..0000000000 --- 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 2ab12b4824..0ea4336321 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 32feabb97b..0000000000 --- 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 b2daa26493..0000000000 --- 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 a77fe5fa8c..226e63af1a 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 6864df58e9..153c1d0b13 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 47c27929dd..422ee33a6d 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( |