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.