Skip to content

Commit c3e1df0

Browse files
keith-packardKeith Packardaggarg
authored
Add Thread Local Storage (TLS) support using Picolibc functions (#343)
* Pass top of stack to configINIT_TLS_BLOCK Picolibc wants to allocate the per-task TLS block within the stack segment, so it will need to modify the top of stack value. Pass the pxTopOfStack variable to make this explicit. Signed-off-by: Keith Packard <[email protected]> * Move newlib-specific definitions to separate file This reduces the clutter in FreeRTOS.h caused by having newlib-specific macros present there. Signed-off-by: Keith Packard <[email protected]> * Make TLS code depend only on configUSE_C_RUNTIME_TLS_SUPPORT Remove reference to configUSE_NEWLIB_REENTRANT as that only works when using newlib. configUSE_C_RUNTIME_TLS_SUPPORT is always set when configUSE_NEWLIB_REENTRANT is set, so using both was redundant in that case. Signed-off-by: Keith Packard <[email protected]> * portable-ARC: Adapt ARC support to use generalized TLS support With generalized thread local storage (TLS) support present in the core, the two ARC ports need to have the changes to the TCB mirrored to them. Signed-off-by: Keith Packard <[email protected]> * Add Thread Local Storage (TLS) support using Picolibc functions This patch provides definitions of the general TLS support macros in terms of the Picolibc TLS support functions. Picolibc is normally configured to use TLS internally for all variables that are intended to be task-local, so these changes are necessary for picolibc to work correctly with FreeRTOS. The picolibc helper functions rely on elements within the linker script to arrange the TLS data in memory and define some symbols. Applications wanting to use this mechanism will need changes in their linker script when migrating to picolibc. Signed-off-by: Keith Packard <[email protected]> --------- Signed-off-by: Keith Packard <[email protected]> Co-authored-by: Keith Packard <[email protected]> Co-authored-by: Gaurav-Aggarwal-AWS <[email protected]>
1 parent e6514fb commit c3e1df0

File tree

7 files changed

+155
-53
lines changed

7 files changed

+155
-53
lines changed

.github/lexicon.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,7 @@ mclk
10541054
mconfigintcoresw
10551055
mcr
10561056
mcu
1057+
md
10571058
mddr
10581059
mder
10591060
mdh
@@ -1335,6 +1336,7 @@ phy
13351336
phya
13361337
pic
13371338
picnt
1339+
picolibc
13381340
pien
13391341
piir
13401342
pimr

include/FreeRTOS.h

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -95,41 +95,26 @@
9595
/* Required if struct _reent is used. */
9696
#if ( configUSE_NEWLIB_REENTRANT == 1 )
9797

98-
/* Note Newlib support has been included by popular demand, but is not
99-
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
100-
* responsible for resulting newlib operation. User must be familiar with
101-
* newlib and must provide system-wide implementations of the necessary
102-
* stubs. Be warned that (at the time of writing) the current newlib design
103-
* implements a system-wide malloc() that must be provided with locks.
104-
*
105-
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
106-
* for additional information. */
107-
#include <reent.h>
98+
#include "newlib-freertos.h"
10899

109-
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
100+
#endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */
110101

111-
#ifndef configTLS_BLOCK_TYPE
112-
#define configTLS_BLOCK_TYPE struct _reent
113-
#endif
102+
/* Must be defaulted before configUSE_PICOLIBC_TLS is used below. */
103+
#ifndef configUSE_PICOLIBC_TLS
104+
#define configUSE_PICOLIBC_TLS 0
105+
#endif
114106

115-
#ifndef configINIT_TLS_BLOCK
116-
#define configINIT_TLS_BLOCK( xTLSBlock ) _REENT_INIT_PTR( &( xTLSBlock ) )
117-
#endif
107+
#if ( configUSE_PICOLIBC_TLS == 1 )
118108

119-
#ifndef configSET_TLS_BLOCK
120-
#define configSET_TLS_BLOCK( xTLSBlock ) ( _impure_ptr = &( xTLSBlock ) )
121-
#endif
109+
#include "picolibc-freertos.h"
122110

123-
#ifndef configDEINIT_TLS_BLOCK
124-
#define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) )
125-
#endif
126-
#endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */
111+
#endif /* if ( configUSE_PICOLIBC_TLS == 1 ) */
127112

128113
#ifndef configUSE_C_RUNTIME_TLS_SUPPORT
129114
#define configUSE_C_RUNTIME_TLS_SUPPORT 0
130115
#endif
131116

132-
#if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
117+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
133118

134119
#ifndef configTLS_BLOCK_TYPE
135120
#error Missing definition: configTLS_BLOCK_TYPE must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
@@ -146,7 +131,7 @@
146131
#ifndef configDEINIT_TLS_BLOCK
147132
#error Missing definition: configDEINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
148133
#endif
149-
#endif /* if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) */
134+
#endif /* if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) */
150135

151136
/*
152137
* Check all the required application specific macros have been defined.
@@ -1306,7 +1291,7 @@ typedef struct xSTATIC_TCB
13061291
#if ( configGENERATE_RUN_TIME_STATS == 1 )
13071292
configRUN_TIME_COUNTER_TYPE ulDummy16;
13081293
#endif
1309-
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
1294+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
13101295
configTLS_BLOCK_TYPE xDummy17;
13111296
#endif
13121297
#if ( configUSE_TASK_NOTIFICATIONS == 1 )

include/newlib-freertos.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
3+
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* SPDX-License-Identifier: MIT
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
8+
* this software and associated documentation files (the "Software"), to deal in
9+
* the Software without restriction, including without limitation the rights to
10+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11+
* the Software, and to permit persons to whom the Software is furnished to do so,
12+
* subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in all
15+
* copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+
*
24+
* https://www.FreeRTOS.org
25+
* https://github.com/FreeRTOS
26+
*
27+
*/
28+
29+
#ifndef INC_NEWLIB_FREERTOS_H
30+
#define INC_NEWLIB_FREERTOS_H
31+
32+
/* Note Newlib support has been included by popular demand, but is not
33+
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
34+
* responsible for resulting newlib operation. User must be familiar with
35+
* newlib and must provide system-wide implementations of the necessary
36+
* stubs. Be warned that (at the time of writing) the current newlib design
37+
* implements a system-wide malloc() that must be provided with locks.
38+
*
39+
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
40+
* for additional information. */
41+
42+
#include <reent.h>
43+
44+
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
45+
46+
#ifndef configTLS_BLOCK_TYPE
47+
#define configTLS_BLOCK_TYPE struct _reent
48+
#endif
49+
50+
#ifndef configINIT_TLS_BLOCK
51+
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) _REENT_INIT_PTR( &( xTLSBlock ) )
52+
#endif
53+
54+
#ifndef configSET_TLS_BLOCK
55+
#define configSET_TLS_BLOCK( xTLSBlock ) _impure_ptr = &( xTLSBlock )
56+
#endif
57+
58+
#ifndef configDEINIT_TLS_BLOCK
59+
#define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) )
60+
#endif
61+
62+
#endif /* INC_NEWLIB_FREERTOS_H */

