mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 03:34:32 +02:00
Merge branch 'bugfix/freertos_current_tcb_unpinned_v4.3' into 'release/v4.3'
freertos: Fix race condition returning incorrect TCB on unpinned tasks (v4.3) See merge request espressif/esp-idf!13236
This commit is contained in:
@@ -231,7 +231,12 @@ count overflows. */
|
||||
* task should be used in place of the parameter. This macro simply checks to
|
||||
* see if the parameter is NULL and returns a pointer to the appropriate TCB.
|
||||
*/
|
||||
#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? (TaskHandle_t)pxCurrentTCB[xPortGetCoreID()] : ( (TaskHandle_t)pxHandle ) )
|
||||
#if portNUM_PROCESSORS > 1
|
||||
/* In SMP, we need to disable interrupts if getting the current task handle outside a critical section. Calling xTaskGetCurrentTaskHandle() ensures this. */
|
||||
#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? xTaskGetCurrentTaskHandle() : ( (TaskHandle_t)pxHandle ) )
|
||||
#else
|
||||
#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? (TaskHandle_t) pxCurrentTCB[0] : ( (TaskHandle_t)pxHandle ) )
|
||||
#endif
|
||||
|
||||
/* The item value of the event list item is normally used to hold the priority
|
||||
of the task to which it belongs (coded to allow it to be held in reverse
|
||||
@@ -4465,7 +4470,7 @@ TCB_t *pxTCB;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
|
||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) || (portNUM_PROCESSORS > 1) )
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle( void )
|
||||
{
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "test_utils.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
TEST_CASE("pthread local storage basics", "[pthread]")
|
||||
{
|
||||
@@ -128,3 +129,36 @@ static void task_test_pthread_destructor(void *v_key)
|
||||
thread_test_pthread_destructor(v_key);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
#define STRESS_NUMITER 2000000
|
||||
#define STRESS_NUMTASKS 16
|
||||
|
||||
static void *thread_stress_test(void *v_key)
|
||||
{
|
||||
pthread_key_t key = (pthread_key_t) v_key;
|
||||
void *tls_value = (void *)esp_random();
|
||||
|
||||
pthread_setspecific(key, tls_value);
|
||||
|
||||
for(int i = 0; i < STRESS_NUMITER; i++) {
|
||||
TEST_ASSERT_EQUAL_HEX32(pthread_getspecific(key), tls_value);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// This test case added to reproduce issues with unpinned tasks and TLS
|
||||
TEST_CASE("pthread local storage stress test", "[pthread]")
|
||||
{
|
||||
pthread_key_t key = -1;
|
||||
pthread_t threads[STRESS_NUMTASKS] = { 0 };
|
||||
TEST_ASSERT_EQUAL(0, pthread_key_create(&key, test_pthread_destructor));
|
||||
|
||||
for (int i = 0; i < STRESS_NUMTASKS; i++) {
|
||||
TEST_ASSERT_EQUAL(0, pthread_create(&threads[i], NULL, thread_stress_test, (void *)key));
|
||||
}
|
||||
for (int i = 0; i < STRESS_NUMTASKS; i++) {
|
||||
TEST_ASSERT_EQUAL(0, pthread_join(threads[i], NULL));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user