Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add picolibc tls support #8392

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[libc][picolibc] add tls support
  • Loading branch information
iDings committed Dec 22, 2023
commit 18373c0cfdbb8c445328f26def82de1ef4abe32f
29 changes: 29 additions & 0 deletions bsp/qemu-vexpress-a9/link.lds
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,35 @@ SECTIONS
}
__data_end = .;

. = ALIGN(8);
.tdata :
{
__tdata_start = .;
*(.tdata .tdata.* .gnu.linkonce.td.*)
__tdata_end = .;
}
__tdata_source = LOADADDR(.tdata);
__tdata_size = SIZEOF(.tdata);

/*
* TLS zeroed data is relocated as if it immediately followed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分,如果是其他工具链 + 其他libc会怎么样?

Copy link
Contributor Author

@iDings iDings Dec 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我现在的理解,这部分是看编译器,编译器如果使能了tls支持的的话,它会生成tdata,tbss的sections,picolibc的tls部分的话是封装了一些接口方便使用.
arm提供的gcc+newlibc的编译器的话,我现在看到的都是--disable-tls的,不会生成tdata,tbss,linker script里面虽然定义了tdata,tbss,从linker map里面看这部分都不会占用空间, 对于--disable-tls走的是emutls,
image
image
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/picolibc/picolibc/blob/main/doc/tls.md
picolibc的tls-mode使用的local-exec模式, 看zephyr的话也是支持这种模式
image
image

* the tdata values. However, the linker 'magically' erases the
* memory allocation so that no ROM is consumed by this
* section
*/
.tbss :
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
__tbss_end = .;
}
__tls_size = __tbss_end - __tdata_start;
__tbss_size = __tls_size - __tdata_size;
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );

. = ALIGN(4);
__bss_start = .;
.bss :
Expand Down
4 changes: 3 additions & 1 deletion bsp/qemu-vexpress-a9/rtconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ def get_mac_address():
STRIP = PREFIX + 'strip'
CFPFLAGS = ' -msoft-float'
AFPFLAGS = ' -mfloat-abi=softfp -mfpu=neon'
DEVICE = ' -march=armv7-a -mtune=cortex-a7 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
DEVICE = ''
#DEVICE += ' --specs=picolibc.specs --picolibc-prefix=' + EXEC_PATH + '/../'
DEVICE += ' -march=armv7-a -mtune=cortex-a7 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'

CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always'
CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -D_POSIX_SOURCE -fdiagnostics-color=always'
Expand Down
5 changes: 4 additions & 1 deletion examples/libc/SConscript
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from building import *

src = Glob('*.c')
group = DefineGroup('UTest', src, depend = ['RT_USING_NEWLIBC', 'RT_USING_PTHREADS'])
if GetDepend(['RT_USING_PICOLIBC']):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example/libc目录rtthread现在没有编译,也没有看到选项可以打开去编译,但是这个tls的例子暂时没有找到合适放的位置,就先放在这个下面了

group = DefineGroup('UTest', src, depend = ['RT_USING_PTHREADS'])
else:
group = DefineGroup('UTest', src, depend = ['RT_USING_NEWLIBC', 'RT_USING_PTHREADS'])

Return('group')
45 changes: 45 additions & 0 deletions examples/libc/tls.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-12-19 iDings first version
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <finsh.h>
#include <rtthread.h>

static __thread int i;

static void child_routine(void *param)
{
printf("child_thread: i:%d\n", i);
i = 300;
printf("child_thread: i:%d\n", i);
}

static int tls_test(void)
{
rt_thread_t child;

char name[RT_NAME_MAX];
rt_thread_get_name(rt_thread_self(), name, sizeof(name));

printf("i:%d\n", i);
i = 200;
printf("main_thread: i:%d\n", i);

child = rt_thread_create("tls_thread", child_routine, NULL, 4096, 10, 20);
rt_thread_startup(child);

sleep(1);
printf("main_thread: i:%d\n", i);

return 0;
}
MSH_CMD_EXPORT(tls_test, thread local storage example);
11 changes: 11 additions & 0 deletions include/rtdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@
#endif /* defined(RT_USING_SIGNALS) || defined(RT_USING_SMART) */
#endif /* RT_USING_NANO */

#ifdef RT_USING_PICOLIBC
#include <picolibc.h>
#ifdef PICOLIBC_TLS
#include <picotls.h>
#endif
#endif

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -998,6 +1005,10 @@ struct rt_thread
#endif
#endif

#ifdef PICOLIBC_TLS
void *tls;
#endif

rt_atomic_t ref_count;
struct rt_spinlock spinlock;
rt_ubase_t user_data; /**< private user data beyond this thread */
Expand Down
6 changes: 6 additions & 0 deletions src/scheduler_mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,9 @@ void rt_schedule(void)
_rt_schedule_remove_thread(to_thread, RT_FALSE);
to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);

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

#ifdef PICOLIBC_TLS
_set_tls(to_thread->tls);
#endif
#ifdef RT_USING_OVERFLOW_CHECK
_scheduler_stack_check(to_thread);
#endif /* RT_USING_OVERFLOW_CHECK */
Expand Down
3 changes: 3 additions & 0 deletions src/scheduler_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ void rt_schedule(void)
rt_schedule_remove_thread(to_thread);
to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);

#ifdef PICOLIBC_TLS
_set_tls(to_thread->tls);
#endif
/* switch to new thread */
LOG_D("[%d]switch to priority#%d "
"thread:%.*s(sp:0x%08x), "
Expand Down
9 changes: 9 additions & 0 deletions src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ static rt_err_t _thread_init(struct rt_thread *thread,
thread->entry = (void *)entry;
thread->parameter = parameter;

#ifdef PICOLIBC_TLS
#define TLS_ALIGN (_tls_align() > 8 ? _tls_align() : 8)
char *tls = (char *)stack_start + stack_size - _tls_size();
thread->tls = (void *)RT_ALIGN_DOWN((rt_ubase_t)tls, TLS_ALIGN);
stack_size = (char *)thread->tls - (char *)stack_start;

_init_tls(thread->tls);
#endif

/* stack init */
thread->stack_addr = stack_start;
thread->stack_size = stack_size;
Expand Down