From 9fa3cf0db84cbabdb639cdeb7565f4c3ca3bc562 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 14 Dec 2011 13:17:19 +0000 Subject: 2011-12-14 Sebastian Huber PR 1924/cpukit * sapi/include/rtems/config.h: Added stack_allocate_init_hook to rtems_configuration_table. * sapi/include/confdefs.h: Added CONFIGURE_TASK_STACK_FROM_ALLOCATOR and CONFIGURE_TASK_STACK_ALLOCATOR_INIT defines. Set default stack allocator and free hook to _Workspace_Allocate() and _Workspace_Free() respectively. * score/src/thread.c, score/src/threadstackallocate.c, score/src/threadstackfree.c: Update due to API changes. --- cpukit/ChangeLog | 12 +++++++++ cpukit/sapi/include/confdefs.h | 47 ++++++++++++++++++++++++---------- cpukit/sapi/include/rtems/config.h | 44 ++++++++++++++++++++++++++----- cpukit/score/src/thread.c | 27 ++++++++++--------- cpukit/score/src/threadstackallocate.c | 33 +++++++++--------------- cpukit/score/src/threadstackfree.c | 8 +++--- 6 files changed, 113 insertions(+), 58 deletions(-) (limited to 'cpukit') diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index d523ea318e..43b26202a8 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,15 @@ +2011-12-14 Sebastian Huber + + PR 1924/cpukit + * sapi/include/rtems/config.h: Added stack_allocate_init_hook to + rtems_configuration_table. + * sapi/include/confdefs.h: Added CONFIGURE_TASK_STACK_FROM_ALLOCATOR + and CONFIGURE_TASK_STACK_ALLOCATOR_INIT defines. Set default stack + allocator and free hook to _Workspace_Allocate() and _Workspace_Free() + respectively. + * score/src/thread.c, score/src/threadstackallocate.c, + score/src/threadstackfree.c: Update due to API changes. + 2011-12-14 Sebastian Huber * libcsupport/src/termios_setinitialbaud.c: Fixed typo. diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index 169cb90761..9cd2954841 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -44,6 +44,7 @@ */ #include #include +#include #ifdef __cplusplus extern "C" { @@ -823,17 +824,24 @@ rtems_fs_init_functions_t rtems_fs_init_helper = #endif /** - * Configure the very much optional task stack allocator + * Configure the very much optional task stack allocator initialization */ -#ifndef CONFIGURE_TASK_STACK_ALLOCATOR - #define CONFIGURE_TASK_STACK_ALLOCATOR NULL +#ifndef CONFIGURE_TASK_STACK_ALLOCATOR_INIT + #define CONFIGURE_TASK_STACK_ALLOCATOR_INIT NULL #endif -/** - * Configure the very much optional task stack deallocator +/* + * Configure the very much optional task stack allocator and deallocator. */ -#ifndef CONFIGURE_TASK_STACK_DEALLOCATOR - #define CONFIGURE_TASK_STACK_DEALLOCATOR NULL +#if !defined(CONFIGURE_TASK_STACK_ALLOCATOR) \ + && !defined(CONFIGURE_TASK_STACK_DEALLOCATOR) + #define CONFIGURE_TASK_STACK_ALLOCATOR _Workspace_Allocate + #define CONFIGURE_TASK_STACK_DEALLOCATOR _Workspace_Free +#elif (defined(CONFIGURE_TASK_STACK_ALLOCATOR) \ + && !defined(CONFIGURE_TASK_STACK_DEALLOCATOR)) \ + || (!defined(CONFIGURE_TASK_STACK_ALLOCATOR) \ + && defined(CONFIGURE_TASK_STACK_DEALLOCATOR)) + #error "CONFIGURE_TASK_STACK_ALLOCATOR and CONFIGURE_TASK_STACK_DEALLOCATOR must be both defined or both undefined" #endif /** @@ -869,7 +877,6 @@ rtems_fs_init_functions_t rtems_fs_init_helper = #endif #ifdef CONFIGURE_UNIFIED_WORK_AREAS - #include Heap_Control *RTEMS_Malloc_Heap = &_Workspace_Area; #else Heap_Control RTEMS_Malloc_Area; @@ -928,6 +935,19 @@ rtems_fs_init_functions_t rtems_fs_init_helper = #define _Configure_From_workspace(_size) \ (ssize_t)((_size) + HEAP_BLOCK_HEADER_SIZE + CPU_HEAP_ALIGNMENT - 1) +/** + * This is a helper macro used in stack space calculations in this file. It + * may be provided by the application in case a special task stack allocator + * is used. The default is allocation from the RTEMS Workspace. + */ +#ifdef CONFIGURE_TASK_STACK_FROM_ALLOCATOR + #define _Configure_From_stackspace(_stack_size) \ + CONFIGURE_TASK_STACK_FROM_ALLOCATOR(_stack_size) +#else + #define _Configure_From_stackspace(_stack_size) \ + _Configure_From_workspace(_stack_size) +#endif + /** * Do not use the unlimited bit as part of the multiplication * for memory usage. @@ -2051,23 +2071,23 @@ rtems_fs_init_functions_t rtems_fs_init_helper = #define CONFIGURE_IDLE_TASKS_STACK \ (CONFIGURE_IDLE_TASKS_COUNT * \ - _Configure_From_workspace( CONFIGURE_IDLE_TASK_STACK_SIZE ) ) + _Configure_From_stackspace( CONFIGURE_IDLE_TASK_STACK_SIZE ) ) #define CONFIGURE_TASKS_STACK \ (_Configure_Max_Objects( CONFIGURE_MAXIMUM_TASKS ) * \ - _Configure_From_workspace( CONFIGURE_MINIMUM_TASK_STACK_SIZE ) ) + _Configure_From_stackspace( CONFIGURE_MINIMUM_TASK_STACK_SIZE ) ) #define CONFIGURE_POSIX_THREADS_STACK \ (_Configure_Max_Objects( CONFIGURE_MAXIMUM_POSIX_THREADS ) * \ - _Configure_From_workspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) ) + _Configure_From_stackspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) ) #define CONFIGURE_GOROUTINES_STACK \ (_Configure_Max_Objects( CONFIGURE_MAXIMUM_GOROUTINES ) * \ - _Configure_From_workspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) ) + _Configure_From_stackspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) ) #define CONFIGURE_ADA_TASKS_STACK \ (_Configure_Max_Objects( CONFIGURE_MAXIMUM_ADA_TASKS ) * \ - _Configure_From_workspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) ) + _Configure_From_stackspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) ) #else /* CONFIGURE_EXECUTIVE_RAM_SIZE */ @@ -2180,6 +2200,7 @@ rtems_fs_init_functions_t rtems_fs_init_helper = CONFIGURE_IDLE_TASK_BODY, /* user's IDLE task */ CONFIGURE_IDLE_TASK_STACK_SIZE, /* IDLE task stack size */ CONFIGURE_INTERRUPT_STACK_SIZE, /* interrupt stack size */ + CONFIGURE_TASK_STACK_ALLOCATOR_INIT, /* stack allocator init */ CONFIGURE_TASK_STACK_ALLOCATOR, /* stack allocator */ CONFIGURE_TASK_STACK_DEALLOCATOR, /* stack deallocator */ CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY, /* true to clear memory */ diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h index 590999c029..25ddfda421 100644 --- a/cpukit/sapi/include/rtems/config.h +++ b/cpukit/sapi/include/rtems/config.h @@ -84,6 +84,30 @@ typedef struct { } rtems_multiprocessing_table; #endif +/** + * @brief Task stack allocator initialization hook. + * + * @param[in] stack_space_size Size of the stack space in bytes. + */ +typedef void (*rtems_stack_allocate_init_hook)( size_t stack_space_size ); + +/** + * @brief Task stack allocator hook. + * + * @param[in] stack_size Size of the task stack in bytes. + * + * @retval NULL Not enough memory. + * @retval other Pointer to task stack. + */ +typedef void *(*rtems_stack_allocate_hook)( size_t stack_size ); + +/** + * @brief Task stack deallocator hook. + * + * @param[in] addr Pointer to previously allocated task stack. + */ +typedef void (*rtems_stack_free_hook)( void *addr ); + /* * The following records define the Configuration Table. The * information contained in this table is required in all @@ -139,15 +163,20 @@ typedef struct { */ uint32_t interrupt_stack_size; - /** The BSP may want to provide it's own stack allocation routines. - * In this case, the BSP will provide this stack allocation hook. + /** + * @brief Optional task stack allocator initialization hook. */ - void * (*stack_allocate_hook)( size_t ); + rtems_stack_allocate_init_hook stack_allocate_init_hook; - /** The BSP may want to provide it's own stack free routines. - * In this case, the BSP will provide this stack free hook. + /** + * @brief Optional task stack allocator hook. */ - void (*stack_free_hook)( void *); + rtems_stack_allocate_hook stack_allocate_hook; + + /** + * @brief Optional task stack free hook. + */ + rtems_stack_free_hook stack_free_hook; /** If this element is TRUE, then RTEMS will zero the Executive Workspace. * When this element is FALSE, it is assumed that the BSP or invoking @@ -268,6 +297,9 @@ extern rtems_configuration_table Configuration; #define rtems_configuration_get_interrupt_stack_size() \ (Configuration.interrupt_stack_size) +#define rtems_configuration_get_stack_allocate_init_hook() \ + (Configuration.stack_allocate_init_hook) + #define rtems_configuration_get_stack_allocate_hook() \ (Configuration.stack_allocate_hook) diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c index 3736f6eda8..613ef77e92 100644 --- a/cpukit/score/src/thread.c +++ b/cpukit/score/src/thread.c @@ -49,30 +49,29 @@ void _Thread_Handler_initialization(void) { - uint32_t ticks_per_timeslice; - uint32_t maximum_extensions; + uint32_t ticks_per_timeslice = + rtems_configuration_get_ticks_per_timeslice(); + uint32_t maximum_extensions = + rtems_configuration_get_maximum_extensions(); + rtems_stack_allocate_init_hook stack_allocate_init_hook = + rtems_configuration_get_stack_allocate_init_hook(); uint32_t maximum_internal_threads; #if defined(RTEMS_MULTIPROCESSING) - uint32_t maximum_proxies; + uint32_t maximum_proxies = + _Configuration_MP_table->maximum_proxies; #endif - ticks_per_timeslice = Configuration.ticks_per_timeslice; - maximum_extensions = Configuration.maximum_extensions; - #if defined(RTEMS_MULTIPROCESSING) - maximum_proxies = _Configuration_MP_table->maximum_proxies; - #endif - /* - * BOTH stacks hooks must be set or both must be NULL. - * Do not allow mixture. - */ - if ( !( (!Configuration.stack_allocate_hook) - == (!Configuration.stack_free_hook) ) ) + if ( rtems_configuration_get_stack_allocate_hook() == NULL || + rtems_configuration_get_stack_free_hook() == NULL) _Internal_error_Occurred( INTERNAL_ERROR_CORE, true, INTERNAL_ERROR_BAD_STACK_HOOK ); + if ( stack_allocate_init_hook != NULL ) + (*stack_allocate_init_hook)( rtems_configuration_get_stack_space_size() ); + _Thread_Dispatch_necessary = false; _Thread_Executing = NULL; _Thread_Heir = NULL; diff --git a/cpukit/score/src/threadstackallocate.c b/cpukit/score/src/threadstackallocate.c index 0989161f1e..9448328365 100644 --- a/cpukit/score/src/threadstackallocate.c +++ b/cpukit/score/src/threadstackallocate.c @@ -46,33 +46,24 @@ size_t _Thread_Stack_Allocate( { void *stack_addr = 0; size_t the_stack_size; + rtems_stack_allocate_hook stack_allocate_hook = + rtems_configuration_get_stack_allocate_hook(); the_stack_size = _Stack_Ensure_minimum( stack_size ); /* - * Call ONLY the CPU table stack allocate hook, _or_ the - * the RTEMS workspace allocate. This is so the stack free - * routine can call the correct deallocation routine. + * Pad the requested size so we allocate enough memory + * so the context initialization can align it properly. The address + * returned the workspace allocate must be directly stored in the + * stack control block because it is later used in the free sequence. + * + * Thus it is the responsibility of the CPU dependent code to + * get and keep the stack adjust factor, the stack alignment, and + * the context initialization sequence in sync. */ + the_stack_size = _Stack_Adjust_size( the_stack_size ); - if ( Configuration.stack_allocate_hook ) { - stack_addr = (*Configuration.stack_allocate_hook)( the_stack_size ); - } else { - - /* - * First pad the requested size so we allocate enough memory - * so the context initialization can align it properly. The address - * returned the workspace allocate must be directly stored in the - * stack control block because it is later used in the free sequence. - * - * Thus it is the responsibility of the CPU dependent code to - * get and keep the stack adjust factor, the stack alignment, and - * the context initialization sequence in sync. - */ - - the_stack_size = _Stack_Adjust_size( the_stack_size ); - stack_addr = _Workspace_Allocate( the_stack_size ); - } + stack_addr = (*stack_allocate_hook)( the_stack_size ); if ( !stack_addr ) the_stack_size = 0; diff --git a/cpukit/score/src/threadstackfree.c b/cpukit/score/src/threadstackfree.c index 64e0278e1b..926c1e9eb1 100644 --- a/cpukit/score/src/threadstackfree.c +++ b/cpukit/score/src/threadstackfree.c @@ -41,6 +41,9 @@ void _Thread_Stack_Free( Thread_Control *the_thread ) { + rtems_stack_free_hook stack_free_hook = + rtems_configuration_get_stack_free_hook(); + #if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API) /* * If the API provided the stack space, then don't free it. @@ -55,8 +58,5 @@ void _Thread_Stack_Free( * routine properly matches the allocation of the stack. */ - if ( Configuration.stack_free_hook ) - (*Configuration.stack_free_hook)( the_thread->Start.Initial_stack.area ); - else - _Workspace_Free( the_thread->Start.Initial_stack.area ); + (*stack_free_hook)( the_thread->Start.Initial_stack.area ); } -- cgit v1.2.3