include/picolibc-freertos.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
3+
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* SPDX-License-Identifier: MIT
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
8+
* this software and associated documentation files (the "Software"), to deal in
9+
* the Software without restriction, including without limitation the rights to
10+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11+
* the Software, and to permit persons to whom the Software is furnished to do so,
12+
* subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in all
15+
* copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+
*
24+
* https://www.FreeRTOS.org
25+
* https://github.com/FreeRTOS
26+
*
27+
*/
28+
29+
#ifndef INC_PICOLIBC_FREERTOS_H
30+
#define INC_PICOLIBC_FREERTOS_H
31+
32+
/* Use picolibc TLS support to allocate space for __thread variables,
33+
* initialize them at thread creation and set the TLS context at
34+
* thread switch time.
35+
*
36+
* See the picolibc TLS docs:
37+
* https://github.com/picolibc/picolibc/blob/main/doc/tls.md
38+
* for additional information. */
39+
40+
#include <picotls.h>
41+
42+
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
43+
44+
#define configTLS_BLOCK_TYPE void *
45+
46+
/* Allocate thread local storage block off the end of the
47+
* stack. The _tls_size() function returns the size (in
48+
* bytes) of the total TLS area used by the application */
49+
#if ( portSTACK_GROWTH < 0 )
50+
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \
51+
do { \
52+
pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) - _tls_size() ); \
53+
xTLSBlock = pxTopOfStack; \
54+
_init_tls( xTLSBlock ); \
55+
} while( 0 )
56+
#else /* portSTACK_GROWTH */
57+
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \
58+
do { \
59+
xTLSBlock = pxTopOfStack; \
60+
pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) + _tls_size() ); \
61+
_init_tls( xTLSBlock ); \
62+
} while( 0 )
63+
#endif /* portSTACK_GROWTH */
64+
65+
#define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock )
66+
67+
#define configDEINIT_TLS_BLOCK( xTLSBlock )
68+
69+
#endif /* INC_PICOLIBC_FREERTOS_H */

