/ components / freertos / test / test_thread_local.c
test_thread_local.c
  1  /*
  2   Test for thread local storage support.
  3  */
  4  
  5  #include <string.h>
  6  #include <esp_types.h>
  7  
  8  #include "freertos/FreeRTOS.h"
  9  #include "freertos/task.h"
 10  #include "unity.h"
 11  #include "test_utils.h"
 12  #include "sdkconfig.h"
 13  
 14  
 15  static __thread int tl_test_var1;
 16  static __thread uint8_t tl_test_var2 = 55;
 17  static __thread uint16_t tl_test_var3 = 44;
 18  static __thread uint8_t tl_test_arr_var[10];
 19  static __thread struct test_tls_var {
 20      int f32;
 21      uint8_t f8;
 22      uint16_t f16;
 23      uint8_t farr[10];
 24  } tl_test_struct_var;
 25  
 26  static void task_test_tls(void *arg)
 27  {
 28      bool *running = (bool *)arg;
 29      uint32_t tp = (uint32_t)-1;
 30      int test_var1_old = 0;
 31      uint8_t test_var2_old = 0;
 32      uint16_t test_var3_old = 0;
 33      int f32_old = 0;
 34      uint8_t f8_old = 0;
 35      uint16_t f16_old = 0;
 36  
 37      asm volatile ("rur.threadptr %0":"=r"(tp));
 38      for (int i = 0; i < 5; i++) {
 39          printf("Task[%x]: var = 0x%x 0x%x\n", tp, tl_test_var1, tl_test_var2);
 40          if (i == 0) {
 41              TEST_ASSERT_EQUAL(0, tl_test_var1);
 42              TEST_ASSERT_EQUAL(55, tl_test_var2);
 43              TEST_ASSERT_EQUAL(44, tl_test_var3);
 44              for (int k = 0; k < sizeof(tl_test_arr_var); k++) {
 45                  TEST_ASSERT_EQUAL(0, tl_test_arr_var[k]);
 46              }
 47              TEST_ASSERT_EQUAL(0, tl_test_struct_var.f32);
 48              TEST_ASSERT_EQUAL(0, tl_test_struct_var.f8);
 49              TEST_ASSERT_EQUAL(0, tl_test_struct_var.f16);
 50              for (int k = 0; k < sizeof(tl_test_struct_var.farr); k++) {
 51                  TEST_ASSERT_EQUAL(0, tl_test_struct_var.farr[k]);
 52              }
 53          } else {
 54              TEST_ASSERT_EQUAL(test_var1_old+1, tl_test_var1);
 55              TEST_ASSERT_EQUAL(test_var2_old+1, tl_test_var2);
 56              TEST_ASSERT_EQUAL(test_var3_old+1, tl_test_var3);
 57              for (int k = 0; k < sizeof(tl_test_arr_var); k++) {
 58                  TEST_ASSERT_EQUAL(i-1, tl_test_arr_var[k]);
 59              }
 60              TEST_ASSERT_EQUAL(f32_old+1, tl_test_struct_var.f32);
 61              TEST_ASSERT_EQUAL(f8_old+1, tl_test_struct_var.f8);
 62              TEST_ASSERT_EQUAL(f16_old+1, tl_test_struct_var.f16);
 63              for (int k = 0; k < sizeof(tl_test_struct_var.farr); k++) {
 64                  TEST_ASSERT_EQUAL(i-1, tl_test_struct_var.farr[k]);
 65              }
 66          }
 67          test_var1_old = tl_test_var1;
 68          test_var2_old = tl_test_var2;
 69          test_var3_old = tl_test_var3;
 70          f32_old = tl_test_struct_var.f32;
 71          f8_old = tl_test_struct_var.f8;
 72          f16_old = tl_test_struct_var.f16;
 73          tl_test_var1++;
 74          tl_test_var2++;
 75          tl_test_var3++;
 76          memset(tl_test_arr_var, i, sizeof(tl_test_arr_var));
 77          tl_test_struct_var.f32++;
 78          tl_test_struct_var.f8++;
 79          tl_test_struct_var.f16++;
 80          memset(tl_test_struct_var.farr, i, sizeof(tl_test_struct_var.farr));
 81          vTaskDelay(10);
 82      }
 83  
 84      if (running) {
 85          *running = false;
 86          vTaskDelete(NULL);
 87      }
 88  }
 89  
 90  TEST_CASE("TLS test", "[freertos]")
 91  {
 92      const size_t stack_size = 3072;
 93      StackType_t s_stack[stack_size]; /* with 8KB test task stack (default) this test still has ~3KB headroom */
 94      StaticTask_t s_task;
 95      bool running[2] = {true, true};
 96  #if CONFIG_FREERTOS_UNICORE == 0
 97      int other_core = 1;
 98  #else
 99      int other_core = 0;
100  #endif
101  
102      xTaskCreatePinnedToCore((TaskFunction_t)&task_test_tls, "task_test_tls", stack_size, &running[0],
103                              UNITY_FREERTOS_PRIORITY, NULL, 0);
104      xTaskCreateStaticPinnedToCore((TaskFunction_t)&task_test_tls, "task_test_tls", stack_size, &running[1],
105          UNITY_FREERTOS_PRIORITY, s_stack, &s_task, other_core);
106      while (running[0] || running[1]) {
107          vTaskDelay(10);
108      }
109      vTaskDelay(10); /* Make sure idle task can clean up s_task, before it goes out of scope */
110  }
111