mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-13 17:44:38 +02:00
Merge branch 'bugfix/update_tlsp_del_cb_tests' into 'master'
FreeRTOS: Fix TLSP deletion callback tests Closes IDF-5071 See merge request espressif/esp-idf!18233
This commit is contained in:
@@ -600,7 +600,8 @@ void vPortTLSPointersDelCb( void * pxTCB )
|
|||||||
{
|
{
|
||||||
/* In case the TLSP deletion callback has been overwritten by a TLS pointer, gracefully abort. */
|
/* In case the TLSP deletion callback has been overwritten by a TLS pointer, gracefully abort. */
|
||||||
if ( !esp_ptr_executable( pvThreadLocalStoragePointersDelCallback[ x ] ) ) {
|
if ( !esp_ptr_executable( pvThreadLocalStoragePointersDelCallback[ x ] ) ) {
|
||||||
ESP_LOGE("FreeRTOS", "Fatal error: TLSP deletion callback at index %d overwritten with non-excutable pointer %p", x, pvThreadLocalStoragePointersDelCallback[ x ]);
|
// We call EARLY log here as currently portCLEAN_UP_TCB() is called in a critical section
|
||||||
|
ESP_EARLY_LOGE("FreeRTOS", "Fatal error: TLSP deletion callback at index %d overwritten with non-excutable pointer %p", x, pvThreadLocalStoragePointersDelCallback[ x ]);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -206,75 +206,3 @@ TEST_CASE("Test FreeRTOS backported eventgroup functions", "[freertos]")
|
|||||||
//Cleanup static event
|
//Cleanup static event
|
||||||
vEventGroupDelete(eg_handle);
|
vEventGroupDelete(eg_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
164
components/freertos/test/miscellaneous/test_tlsp_del_cb.c
Normal file
164
components/freertos/test/miscellaneous/test_tlsp_del_cb.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
Reference in New Issue
Block a user