portable/ThirdParty/GCC/ARC_EM_HS/port.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,8 @@ void vPortEndTask( void )
251251
uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
252252
#endif
253253

254-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
255-
256-
/* Allocate a Newlib reent structure that is specific to this task.
257-
* Note Newlib support has been included by popular demand, but is not
258-
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
259-
* responsible for resulting newlib operation. User must be familiar with
260-
* newlib and must provide system-wide implementations of the necessary
261-
* stubs. Be warned that (at the time of writing) the current newlib design
262-
* implements a system-wide malloc() that must be provided with locks. */
263-
struct _reent xNewLib_reent;
254+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
255+
configTLS_BLOCK_TYPE xTLSBlock; /*< Memory block used as Thread Local Storage (TLS) Block for the task. */
264256
#endif
265257

266258
#if ( configUSE_TASK_NOTIFICATIONS == 1 )

portable/ThirdParty/GCC/ARC_v1/port.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,8 @@ void vPortEndTask( void )
251251
uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
252252
#endif
253253

254-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
255-
256-
/* Allocate a Newlib reent structure that is specific to this task.
257-
* Note Newlib support has been included by popular demand, but is not
258-
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
259-
* responsible for resulting newlib operation. User must be familiar with
260-
* newlib and must provide system-wide implementations of the necessary
261-
* stubs. Be warned that (at the time of writing) the current newlib design
262-
* implements a system-wide malloc() that must be provided with locks. */
263-
struct _reent xNewLib_reent;
254+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
255+
configTLS_BLOCK_TYPE xTLSBlock; /*< Memory block used as Thread Local Storage (TLS) Block for the task. */
264256
#endif
265257

266258
#if ( configUSE_TASK_NOTIFICATIONS == 1 )

tasks.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
300300
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /**< Stores the amount of time the task has spent in the Running state. */
301301
#endif
302302

303-
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
303+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
304304
configTLS_BLOCK_TYPE xTLSBlock; /**< Memory block used as Thread Local Storage (TLS) Block for the task. */
305305
#endif
306306

@@ -955,10 +955,10 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
955955
}
956956
#endif
957957

958-
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
958+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
959959
{
960960
/* Allocate and initialize memory for the task's TLS Block. */
961-
configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock );
961+
configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock, pxTopOfStack );
962962
}
963963
#endif
964964

@@ -2030,7 +2030,7 @@ void vTaskStartScheduler( void )
20302030
* starts to run. */
20312031
portDISABLE_INTERRUPTS();
20322032

2033-
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
2033+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
20342034
{
20352035
/* Switch C-Runtime's TLS Block to point to the TLS
20362036
* block specific to the task that will run first. */
@@ -3074,7 +3074,7 @@ void vTaskSwitchContext( void )
30743074
}
30753075
#endif
30763076

3077-
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
3077+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
30783078
{
30793079
/* Switch C-Runtime's TLS Block to point to the TLS
30803080
* Block specific to this task. */
@@ -3950,7 +3950,7 @@ static void prvCheckTasksWaitingTermination( void )
39503950
* want to allocate and clean RAM statically. */
39513951
portCLEAN_UP_TCB( pxTCB );
39523952

3953-
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
3953+
#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 )
39543954
{
39553955
/* Free up the memory allocated for the task's TLS Block. */
39563956
configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock );

0 commit comments

Comments
 (0)