File indexing completed on 2025-05-11 08:24:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef _RTEMS_SCORE_TLS_H
0038 #define _RTEMS_SCORE_TLS_H
0039
0040 #include <rtems/score/cpuimpl.h>
0041
0042 #include <string.h>
0043
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 typedef struct {
0066
0067
0068
0069 const char *data_begin;
0070
0071
0072
0073
0074 const char *data_size;
0075
0076
0077
0078
0079 const char *bss_begin;
0080
0081
0082
0083
0084 const char *bss_size;
0085
0086
0087
0088
0089 const char *size;
0090
0091
0092
0093
0094 const char *alignment;
0095 } TLS_Configuration;
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 extern const volatile TLS_Configuration _TLS_Configuration;
0107
0108 typedef struct {
0109
0110
0111
0112
0113 uint32_t generation_number;
0114
0115 void *tls_blocks[1];
0116 } TLS_Dynamic_thread_vector;
0117
0118 typedef struct TLS_Thread_control_block {
0119 #if defined(__i386__) || defined(__x86_64__)
0120 struct TLS_Thread_control_block *tcb;
0121 #else
0122 TLS_Dynamic_thread_vector *dtv;
0123
0124
0125
0126
0127 #if CPU_SIZEOF_POINTER == 4 || defined(AARCH64_MULTILIB_ARCH_V8)
0128 uintptr_t reserved;
0129 #endif
0130 #endif
0131 } TLS_Thread_control_block;
0132
0133 typedef struct {
0134 uintptr_t module;
0135 uintptr_t offset;
0136 } TLS_Index;
0137
0138
0139
0140
0141
0142
0143
0144
0145 static inline uintptr_t _TLS_Get_thread_control_block_area_size(
0146 const volatile TLS_Configuration *config
0147 )
0148 {
0149 #if CPU_THREAD_LOCAL_STORAGE_VARIANT == 11
0150 uintptr_t alignment;
0151
0152 alignment = (uintptr_t) config->alignment;
0153
0154 return RTEMS_ALIGN_UP( sizeof( TLS_Thread_control_block ), alignment );
0155 #else
0156 (void) config;
0157 return sizeof( TLS_Thread_control_block );
0158 #endif
0159 }
0160
0161
0162
0163
0164
0165
0166
0167 uintptr_t _TLS_Get_allocation_size( void );
0168
0169
0170
0171
0172
0173
0174
0175
0176 static inline void _TLS_Copy_and_clear(
0177 const volatile TLS_Configuration *config,
0178 void *tls_data
0179 )
0180 {
0181 tls_data =
0182 memcpy( tls_data, config->data_begin, (uintptr_t) config->data_size );
0183
0184 memset(
0185 (char *) tls_data +
0186 (uintptr_t) config->bss_begin - (uintptr_t) config->data_begin,
0187 0,
0188 (uintptr_t) config->bss_size
0189 );
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 static inline void _TLS_Initialize_TCB_and_DTV(
0202 void *tls_data,
0203 TLS_Thread_control_block *tcb,
0204 TLS_Dynamic_thread_vector *dtv
0205 )
0206 {
0207 #if defined(__i386__) || defined(__x86_64__)
0208 (void) dtv;
0209 tcb->tcb = tcb;
0210 #else
0211 tcb->dtv = dtv;
0212 dtv->generation_number = 1;
0213 dtv->tls_blocks[0] = tls_data;
0214 #endif
0215 }
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 static inline void *_TLS_Initialize_area( void *tls_area )
0227 {
0228 const volatile TLS_Configuration *config;
0229 uintptr_t alignment;
0230 void *tls_data;
0231 TLS_Thread_control_block *tcb;
0232 TLS_Dynamic_thread_vector *dtv;
0233 void *return_value;
0234 #if CPU_THREAD_LOCAL_STORAGE_VARIANT == 11
0235 uintptr_t tcb_size;
0236 #endif
0237 #if CPU_THREAD_LOCAL_STORAGE_VARIANT == 20
0238 uintptr_t size;
0239 uintptr_t alignment_2;
0240 #endif
0241
0242 config = &_TLS_Configuration;
0243 alignment = (uintptr_t) config->alignment;
0244
0245 #if defined(__i386__) || defined(__x86_64__)
0246 dtv = NULL;
0247 #else
0248 dtv = (TLS_Dynamic_thread_vector *) tls_area;
0249 tls_area = (char *) tls_area + sizeof( *dtv );
0250 #endif
0251
0252 #if CPU_THREAD_LOCAL_STORAGE_VARIANT == 10
0253 tls_data = (void *)
0254 RTEMS_ALIGN_UP( (uintptr_t) tls_area + sizeof( *tcb ), alignment );
0255 tcb = (TLS_Thread_control_block *) ((char *) tls_data - sizeof( *tcb ));
0256 return_value = tls_data;
0257 #elif CPU_THREAD_LOCAL_STORAGE_VARIANT == 11
0258 tcb_size = RTEMS_ALIGN_UP( sizeof( *tcb ), alignment );
0259 tls_data = (void *)
0260 RTEMS_ALIGN_UP( (uintptr_t) tls_area + tcb_size, alignment );
0261 tcb = (TLS_Thread_control_block *) ((char *) tls_data - tcb_size);
0262 return_value = tcb;
0263 #elif CPU_THREAD_LOCAL_STORAGE_VARIANT == 20
0264 alignment_2 = RTEMS_ALIGN_UP( alignment, CPU_SIZEOF_POINTER );
0265 tls_area = (void *) RTEMS_ALIGN_UP( (uintptr_t) tls_area, alignment_2 );
0266 size = (uintptr_t) config->size;
0267 tcb = (TLS_Thread_control_block *)
0268 ((char *) tls_area + RTEMS_ALIGN_UP( size, alignment_2 ));
0269 tls_data = (char *) tcb - RTEMS_ALIGN_UP( size, alignment );
0270 return_value = tcb;
0271 #else
0272 #error "unexpected CPU_THREAD_LOCAL_STORAGE_VARIANT value"
0273 #endif
0274
0275 _TLS_Initialize_TCB_and_DTV( tls_data, tcb, dtv );
0276 _TLS_Copy_and_clear( config, tls_data );
0277
0278 return return_value;
0279 }
0280
0281
0282
0283 #ifdef __cplusplus
0284 }
0285 #endif
0286
0287 #endif