test_thread_local.c 3.7 KB

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