Skip to content

Commit 18373c0

Browse files
committed
[libc][picolibc] add tls support
1 parent 6d1fdde commit 18373c0

File tree

8 files changed

+110
-2
lines changed

8 files changed

+110
-2
lines changed

bsp/qemu-vexpress-a9/link.lds

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,35 @@ SECTIONS
8585
}
8686
__data_end = .;
8787

88+
. = ALIGN(8);
89+
.tdata :
90+
{
91+
__tdata_start = .;
92+
*(.tdata .tdata.* .gnu.linkonce.td.*)
93+
__tdata_end = .;
94+
}
95+
__tdata_source = LOADADDR(.tdata);
96+
__tdata_size = SIZEOF(.tdata);
97+
98+
/*
99+
* TLS zeroed data is relocated as if it immediately followed
100+
* the tdata values. However, the linker 'magically' erases the
101+
* memory allocation so that no ROM is consumed by this
102+
* section
103+
*/
104+
.tbss :
105+
{
106+
*(.tbss .tbss.* .gnu.linkonce.tb.*)
107+
*(.tcommon)
108+
__tbss_end = .;
109+
}
110+
__tls_size = __tbss_end - __tdata_start;
111+
__tbss_size = __tls_size - __tdata_size;
112+
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
113+
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
114+
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
115+
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );
116+
88117
. = ALIGN(4);
89118
__bss_start = .;
90119
.bss :

bsp/qemu-vexpress-a9/rtconfig.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ def get_mac_address():
4949
STRIP = PREFIX + 'strip'
5050
CFPFLAGS = ' -msoft-float'
5151
AFPFLAGS = ' -mfloat-abi=softfp -mfpu=neon'
52-
DEVICE = ' -march=armv7-a -mtune=cortex-a7 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
52+
DEVICE = ''
53+
#DEVICE += ' --specs=picolibc.specs --picolibc-prefix=' + EXEC_PATH + '/../'
54+
DEVICE += ' -march=armv7-a -mtune=cortex-a7 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
5355

5456
CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always'
5557
CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -D_POSIX_SOURCE -fdiagnostics-color=always'

examples/libc/SConscript

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from building import *
22

33
src = Glob('*.c')
4-
group = DefineGroup('UTest', src, depend = ['RT_USING_NEWLIBC', 'RT_USING_PTHREADS'])
4+
if GetDepend(['RT_USING_PICOLIBC']):
5+
group = DefineGroup('UTest', src, depend = ['RT_USING_PTHREADS'])
6+
else:
7+
group = DefineGroup('UTest', src, depend = ['RT_USING_NEWLIBC', 'RT_USING_PTHREADS'])
58

69
Return('group')

examples/libc/tls.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2006-2021, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2023-12-19 iDings first version
9+
*/
10+
11+
#include <stdio.h>
12+
#include <stdlib.h>
13+
#include <unistd.h>
14+
#include <finsh.h>
15+
#include <rtthread.h>
16+
17+
static __thread int i;
18+
19+
static void child_routine(void *param)
20+
{
21+
printf("child_thread: i:%d\n", i);
22+
i = 300;
23+
printf("child_thread: i:%d\n", i);
24+
}
25+
26+
static int tls_test(void)
27+
{
28+
rt_thread_t child;
29+
30+
char name[RT_NAME_MAX];
31+
rt_thread_get_name(rt_thread_self(), name, sizeof(name));
32+
33+
printf("i:%d\n", i);
34+
i = 200;
35+
printf("main_thread: i:%d\n", i);
36+
37+
child = rt_thread_create("tls_thread", child_routine, NULL, 4096, 10, 20);
38+
rt_thread_startup(child);
39+
40+
sleep(1);
41+
printf("main_thread: i:%d\n", i);
42+
43+
return 0;
44+
}
45+
MSH_CMD_EXPORT(tls_test, thread local storage example);

include/rtdef.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@
7171
#endif /* defined(RT_USING_SIGNALS) || defined(RT_USING_SMART) */
7272
#endif /* RT_USING_NANO */
7373

74+
#ifdef RT_USING_PICOLIBC
75+
#include <picolibc.h>
76+
#ifdef PICOLIBC_TLS
77+
#include <picotls.h>
78+
#endif
79+
#endif
80+
7481
#ifdef __cplusplus
7582
extern "C" {
7683
#endif
@@ -998,6 +1005,10 @@ struct rt_thread
9981005
#endif
9991006
#endif
10001007

1008+
#ifdef PICOLIBC_TLS
1009+
void *tls;
1010+
#endif
1011+
10011012
rt_atomic_t ref_count;
10021013
struct rt_spinlock spinlock;
10031014
rt_ubase_t user_data; /**< private user data beyond this thread */

src/scheduler_mp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,9 @@ void rt_schedule(void)
546546
_rt_schedule_remove_thread(to_thread, RT_FALSE);
547547
to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
548548

549+
#ifdef PICOLIBC_TLS
550+
_set_tls(to_thread->tls);
551+
#endif
549552
/* switch to new thread */
550553
LOG_D("[%d]switch to priority#%d "
551554
"thread:%.*s(sp:0x%08x), "
@@ -700,6 +703,9 @@ void rt_scheduler_do_irq_switch(void *context)
700703
_rt_schedule_remove_thread(to_thread, RT_FALSE);
701704
to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
702705

706+
#ifdef PICOLIBC_TLS
707+
_set_tls(to_thread->tls);
708+
#endif
703709
#ifdef RT_USING_OVERFLOW_CHECK
704710
_scheduler_stack_check(to_thread);
705711
#endif /* RT_USING_OVERFLOW_CHECK */

src/scheduler_up.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ void rt_schedule(void)
295295
rt_schedule_remove_thread(to_thread);
296296
to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
297297

298+
#ifdef PICOLIBC_TLS
299+
_set_tls(to_thread->tls);
300+
#endif
298301
/* switch to new thread */
299302
LOG_D("[%d]switch to priority#%d "
300303
"thread:%.*s(sp:0x%08x), "

src/thread.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,15 @@ static rt_err_t _thread_init(struct rt_thread *thread,
184184
thread->entry = (void *)entry;
185185
thread->parameter = parameter;
186186

187+
#ifdef PICOLIBC_TLS
188+
#define TLS_ALIGN (_tls_align() > 8 ? _tls_align() : 8)
189+
char *tls = (char *)stack_start + stack_size - _tls_size();
190+
thread->tls = (void *)RT_ALIGN_DOWN((rt_ubase_t)tls, TLS_ALIGN);
191+
stack_size = (char *)thread->tls - (char *)stack_start;
192+
193+
_init_tls(thread->tls);
194+
#endif
195+
187196
/* stack init */
188197
thread->stack_addr = stack_start;
189198
thread->stack_size = stack_size;

0 commit comments

Comments
 (0)