diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-12-09 10:12:14 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-02-12 09:08:36 +0100 |
commit | f4dbf37dd432623c345f8e19f78a4eb01fcedb8b (patch) | |
tree | cb18eb86ccce8ab3fff22c9c4543ddaf9d93b183 /cpukit/score | |
parent | score: Simplify FP context allocation (diff) | |
download | rtems-f4dbf37dd432623c345f8e19f78a4eb01fcedb8b.tar.bz2 |
score: Simplify TLS area allocation
Use the stack area to allocate the TLS area.
Update #3835.
Diffstat (limited to 'cpukit/score')
-rw-r--r-- | cpukit/score/src/configstackspacesize.c | 54 | ||||
-rw-r--r-- | cpukit/score/src/threadinitialize.c | 30 | ||||
-rw-r--r-- | cpukit/score/src/threadrestart.c | 2 | ||||
-rw-r--r-- | cpukit/score/src/tlsallocsize.c | 72 | ||||
-rw-r--r-- | cpukit/score/src/wkspace.c | 38 |
5 files changed, 141 insertions, 55 deletions
diff --git a/cpukit/score/src/configstackspacesize.c b/cpukit/score/src/configstackspacesize.c new file mode 100644 index 0000000000..4f0c24cee6 --- /dev/null +++ b/cpukit/score/src/configstackspacesize.c @@ -0,0 +1,54 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2014, 2019 embedded brains GmbH + * + * 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/config.h> +#include <rtems/score/stack.h> +#include <rtems/score/tls.h> +#include <rtems/score/thread.h> + +uintptr_t rtems_configuration_get_stack_space_size( void ) +{ + uintptr_t space_size; + + space_size = _Stack_Space_size; + + /* + * In case we have a non-zero TLS size, then we need a TLS area for each + * thread. These areas are allocated within the stack area from the stack + * space. Ensure that the stack space is large enough to fulfill all requests + * known at configuration time (so excluding the unlimited option). It is not + * possible to estimate the TLS size in the configuration at compile-time. + * The TLS size is determined at application link-time. + */ + space_size += _Thread_Initial_thread_count * _TLS_Get_allocation_size(); + + return space_size; +} diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 48444824b2..a1bc3b2939 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -42,7 +42,7 @@ bool _Thread_Initialize( Objects_Name name ) { - uintptr_t tls_size = _TLS_Get_size(); + uintptr_t tls_size; bool extension_status; size_t i; Scheduler_Node *scheduler_node; @@ -83,6 +83,8 @@ bool _Thread_Initialize( (char *) the_thread + add_on->source_offset; } + tls_size = _TLS_Get_allocation_size(); + /* Allocate the stack for this thread */ #if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API) if ( stack_area == NULL ) { @@ -95,6 +97,7 @@ bool _Thread_Initialize( } #endif + stack_size += tls_size; stack_area = _Stack_Allocate( stack_size ); if ( stack_area == NULL ) { @@ -116,6 +119,17 @@ bool _Thread_Initialize( } #endif + /* Allocate thread-local storage (TLS) area in stack area */ + if ( tls_size > 0 ) { + uintptr_t tls_align; + + 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 = (char *) stack_area + tls_size; + } + _Stack_Initialize( &the_thread->Start.Initial_stack, stack_area, @@ -124,19 +138,6 @@ bool _Thread_Initialize( scheduler_index = 0; - /* Thread-local storage (TLS) area allocation */ - if ( tls_size > 0 ) { - uintptr_t tls_align = _TLS_Heap_align_up( (uintptr_t) _TLS_Alignment ); - uintptr_t tls_alloc = _TLS_Get_allocation_size( tls_size, tls_align ); - - the_thread->Start.tls_area = - _Workspace_Allocate_aligned( tls_alloc, tls_align ); - - if ( the_thread->Start.tls_area == NULL ) { - goto failed; - } - } - /* * Get thread queue heads */ @@ -301,7 +302,6 @@ failed: } #endif - _Workspace_Free( the_thread->Start.tls_area ); _Freechain_Put( &information->Thread_queue_heads.Free, the_thread->Wait.spare_heads diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c index aa47fefd1f..0c6890324c 100644 --- a/cpukit/score/src/threadrestart.c +++ b/cpukit/score/src/threadrestart.c @@ -185,8 +185,6 @@ static void _Thread_Free( Thread_Control *the_thread ) */ _Stack_Free( the_thread->Start.allocated_stack ); - _Workspace_Free( the_thread->Start.tls_area ); - #if defined(RTEMS_SMP) _ISR_lock_Destroy( &the_thread->Scheduler.Lock ); _ISR_lock_Destroy( &the_thread->Wait.Lock.Default ); diff --git a/cpukit/score/src/tlsallocsize.c b/cpukit/score/src/tlsallocsize.c new file mode 100644 index 0000000000..046579814a --- /dev/null +++ b/cpukit/score/src/tlsallocsize.c @@ -0,0 +1,72 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2014, 2019 embedded brains GmbH + * + * 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/score/tls.h> + +static uintptr_t _TLS_Allocation_size; + +uintptr_t _TLS_Get_allocation_size( void ) +{ + uintptr_t size; + uintptr_t allocation_size; + uintptr_t alignment; + + size = _TLS_Get_size(); + + if ( size == 0 ) { + return 0; + } + + allocation_size = _TLS_Allocation_size; + + if ( allocation_size == 0 ) { + allocation_size = _TLS_Heap_align_up( size ); + alignment = _TLS_Heap_align_up( (uintptr_t) _TLS_Alignment ); + + /* + * The stack allocator does not support aligned allocations. Allocate + * enough to do the alignment manually. + */ + if ( alignment > CPU_HEAP_ALIGNMENT ) { + allocation_size += alignment; + } + + allocation_size += _TLS_Get_thread_control_block_area_size( alignment ); + +#ifndef __i386__ + allocation_size += sizeof(TLS_Dynamic_thread_vector); +#endif + + _TLS_Allocation_size = allocation_size; + } + + return allocation_size; +} diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c index 5a87ee4b83..fbdb0b0ba9 100644 --- a/cpukit/score/src/wkspace.c +++ b/cpukit/score/src/wkspace.c @@ -23,7 +23,6 @@ #include <rtems/score/heapimpl.h> #include <rtems/score/interr.h> #include <rtems/score/threadimpl.h> -#include <rtems/score/tls.h> #include <rtems/posix/pthread.h> #include <rtems/config.h> #include <rtems/sysinit.h> @@ -37,41 +36,6 @@ Heap_Control _Workspace_Area; -static uintptr_t _Workspace_Space_for_TLS( uintptr_t page_size ) -{ - uintptr_t tls_size; - uintptr_t space; - - tls_size = _TLS_Get_size(); - - /* - * In case we have a non-zero TLS size, then we need a TLS area for each - * thread. These areas are allocated from the workspace. Ensure that the - * workspace is large enough to fulfill all requests known at configuration - * time (so excluding the unlimited option). It is not possible to estimate - * the TLS size in the configuration at compile-time. The TLS size is - * determined at application link-time. - */ - if ( tls_size > 0 ) { - uintptr_t tls_align = _TLS_Heap_align_up( (uintptr_t) _TLS_Alignment ); - uintptr_t tls_alloc = _TLS_Get_allocation_size( tls_size, tls_align ); - - /* - * Memory allocated with an alignment constraint is allocated from the end - * of a free block. The last allocation may need one free block of minimum - * size. - */ - space = _Heap_Min_block_size( page_size ); - - space += _Thread_Initial_thread_count - * _Heap_Size_with_overhead( page_size, tls_alloc, tls_align ); - } else { - space = 0; - } - - return space; -} - static void _Workspace_Initialize( void ) { _Workspace_Handler_initialization( _Memory_Get(), _Heap_Extend ); @@ -97,8 +61,6 @@ void _Workspace_Handler_initialization( page_size = CPU_HEAP_ALIGNMENT; remaining = rtems_configuration_get_work_space_size(); - remaining += _Workspace_Space_for_TLS( page_size ); - init_or_extend = _Heap_Initialize; unified = rtems_configuration_get_unified_work_area(); overhead = _Heap_Area_overhead( page_size ); |