Make the initialization of the per-CPU data optional. --- cpukit/Makefile.am | 1 + cpukit/include/rtems/score/percpudata.h | 14 ++++ cpukit/sapi/src/exinit.c | 13 ---- cpukit/score/src/percpudata.c | 94 ++++++++++++++++++++++++ cpukit/score/src/smp.c | 42 ----------- spec/build/cpukit/librtemscpu.yml | 1 + testsuites/smptests/smpfatal09/init.c | 2 + testsuites/sptests/sppercpudata01/init.c | 2 + 8 files changed, 114 insertions(+), 55 deletions(-) create mode 100644 cpukit/score/src/percpudata.c
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am index 2782d58d93..78e33b683b 100644 --- a/cpukit/Makefile.am +++ b/cpukit/Makefile.am @@ -840,6 +840,7 @@ librtemscpu_a_SOURCES += score/src/coremsgwkspace.c librtemscpu_a_SOURCES += score/src/coremutexseize.c librtemscpu_a_SOURCES += score/src/percpu.c librtemscpu_a_SOURCES += score/src/percpuasm.c +librtemscpu_a_SOURCES += score/src/percpudata.c librtemscpu_a_SOURCES += score/src/corerwlock.c librtemscpu_a_SOURCES += score/src/corerwlockobtainread.c librtemscpu_a_SOURCES += score/src/corerwlockobtainwrite.c diff --git a/cpukit/include/rtems/score/percpudata.h b/cpukit/include/rtems/score/percpudata.h index cae73a62b0..da454fd7bf 100644 --- a/cpukit/include/rtems/score/percpudata.h +++ b/cpukit/include/rtems/score/percpudata.h @@ -50,6 +50,20 @@ extern "C" { RTEMS_LINKER_RWSET_DECLARE( _Per_CPU_Data, char ); +/** + * @brief Translation units which define per-CPU items shall call this macro + * exactly once at file scope. + */ +#ifdef RTEMS_SMP +#define PER_CPU_DATA_NEED_INITIALIZATION() \ + static const char * const _Per_CPU_Data_reference \ + RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \ + RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data ) +#else +#define PER_CPU_DATA_NEED_INITIALIZATION() \ + RTEMS_LINKER_RWSET_DECLARE( _Per_CPU_Data, char ) +#endif + /** * @brief Declares a per-CPU item of the specified type. * diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c index 9015a369a2..c98ed08f10 100644 --- a/cpukit/sapi/src/exinit.c +++ b/cpukit/sapi/src/exinit.c @@ -32,7 +32,6 @@ #include <rtems/score/heap.h> #include <rtems/score/interr.h> #include <rtems/score/isr.h> -#include <rtems/score/percpudata.h> #include <rtems/score/priority.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/smpimpl.h> @@ -58,18 +57,6 @@ _Objects_Information_table[ OBJECTS_APIS_LAST + 1 ] = { &_POSIX_Objects[ 0 ] }; -RTEMS_LINKER_RWSET( - _Per_CPU_Data, -#if defined(RTEMS_SMP) - /* - * In SMP configurations, prevent false cache line sharing of per-processor - * data with a proper alignment. - */ - RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES ) -#endif - char -); - static void rtems_initialize_data_structures(void) { /* diff --git a/cpukit/score/src/percpudata.c b/cpukit/score/src/percpudata.c new file mode 100644 index 0000000000..091c6f0126 --- /dev/null +++ b/cpukit/score/src/percpudata.c @@ -0,0 +1,94 @@ +/** + * @file + * + * @ingroup RTEMSScorePerCPUData + * + * @brief This source file contains the per-CPU data linker set and its system + * initialization handler. + */ + +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2019, 2021 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. + */ + +#include <rtems/score/percpudata.h> +#include <rtems/score/interr.h> +#include <rtems/score/memory.h> +#include <rtems/config.h> +#include <rtems/sysinit.h> + +#include <string.h> + +RTEMS_LINKER_RWSET( + _Per_CPU_Data, +#if defined(RTEMS_SMP) + /* + * In SMP configurations, prevent false cache line sharing of per-processor + * data with a proper alignment. + */ + RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES ) +#endif + char +); + +#if defined(RTEMS_SMP) +static void _Per_CPU_Data_initialize( void ) +{ + uintptr_t size; + + size = RTEMS_LINKER_SET_SIZE( _Per_CPU_Data ); + + if ( size > 0 ) { + const Memory_Information *mem; + Per_CPU_Control *cpu; + uint32_t cpu_index; + uint32_t cpu_max; + + mem = _Memory_Get(); + cpu = _Per_CPU_Get_by_index( 0 ); + cpu->data = RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data ); + + cpu_max = rtems_configuration_get_maximum_processors(); + + for ( cpu_index = 1 ; cpu_index < cpu_max ; ++cpu_index ) { + cpu = _Per_CPU_Get_by_index( cpu_index ); + cpu->data = _Memory_Allocate( mem, size, CPU_CACHE_LINE_BYTES ); + + if( cpu->data == NULL ) { + _Internal_error( INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA ); + } + + memcpy( cpu->data, RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data ), size); + } + } +} + +RTEMS_SYSINIT_ITEM( + _Per_CPU_Data_initialize, + RTEMS_SYSINIT_PER_CPU_DATA, + RTEMS_SYSINIT_ORDER_MIDDLE +); +#endif diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c index 2a3405c6ef..0488464da0 100644 --- a/cpukit/score/src/smp.c +++ b/cpukit/score/src/smp.c @@ -27,14 +27,9 @@ #include <rtems/score/smpimpl.h> #include <rtems/score/assert.h> -#include <rtems/score/memory.h> -#include <rtems/score/percpudata.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/threadimpl.h> #include <rtems/config.h> -#include <rtems/sysinit.h> - -#include <string.h> #if CPU_USE_DEFERRED_FP_SWITCH == TRUE #error "deferred FP switch not implemented for SMP" @@ -264,40 +259,3 @@ void _SMP_Send_message_multicast( } } } - -static void _Per_CPU_Data_initialize( void ) -{ - uintptr_t size; - - size = RTEMS_LINKER_SET_SIZE( _Per_CPU_Data ); - - if ( size > 0 ) { - const Memory_Information *mem; - Per_CPU_Control *cpu; - uint32_t cpu_index; - uint32_t cpu_max; - - mem = _Memory_Get(); - cpu = _Per_CPU_Get_by_index( 0 ); - cpu->data = RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data ); - - cpu_max = rtems_configuration_get_maximum_processors(); - - for ( cpu_index = 1 ; cpu_index < cpu_max ; ++cpu_index ) { - cpu = _Per_CPU_Get_by_index( cpu_index ); - cpu->data = _Memory_Allocate( mem, size, CPU_CACHE_LINE_BYTES ); - - if( cpu->data == NULL ) { - _Internal_error( INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA ); - } - - memcpy( cpu->data, RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data ), size); - } - } -} - -RTEMS_SYSINIT_ITEM( - _Per_CPU_Data_initialize, - RTEMS_SYSINIT_PER_CPU_DATA, - RTEMS_SYSINIT_ORDER_MIDDLE -); diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index 810ba66352..e3f328ec5f 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -1454,6 +1454,7 @@ source: - cpukit/score/src/once.c - cpukit/score/src/percpu.c - cpukit/score/src/percpuasm.c +- cpukit/score/src/percpudata.c - cpukit/score/src/pheapallocate.c - cpukit/score/src/pheapextend.c - cpukit/score/src/pheapfree.c diff --git a/testsuites/smptests/smpfatal09/init.c b/testsuites/smptests/smpfatal09/init.c index e67ed0a56a..dfdd11d84c 100644 --- a/testsuites/smptests/smpfatal09/init.c +++ b/testsuites/smptests/smpfatal09/init.c @@ -36,6 +36,8 @@ #include <tmacros.h> +PER_CPU_DATA_NEED_INITIALIZATION(); + static PER_CPU_DATA_ITEM(int, i) = 123; const char rtems_test_name[] = "SMPFATAL 9"; diff --git a/testsuites/sptests/sppercpudata01/init.c b/testsuites/sptests/sppercpudata01/init.c index 3d105ee61f..fbdf4c50ad 100644 --- a/testsuites/sptests/sppercpudata01/init.c +++ b/testsuites/sptests/sppercpudata01/init.c @@ -25,6 +25,8 @@ const char rtems_test_name[] = "SPPERCPUDATA 1"; +PER_CPU_DATA_NEED_INITIALIZATION(); + static RTEMS_ALIGNED(CPU_HEAP_ALIGNMENT) PER_CPU_DATA_ITEM(unsigned char, c) = 1; -- 2.26.2 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel