esp-idf/components/freertos/test/miscellaneous/test_tlsp_del_cb.c
Darian Leung 49256fe5c9 freertos: Refactor TLSP deletion callback test
- Add a new test case for SMP FreeRTOS
- Old test case is preserved. To be removed in the future
2022-05-28 21:36:39 +08:00

165 lines
5.5 KiB
C

/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#if CONFIG_FREERTOS_SMP
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
#include "test_utils.h"
/*
Test TLSP Deletion Callbacks
Purpose:
- Test that TLSP Deletion Callbacks can be registered
- Test that TLSP Deletion Callbacks are called when a task is deleted
Procedure:
- Create a task on each core along with an array of integers to act as TLSP data
- Each task should initialize their integers to a particular value (i.e., the index value)
- Each task should register those integers as TLSPs along with a deletion callback
- Each task should self delete to trigger the TLSP deletion callback
- The TLSP deletion callback should indicate that it has run by negating the integer values
Expected:
- The TLSP deletion callback should check that the correct TLSP is provided by checking the TLSPs initialization
value (i.e., should be set to the index value)
- After deletion, the integer values should be negated to indicate deletion callback execution
*/
#define NUM_TLSP CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
static void tlsp_del_cb(int index, void *tlsp)
{
int *val = (int *)tlsp;
// Check that the TLSP's initialization value is correct
TEST_ASSERT_EQUAL(index, *val);
// Set the TLSP's value again to a negative value to indicate that the del cb has ran
*val = -*val;
}
static void tlsp_task(void *arg)
{
int *tlsps = (int *)arg;
for (int index = 0; index < NUM_TLSP; index++) {
// Initialize the TLSPs to a positive value
tlsps[index] = index;
// Set TLSPs and deletion callbacks
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, index, &tlsps[index], tlsp_del_cb);
}
// Self delete to trigger TLSP del cb
vTaskDelete(NULL);
}
TEST_CASE("Test TLSP deletion callbacks", "[freertos]")
{
TaskHandle_t tasks[portNUM_PROCESSORS];
int tlsps[portNUM_PROCESSORS][NUM_TLSP];
for (int i = 0; i < portNUM_PROCESSORS; i++) {
TEST_ASSERT_EQUAL(pdPASS, xTaskCreatePinnedToCore(tlsp_task, "tlsp_tsk", configMINIMAL_STACK_SIZE * 2, (void *)&tlsps[i], UNITY_FREERTOS_PRIORITY - 1, &tasks[i], i));
}
// Significant delay to let tasks run and delete themselves
vTaskDelay(pdMS_TO_TICKS(100));
// Check the values of the TLSPs to see if the del cb have ran
for (int i = 0; i < portNUM_PROCESSORS; i++) {
for (int index = 0; index < NUM_TLSP; index++) {
// Del cb should have set the TLSP to a negative value
TEST_ASSERT_EQUAL(-index, tlsps[i][index]);
}
}
}
#else // CONFIG_FREERTOS_SMP
// Todo: Remove IDF FreeRTOS Test Case
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "unity.h"
#include "test_utils.h"
/* --------Test backported thread local storage pointer and deletion cb feature----------
* vTaskSetThreadLocalStoragePointerAndDelCallback()
* pvTaskGetThreadLocalStoragePointer(),
*
* This test creates a task and set's the task's TLSPs. The task is then deleted
* which should trigger the deletion cb.
*/
#define NO_OF_TLSP configNUM_THREAD_LOCAL_STORAGE_POINTERS
#define TLSP_SET_BASE 0x0F //0b1111 to be bit shifted by index
#define TLSP_DEL_BASE 0x05 //0b0101 to be bit shifted by index
//The variables pointed to by Thread Local Storage Pointer
static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0};
/* If static task cleanup is defined, can't set index 0 even if the calling task is not a pthread,
as the cleanup is called for every task.
*/
#if defined(CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP)
static const int skip_index = 0; /*PTHREAD_TLS_INDEX*/
#else
static const int skip_index = -1;
#endif
static void del_cb(int index, void *ptr)
{
*((uint32_t *)ptr) = (TLSP_DEL_BASE << index); //Indicate deletion by setting task storage element to a unique value
}
static void task_cb(void *arg)
{
int core = xPortGetCoreID();
for(int i = 0; i < NO_OF_TLSP; i++){
if (i == skip_index) {
continue;
}
task_storage[core][i] = (TLSP_SET_BASE << i); //Give each element of task_storage a unique number
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, i, (void *)&task_storage[core][i], del_cb); //Set each TLSP to point to a task storage element
}
for(int i = 0; i < NO_OF_TLSP; i++){
if (i == skip_index) {
continue;
}
uint32_t * tlsp = (uint32_t *)pvTaskGetThreadLocalStoragePointer(NULL, i);
TEST_ASSERT_EQUAL(*tlsp, (TLSP_SET_BASE << i)); //Check if TLSP points to the correct task storage element by checking unique value
}
vTaskDelete(NULL); //Delete Task to Trigger TSLP deletion callback
}
TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]")
{
//Create Task
for(int core = 0; core < portNUM_PROCESSORS; core++){
xTaskCreatePinnedToCore(task_cb, "task", 1024, NULL, UNITY_FREERTOS_PRIORITY+1, NULL, core);
}
vTaskDelay(10); //Delay long enough for tasks to run to completion
for(int core = 0; core < portNUM_PROCESSORS; core++){
for(int i = 0; i < NO_OF_TLSP; i++){
if (i == skip_index) {
continue;
}
TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value
}
}
}
#endif // CONFIG_FREERTOS_SMP