mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 04:59:55 +00:00 
			
		
		
		
	Merge branch 'bugfix/freertos_current_tcb_unpinned' into 'master'
freertos: Fix race condition returning incorrect TCB on unpinned tasks Closes WIFI-3125 See merge request espressif/esp-idf!13189
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 |  * 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. |  * 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 | /* 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 | of the task to which it belongs (coded to allow it to be held in reverse | ||||||
| @@ -4449,7 +4454,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 ) | 	TaskHandle_t xTaskGetCurrentTaskHandle( void ) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| #include "freertos/FreeRTOS.h" | #include "freertos/FreeRTOS.h" | ||||||
| #include "freertos/task.h" | #include "freertos/task.h" | ||||||
| #include "test_utils.h" | #include "test_utils.h" | ||||||
|  | #include "esp_system.h" | ||||||
|  |  | ||||||
| TEST_CASE("pthread local storage basics", "[pthread]") | 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); |     thread_test_pthread_destructor(v_key); | ||||||
|     vTaskDelete(NULL); |     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
	 Angus Gratton
					Angus Gratton