RTEMS CPU Kit with SuperCore  4.11.2
tls.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
11  *
12  * embedded brains GmbH
13  * Dornierstr. 4
14  * 82178 Puchheim
15  * Germany
16  * <rtems@embedded-brains.de>
17  *
18  * The license and distribution terms for this file may be
19  * found in the file LICENSE in this distribution or at
20  * http://www.rtems.org/license/LICENSE.
21  */
22 
23 #ifndef _RTEMS_SCORE_TLS_H
24 #define _RTEMS_SCORE_TLS_H
25 
26 #include <rtems/score/cpu.h>
27 
28 #include <string.h>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33 
47 extern char _TLS_Data_begin[];
48 
49 extern char _TLS_Data_end[];
50 
51 extern char _TLS_Data_size[];
52 
53 extern char _TLS_BSS_begin[];
54 
55 extern char _TLS_BSS_end[];
56 
57 extern char _TLS_BSS_size[];
58 
59 extern char _TLS_Size[];
60 
61 extern char _TLS_Alignment[];
62 
63 typedef struct {
64  /*
65  * FIXME: Not sure if the generation number type is correct for all
66  * architectures.
67  */
68  uint32_t generation_number;
69 
70  void *tls_blocks[1];
72 
73 typedef struct {
75  uintptr_t reserved;
77 
78 typedef struct {
79  uintptr_t module;
80  uintptr_t offset;
81 } TLS_Index;
82 
83 static inline uintptr_t _TLS_Get_size( void )
84 {
85  /*
86  * Do not use _TLS_Size here since this will lead GCC to assume that this
87  * symbol is not 0 and the tests for 0 will be optimized away.
88  */
89  return (uintptr_t) _TLS_BSS_end - (uintptr_t) _TLS_Data_begin;
90 }
91 
92 static inline uintptr_t _TLS_Heap_align_up( uintptr_t val )
93 {
94  uintptr_t msk = CPU_HEAP_ALIGNMENT - 1;
95 
96  return (val + msk) & ~msk;
97 }
98 
99 static inline uintptr_t _TLS_Get_thread_control_block_area_size(
100  uintptr_t alignment
101 )
102 {
103  return alignment <= sizeof(TLS_Thread_control_block) ?
104  sizeof(TLS_Thread_control_block) : alignment;
105 }
106 
107 static inline uintptr_t _TLS_Get_allocation_size(
108  uintptr_t size,
109  uintptr_t alignment
110 )
111 {
112  uintptr_t aligned_size = _TLS_Heap_align_up( size );
113 
114  return _TLS_Get_thread_control_block_area_size( alignment )
115  + aligned_size + sizeof(TLS_Dynamic_thread_vector);
116 }
117 
118 static inline void *_TLS_Copy_and_clear( void *tls_area )
119 {
120  tls_area = memcpy(
121  tls_area,
122  _TLS_Data_begin,
123  (size_t) ((uintptr_t)_TLS_Data_size)
124  );
125 
126 
127  memset(
128  (char *) tls_area + (size_t)((intptr_t) _TLS_BSS_begin) -
129  (size_t)((intptr_t) _TLS_Data_begin),
130  0,
131  ((size_t) (intptr_t)_TLS_BSS_size)
132  );
133 
134  return tls_area;
135 }
136 
137 static inline void *_TLS_Initialize(
138  void *tls_block,
141 )
142 {
143  tcb->dtv = dtv;
144  dtv->generation_number = 1;
145  dtv->tls_blocks[0] = tls_block;
146 
147  return _TLS_Copy_and_clear( tls_block );
148 }
149 
150 /* Use Variant I, TLS offsets emitted by linker takes the TCB into account */
151 static inline void *_TLS_TCB_at_area_begin_initialize( void *tls_area )
152 {
153  void *tls_block = (char *) tls_area
154  + _TLS_Get_thread_control_block_area_size( (uintptr_t) _TLS_Alignment );
155  TLS_Thread_control_block *tcb = tls_area;
156  uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
158  ((char *) tls_block + aligned_size);
159 
160  return _TLS_Initialize( tls_block, tcb, dtv );
161 }
162 
163 /* Use Variant I, TLS offsets emitted by linker neglects the TCB */
164 static inline void *_TLS_TCB_before_TLS_block_initialize( void *tls_area )
165 {
166  void *tls_block = (char *) tls_area
167  + _TLS_Get_thread_control_block_area_size( (uintptr_t) _TLS_Alignment );
169  ((char *) tls_block - sizeof(*tcb));
170  uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
172  ((char *) tls_block + aligned_size);
173 
174  return _TLS_Initialize( tls_block, tcb, dtv );
175 }
176 
177 /* Use Variant II */
178 static inline void *_TLS_TCB_after_TLS_block_initialize( void *tls_area )
179 {
180  uintptr_t size = (uintptr_t) _TLS_Size;
181  uintptr_t tls_align = (uintptr_t) _TLS_Alignment;
182  uintptr_t tls_mask = tls_align - 1;
183  uintptr_t heap_align = _TLS_Heap_align_up( tls_align );
184  uintptr_t heap_mask = heap_align - 1;
186  ((char *) tls_area + ((size + heap_mask) & ~heap_mask));
187  void *tls_block = (char *) tcb - ((size + tls_mask) & ~tls_mask);
189  ((char *) tcb + sizeof(*tcb));
190 
191  _TLS_Initialize( tls_block, tcb, dtv );
192 
193  return tcb;
194 }
195 
198 #ifdef __cplusplus
199 }
200 #endif /* __cplusplus */
201 
202 #endif /* _RTEMS_SCORE_TLS_H */
Definition: tls.h:63
Definition: tls.h:73
Definition: tls.h:78