diff options
Diffstat (limited to 'cpukit/score/src/threadcreateidle.c')
-rw-r--r-- | cpukit/score/src/threadcreateidle.c | 77 |
1 files changed, 62 insertions, 15 deletions
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c index 83d9bdcd8d..4f16a57099 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * @@ -11,26 +13,50 @@ * COPYRIGHT (c) 1989-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. + * 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 <rtems/score/threadidledata.h> #include <rtems/score/threadimpl.h> + #include <rtems/score/assert.h> +#include <rtems/score/cpuimpl.h> +#include <rtems/score/interr.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/stackimpl.h> #include <rtems/score/sysstate.h> +#include <rtems/score/threadidledata.h> +#include <rtems/score/tls.h> #include <rtems/score/userextimpl.h> #include <string.h> -static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) +static void _Thread_Create_idle_for_CPU( + Per_CPU_Control *cpu, + uintptr_t storage_size +) { Thread_Configuration config; Thread_Control *idle; @@ -46,18 +72,22 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) config.name = _Objects_Build_name( 'I', 'D', 'L', 'E' ); config.is_fp = CPU_IDLE_TASK_IS_FP; config.is_preemptible = true; - config.stack_size = _Thread_Idle_stack_size - + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE; + config.stack_free = _Objects_Free_nothing; + config.stack_size = storage_size; /* * The IDLE thread stacks may be statically allocated or there may be a * custom allocator provided just as with user threads. */ - config.stack_area = (*_Stack_Allocator_allocate_for_idle)( + config.stack_area = ( *_Stack_Allocator_allocate_for_idle )( _Per_CPU_Get_index( cpu ), - config.stack_size + &config.stack_size ); + if ( config.stack_size < storage_size ) { + _Internal_error( INTERNAL_ERROR_IDLE_THREAD_STACK_TOO_SMALL ); + } + /* * The entire workspace is zeroed during its initialization. Thus, all * fields not explicitly assigned were explicitly zeroed by @@ -67,13 +97,15 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) _Assert( idle != NULL ); status = _Thread_Initialize( &_Thread_Information, idle, &config ); - _Assert_Unused_variable_equals( status, STATUS_SUCCESSFUL ); + if ( status != STATUS_SUCCESSFUL ) { + _Internal_error( INTERNAL_ERROR_IDLE_THREAD_CREATE_FAILED ); + } /* * WARNING!!! This is necessary to "kick" start the system and * MUST be done before _Thread_Start is invoked. */ - cpu->heir = + cpu->heir = idle; cpu->executing = idle; #if defined(RTEMS_SMP) cpu->ancestor = idle; @@ -92,17 +124,32 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) void _Thread_Create_idle( void ) { - uint32_t cpu_max; - uint32_t cpu_index; + uintptr_t storage_size; +#if defined(RTEMS_SMP) + uint32_t cpu_max; + uint32_t cpu_index; +#endif - _System_state_Set( SYSTEM_STATE_BEFORE_MULTITASKING ); + storage_size = _TLS_Get_allocation_size() + + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE + + _Thread_Idle_stack_size; + +#if defined(RTEMS_SMP) cpu_max = _SMP_Get_processor_maximum(); for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) { Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index ); if ( _Per_CPU_Is_processor_online( cpu ) ) { - _Thread_Create_idle_for_CPU( cpu ); + _Thread_Create_idle_for_CPU( cpu, storage_size ); } } +#else + _Thread_Create_idle_for_CPU( _Per_CPU_Get(), storage_size ); +#endif + + _CPU_Use_thread_local_storage( + &_Per_CPU_Get_executing( _Per_CPU_Get() )->Registers + ); + _System_state_Set( SYSTEM_STATE_BEFORE_MULTITASKING ); } |