Hi
I am trying to support thread local storage in PICOLIBC for FreeRTOS. I set the macro configUSE_PICOLIBC_TLS
and wrote the following test demo. And test it on RISCV-32 platform.
#if ( configUSE_PICOLIBC_TLS == 1 )
static void prvPICOTLSTask( void *pvParameters );
__attribute__((section(".tdata"))) uint32_t tls_variable = 0;
#endif
int main( void )
{
printf("hello \n");
#if ( configUSE_PICOLIBC_TLS == 1 )
xTaskCreate(prvPICOTLSTask,
"TLS1",
configMINIMAL_STACK_SIZE,
(void *) 1,
mainQUEUE_SEND_TASK_PRIORITY,
NULL );
xTaskCreate(prvPICOTLSTask,
"TLS2",
configMINIMAL_STACK_SIZE,
(void *) 2,
mainQUEUE_SEND_TASK_PRIORITY,
NULL );
#endif
vTaskDelete(NULL);
}
/*-----------------------------------------------------------*/
#if ( configUSE_PICOLIBC_TLS == 1 )
static void prvPICOTLSTask( void *pvParameters )
{
tls_variable = (uint32_t)(uint32_t *) pvParameters;
while (1) {
printf("Task %ld: tls_variable = %ld\n", tls_variable, tls_variable);
vTaskDelay(300);
}
}
#endif
I expected that the program result should be that “TLS1” prints the value of tls_variable as 1, and “TLS2” prints the value as 2. However, the test results did not meet expectations.
hello
Task 1: tls_variable = 1
Task 2: tls_variable = 2
Task 2: tls_variable = 2
Task 2: tls_variable = 2
In the end, tls_variable remained 2 and did not change.
When enable configUSE_PICOLIBC_TLS
, each task would create xTLSBlock
in TCB to store tis local storage pointer. xTLSBlock
only is only used in context switch by macro configSET_TLS_BLOCK
_set_tls
#define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock )
void
_set_tls(void *tls)
{
__asm__("mov " REG(TLS_REGNO) ", %0" : : "r" (tls));
}
The compiled assembly is as follows:
80009a14 <_set_tls>:
80009a14: 822a c.mv tp,a0
80009a16: 8082 c.jr ra
configSET_TLS_BLOCK()
just set tp
to xTLSBlock
, which means that each context switch will set the tp register of the current task to xTLSBlock
. It seems that there is no modification of local storage variable tls_variable. I would appreciate to know how tls works and whether it needs to make corresponding changes in the protable file (porASM.S or port.c).
Best regards.