From aedd92d1477df0025821b77c06b2f2b2dc7aaf67 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 9 Apr 2020 12:11:19 +0200 Subject: score: Add stack free handler to TCB This avoids a dependency to the stack free function in the thread destruction. Update #3959. --- cpukit/Makefile.am | 1 + cpukit/include/rtems/score/stackimpl.h | 7 +++++ cpukit/include/rtems/score/thread.h | 5 ++-- cpukit/include/rtems/score/threadimpl.h | 6 ++-- cpukit/posix/src/pthreadcreate.c | 4 ++- cpukit/rtems/src/taskcreate.c | 2 +- cpukit/score/src/stackallocatorfreenothing.c | 45 ++++++++++++++++++++++++++++ cpukit/score/src/threadinitialize.c | 30 +++++++++---------- cpukit/score/src/threadrestart.c | 2 +- 9 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 cpukit/score/src/stackallocatorfreenothing.c diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am index a8cc9b2b1d..e5009e53c9 100644 --- a/cpukit/Makefile.am +++ b/cpukit/Makefile.am @@ -933,6 +933,7 @@ librtemscpu_a_SOURCES += score/src/schedulercbsreleasejob.c librtemscpu_a_SOURCES += score/src/schedulercbsunblock.c librtemscpu_a_SOURCES += score/src/stackallocator.c librtemscpu_a_SOURCES += score/src/stackallocatorfree.c +librtemscpu_a_SOURCES += score/src/stackallocatorfreenothing.c librtemscpu_a_SOURCES += score/src/stackallocatorinit.c librtemscpu_a_SOURCES += score/src/pheapallocate.c librtemscpu_a_SOURCES += score/src/pheapextend.c diff --git a/cpukit/include/rtems/score/stackimpl.h b/cpukit/include/rtems/score/stackimpl.h index 305c4e4e51..df9f87d5a3 100644 --- a/cpukit/include/rtems/score/stackimpl.h +++ b/cpukit/include/rtems/score/stackimpl.h @@ -166,6 +166,13 @@ void *_Stack_Allocate( size_t stack_size ); */ void _Stack_Free( void *stack_area ); +/** + * @brief This function does nothing. + * + * @param stack_area is not used. + */ +void _Stack_Free_nothing( void *stack_area ); + /** @} */ #ifdef __cplusplus diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h index ee0aee5b79..1daf6143f9 100644 --- a/cpukit/include/rtems/score/thread.h +++ b/cpukit/include/rtems/score/thread.h @@ -194,10 +194,9 @@ typedef struct { /** This field is the initial priority. */ Priority_Control initial_priority; /** - * @brief This field is a pointer to the allocated stack area, otherwise it - * is NULL. + * @brief This field points to the handler which should free the stack. */ - void *allocated_stack; + void ( *stack_free )( void * ); /** This field is the stack information. */ Stack_Control Initial_stack; #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h index 0b69caf962..61454eb7fe 100644 --- a/cpukit/include/rtems/score/threadimpl.h +++ b/cpukit/include/rtems/score/threadimpl.h @@ -144,9 +144,11 @@ typedef struct { size_t stack_size; /** - * @brief The address of the allocated stack area or NULL. + * @brief This member contains the handler to free the stack. + * + * It shall not be NULL. Use _Stack_Free_nothing() if nothing is to free. */ - void *allocated_stack; + void ( *stack_free )( void * ); /** * @brief The new thread's priority. diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index d431c64a3e..33c5f8d03a 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -218,8 +218,10 @@ int pthread_create( } if ( config.stack_area == NULL ) { + config.stack_free = _Stack_Free; config.stack_area = _Stack_Allocate( config.stack_size ); - config.allocated_stack = config.stack_area; + } else { + config.stack_free = _Stack_Free_nothing; } status = ( config.stack_area != NULL ); diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c index b430d3c705..5486ac9b6e 100644 --- a/cpukit/rtems/src/taskcreate.c +++ b/cpukit/rtems/src/taskcreate.c @@ -146,8 +146,8 @@ rtems_status_code rtems_task_create( } #endif + config.stack_free = _Stack_Free; config.stack_area = _Stack_Allocate( config.stack_size ); - config.allocated_stack = config.stack_area; status = ( config.stack_area != NULL ); /* diff --git a/cpukit/score/src/stackallocatorfreenothing.c b/cpukit/score/src/stackallocatorfreenothing.c new file mode 100644 index 0000000000..b469f650b6 --- /dev/null +++ b/cpukit/score/src/stackallocatorfreenothing.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSScoreStack + * + * @brief _Stack_Free_nothing() Implementation + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +void _Stack_Free_nothing( void *stack_area ) +{ + (void) stack_area; +} diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 4872f84950..4a74426498 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -36,8 +36,8 @@ bool _Thread_Initialize( uintptr_t tls_size; bool extension_status; size_t i; - char *stack_area; - size_t stack_size; + char *stack_begin; + char *stack_end; Scheduler_Node *scheduler_node; #if defined(RTEMS_SMP) Scheduler_Node *scheduler_node_for_index; @@ -61,7 +61,7 @@ bool _Thread_Initialize( /* Set everything to perform the error case clean up */ scheduler_index = 0; - the_thread->Start.allocated_stack = config->allocated_stack; + the_thread->Start.stack_free = config->stack_free; #if defined(RTEMS_SMP) if ( @@ -83,16 +83,15 @@ bool _Thread_Initialize( } #endif - stack_area = config->stack_area; - stack_size = config->stack_size; + stack_begin = config->stack_area; + stack_end = stack_begin + config->stack_size; /* Allocate floating-point context in stack area */ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) if ( config->is_fp ) { - the_thread->fp_context = ( Context_Control_fp *) stack_area; - the_thread->Start.fp_context = ( Context_Control_fp *) stack_area; - stack_size -= CONTEXT_FP_SIZE; - stack_area += CONTEXT_FP_SIZE; + stack_end -= CONTEXT_FP_SIZE; + the_thread->fp_context = (Context_Control_fp *) stack_end; + the_thread->Start.fp_context = (Context_Control_fp *) stack_end; } #endif @@ -102,17 +101,16 @@ bool _Thread_Initialize( if ( tls_size > 0 ) { uintptr_t tls_align; + stack_end -= tls_size; tls_align = (uintptr_t) _TLS_Alignment; the_thread->Start.tls_area = (void *) - ( ( (uintptr_t) stack_area + tls_align - 1 ) & ~( tls_align - 1 ) ); - stack_size -= tls_size; - stack_area += tls_size; + ( ( (uintptr_t) stack_end + tls_align - 1 ) & ~( tls_align - 1 ) ); } _Stack_Initialize( - &the_thread->Start.Initial_stack, - stack_area, - stack_size + &the_thread->Start.Initial_stack, + stack_begin, + stack_end - stack_begin ); /* @@ -279,6 +277,6 @@ failed: &information->Thread_queue_heads.Free, the_thread->Wait.spare_heads ); - _Stack_Free( the_thread->Start.allocated_stack ); + ( *the_thread->Start.stack_free )( the_thread->Start.Initial_stack.area ); return false; } diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c index a2712fa061..3350bfe464 100644 --- a/cpukit/score/src/threadrestart.c +++ b/cpukit/score/src/threadrestart.c @@ -185,7 +185,7 @@ static void _Thread_Free( Thread_Control *the_thread ) * Free the rest of the memory associated with this task * and set the associated pointers to NULL for safety. */ - _Stack_Free( the_thread->Start.allocated_stack ); + ( *the_thread->Start.stack_free )( the_thread->Start.Initial_stack.area ); #if defined(RTEMS_SMP) _ISR_lock_Destroy( &the_thread->Scheduler.Lock ); -- cgit v1.2.3